3   CHOICE_AMBIGUITY_CHECK = 2;
 
   4   OTHER_AMBIGUITY_CHECK = 1;
 
   7   DEBUG_LOOKAHEAD = false;
 
   8   DEBUG_TOKEN_MANAGER = false;
 
   9   OPTIMIZE_TOKEN_MANAGER = false;
 
  10   ERROR_REPORTING = true;
 
  11   JAVA_UNICODE_ESCAPE = false;
 
  12   UNICODE_INPUT = false;
 
  14   USER_TOKEN_MANAGER = false;
 
  15   USER_CHAR_STREAM = false;
 
  17   BUILD_TOKEN_MANAGER = true;
 
  19   FORCE_LA_CHECK = false;
 
  22 PARSER_BEGIN(PHPParser)
 
  25 import org.eclipse.core.resources.IFile;
 
  26 import org.eclipse.core.resources.IMarker;
 
  27 import org.eclipse.core.runtime.CoreException;
 
  28 import org.eclipse.ui.texteditor.MarkerUtilities;
 
  29 import org.eclipse.jface.preference.IPreferenceStore;
 
  31 import java.util.Hashtable;
 
  32 import java.io.StringReader;
 
  33 import java.text.MessageFormat;
 
  35 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
 
  36 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  37 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
 
  38 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren;
 
  39 import net.sourceforge.phpdt.internal.compiler.parser.PHPFunctionDeclaration;
 
  40 import net.sourceforge.phpdt.internal.compiler.parser.PHPClassDeclaration;
 
  41 import net.sourceforge.phpdt.internal.compiler.parser.PHPVarDeclaration;
 
  42 import net.sourceforge.phpdt.internal.compiler.parser.PHPReqIncDeclaration;
 
  46  * This php parser is inspired by the Java 1.2 grammar example 
 
  47  * given with JavaCC. You can get JavaCC at http://www.webgain.com
 
  48  * You can test the parser with the PHPParserTestCase2.java
 
  49  * @author Matthieu Casanova
 
  51 public final class PHPParser extends PHPParserSuperclass {
 
  53   private static IFile fileToParse;
 
  55   /** The current segment */
 
  56   private static PHPSegmentWithChildren currentSegment;
 
  58   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
 
  59   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
 
  60   PHPOutlineInfo outlineInfo;
 
  61   private static int errorLevel = ERROR;
 
  62   private static String errorMessage;
 
  67   public final void setFileToParse(final IFile fileToParse) {
 
  68     this.fileToParse = fileToParse;
 
  71   public PHPParser(final IFile fileToParse) {
 
  72     this(new StringReader(""));
 
  73     this.fileToParse = fileToParse;
 
  76   public static final void phpParserTester(final String strEval) throws CoreException, ParseException {
 
  77     PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
 
  78     final StringReader stream = new StringReader(strEval);
 
  79     if (jj_input_stream == null) {
 
  80       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
  82     ReInit(new StringReader(strEval));
 
  86   public static final void htmlParserTester(final String strEval) throws CoreException, ParseException {
 
  87     final StringReader stream = new StringReader(strEval);
 
  88     if (jj_input_stream == null) {
 
  89       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
  95   public final PHPOutlineInfo parseInfo(final Object parent, final String s) {
 
  96     outlineInfo = new PHPOutlineInfo(parent);
 
  97     currentSegment = outlineInfo.getDeclarations();
 
  98     final StringReader stream = new StringReader(s);
 
  99     if (jj_input_stream == null) {
 
 100       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 105     } catch (ParseException e) {
 
 106       processParseException(e);
 
 112    * This method will process the parse exception.
 
 113    * If the error message is null, the parse exception wasn't catched and a trace is written in the log
 
 114    * @param e the ParseException
 
 116   private static void processParseException(final ParseException e) {
 
 117     if (errorMessage == null) {
 
 118       PHPeclipsePlugin.log(e);
 
 119       errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it";
 
 126    * Create marker for the parse error
 
 127    * @param e the ParseException
 
 129   private static void setMarker(final ParseException e) {
 
 131       setMarker(fileToParse,
 
 133                 jj_input_stream.tokenBegin,
 
 134                 jj_input_stream.tokenBegin + e.currentToken.image.length(),
 
 136                 "Line " + e.currentToken.beginLine);
 
 137     } catch (CoreException e2) {
 
 138       PHPeclipsePlugin.log(e2);
 
 143    * Create markers according to the external parser output
 
 145   private static void createMarkers(final String output, final IFile file) throws CoreException {
 
 146     // delete all markers
 
 147     file.deleteMarkers(IMarker.PROBLEM, false, 0);
 
 152     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
 
 153       // newer php error output (tested with 4.2.3)
 
 154       scanLine(output, file, indx, brIndx);
 
 159       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
 
 160         // older php error output (tested with 4.2.3)
 
 161         scanLine(output, file, indx, brIndx);
 
 167   private static void scanLine(final String output,
 
 170                                final int brIndx) throws CoreException {
 
 172     StringBuffer lineNumberBuffer = new StringBuffer(10);
 
 174     current = output.substring(indx, brIndx);
 
 176     if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
 
 177       int onLine = current.indexOf("on line <b>");
 
 179         lineNumberBuffer.delete(0, lineNumberBuffer.length());
 
 180         for (int i = onLine; i < current.length(); i++) {
 
 181           ch = current.charAt(i);
 
 182           if ('0' <= ch && '9' >= ch) {
 
 183             lineNumberBuffer.append(ch);
 
 187         int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
 
 189         Hashtable attributes = new Hashtable();
 
 191         current = current.replaceAll("\n", "");
 
 192         current = current.replaceAll("<b>", "");
 
 193         current = current.replaceAll("</b>", "");
 
 194         MarkerUtilities.setMessage(attributes, current);
 
 196         if (current.indexOf(PARSE_ERROR_STRING) != -1)
 
 197           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
 
 198         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
 
 199           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
 
 201           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
 
 202         MarkerUtilities.setLineNumber(attributes, lineNumber);
 
 203         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
 
 208   public final void parse(final String s) throws CoreException {
 
 209     final StringReader stream = new StringReader(s);
 
 210     if (jj_input_stream == null) {
 
 211       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 216     } catch (ParseException e) {
 
 217       processParseException(e);
 
 222    * Call the php parse command ( php -l -f <filename> )
 
 223    * and create markers according to the external parser output
 
 225   public static void phpExternalParse(final IFile file) {
 
 226     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
 
 227     final String filename = file.getLocation().toString();
 
 229     final String[] arguments = { filename };
 
 230     final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
 
 231     final String command = form.format(arguments);
 
 233     final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
 
 236       // parse the buffer to find the errors and warnings
 
 237       createMarkers(parserResult, file);
 
 238     } catch (CoreException e) {
 
 239       PHPeclipsePlugin.log(e);
 
 243   public static final void parse() throws ParseException {
 
 248 PARSER_END(PHPParser)
 
 252   <PHPSTARTSHORT : "<?"> : PHPPARSING
 
 253 | <PHPSTARTLONG : "<?php"> : PHPPARSING
 
 254 | <PHPECHOSTART : "<?=">      : PHPPARSING
 
 259   <PHPEND :"?>"> : DEFAULT
 
 281 <PHPPARSING> SPECIAL_TOKEN :
 
 283   "//" : IN_SINGLE_LINE_COMMENT
 
 285   <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
 
 287   "/*" : IN_MULTI_LINE_COMMENT
 
 290 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 
 292   <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
 
 295 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 
 297   <SINGLE_LINE_COMMENT_PHPEND : "?>" > : DEFAULT
 
 303   <FORMAL_COMMENT: "*/" > : PHPPARSING
 
 306 <IN_MULTI_LINE_COMMENT>
 
 309   <MULTI_LINE_COMMENT: "*/" > : PHPPARSING
 
 312 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
 
 322 | <FUNCTION : "function">
 
 325 | <ELSEIF   : "elseif">
 
 331 /* LANGUAGE CONSTRUCT */
 
 336 | <INCLUDE            : "include">
 
 337 | <REQUIRE            : "require">
 
 338 | <INCLUDE_ONCE       : "include_once">
 
 339 | <REQUIRE_ONCE       : "require_once">
 
 340 | <GLOBAL             : "global">
 
 341 | <STATIC             : "static">
 
 342 | <CLASSACCESS        : "->">
 
 343 | <STATICCLASSACCESS  : "::">
 
 344 | <ARRAYASSIGN        : "=>">
 
 351 /* RESERVED WORDS AND LITERALS */
 
 357 | <CONTINUE : "continue">
 
 358 | <_DEFAULT : "default">
 
 360 | <EXTENDS  : "extends">
 
 365 | <RETURN   : "return">
 
 367 | <SWITCH   : "switch">
 
 372 | <ENDWHILE : "endwhile">
 
 374 | <ENDFOR   : "endfor">
 
 375 | <FOREACH  : "foreach">
 
 384 | <OBJECT  : "object">
 
 386 | <BOOLEAN : "boolean">
 
 388 | <DOUBLE  : "double">
 
 391 | <INTEGER : "integer">
 
 405         <DECIMAL_LITERAL> (["l","L"])?
 
 406       | <HEX_LITERAL> (["l","L"])?
 
 407       | <OCTAL_LITERAL> (["l","L"])?
 
 410   < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
 
 412   < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
 
 414   < #OCTAL_LITERAL: "0" (["0"-"7"])* >
 
 416   < FLOATING_POINT_LITERAL:
 
 417         (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
 
 418       | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
 
 419       | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
 
 420       | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
 
 423   < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
 
 425   < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
 
 460   < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
 
 463       ["a"-"z"] | ["A"-"Z"]
 
 471     "_" | ["\u007f"-"\u00ff"]
 
 501 | <BANGDOUBLEEQUAL    : "!==">
 
 502 | <TRIPLEEQUAL        : "===">
 
 509 | <PLUSASSIGN         : "+=">
 
 510 | <MINUSASSIGN        : "-=">
 
 511 | <STARASSIGN         : "*=">
 
 512 | <SLASHASSIGN        : "/=">
 
 518 | <TILDEEQUAL         : "~=">
 
 542 | <RSIGNEDSHIFT       : ">>">
 
 543 | <RUNSIGNEDSHIFT     : ">>>">
 
 544 | <LSHIFTASSIGN       : "<<=">
 
 545 | <RSIGNEDSHIFTASSIGN : ">>=">
 
 550   < DOLLAR_ID: <DOLLAR> <IDENTIFIER>  >
 
 566   } catch (TokenMgrError e) {
 
 567     errorMessage = e.getMessage();
 
 569     throw generateParseException();
 
 575   final int start = jj_input_stream.bufpos;
 
 578   <PHPECHOSTART> Expression() [ <SEMICOLON> ] <PHPEND>
 
 583     setMarker(fileToParse,
 
 584               "You should use '<?php' instead of '<?' it will avoid some problems with XML",
 
 586               jj_input_stream.bufpos,
 
 588               "Line " + token.beginLine);
 
 589   } catch (CoreException e) {
 
 590     PHPeclipsePlugin.log(e);
 
 595   } catch (ParseException e) {
 
 596     errorMessage = "'?>' expected";
 
 608 void ClassDeclaration() :
 
 610   final PHPClassDeclaration classDeclaration;
 
 611   final Token className;
 
 612   final int pos = jj_input_stream.bufpos;
 
 615   <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
 
 617     if (currentSegment != null) {
 
 618       classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
 
 619       currentSegment.add(classDeclaration);
 
 620       currentSegment = classDeclaration;
 
 625     if (currentSegment != null) {
 
 626       currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
 636   } catch (ParseException e) {
 
 637     errorMessage = "'{' expected";
 
 641   ( ClassBodyDeclaration() )*
 
 644   } catch (ParseException e) {
 
 645     errorMessage = "'var', 'function' or '}' expected";
 
 651 void ClassBodyDeclaration() :
 
 659 void FieldDeclaration() :
 
 661   PHPVarDeclaration variableDeclaration;
 
 664   <VAR> variableDeclaration = VariableDeclarator()
 
 666     if (currentSegment != null) {
 
 667       currentSegment.add(variableDeclaration);
 
 671       variableDeclaration = VariableDeclarator()
 
 673       if (currentSegment != null) {
 
 674         currentSegment.add(variableDeclaration);
 
 680   } catch (ParseException e) {
 
 681     errorMessage = "';' expected after variable declaration";
 
 687 PHPVarDeclaration VariableDeclarator() :
 
 689   final String varName;
 
 690   String varValue = null;
 
 691   final int pos = jj_input_stream.bufpos;
 
 694   varName = VariableDeclaratorId()
 
 698       varValue = VariableInitializer()
 
 699       {return new PHPVarDeclaration(currentSegment,varName,pos,varValue);}
 
 700     } catch (ParseException e) {
 
 701       errorMessage = "Literal expression expected in variable initializer";
 
 706   {return new PHPVarDeclaration(currentSegment,varName,pos);}
 
 709 String VariableDeclaratorId() :
 
 712   final StringBuffer buff = new StringBuffer();
 
 718     ( LOOKAHEAD(2) expr = VariableSuffix()
 
 721     {return buff.toString();}
 
 722   } catch (ParseException e) {
 
 723     errorMessage = "'$' expected for variable identifier";
 
 735   token = <DOLLAR_ID> [<LBRACE> expr = Expression() <RBRACE>]
 
 740     return token + "{" + expr + "}";
 
 743   <DOLLAR> expr = VariableName()
 
 747 String VariableName():
 
 753   <LBRACE> expr = Expression() <RBRACE>
 
 754   {return "{"+expr+"}";}
 
 756   token = <IDENTIFIER> [<LBRACE> expr = Expression() <RBRACE>]
 
 761     return token + "{" + expr + "}";
 
 764   <DOLLAR> expr = VariableName()
 
 767   token = <DOLLAR_ID> [expr = VariableName()]
 
 772   return token.image + expr;
 
 776 String VariableInitializer() :
 
 785   <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 786   {return "-" + token.image;}
 
 788   <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 789   {return "+" + token.image;}
 
 791   expr = ArrayDeclarator()
 
 795   {return token.image;}
 
 798 String ArrayVariable() :
 
 801 final StringBuffer buff = new StringBuffer();
 
 806    [<ARRAYASSIGN> expr = Expression()
 
 807    {buff.append("=>").append(expr);}]
 
 808   {return buff.toString();}
 
 811 String ArrayInitializer() :
 
 814 final StringBuffer buff = new StringBuffer("(");
 
 817   <LPAREN> [ expr = ArrayVariable()
 
 819             ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
 
 820             {buff.append(",").append(expr);}
 
 825     return buff.toString();
 
 829 void MethodDeclaration() :
 
 831   final PHPFunctionDeclaration functionDeclaration;
 
 834   <FUNCTION> functionDeclaration = MethodDeclarator()
 
 836     if (currentSegment != null) {
 
 837       currentSegment.add(functionDeclaration);
 
 838       currentSegment = functionDeclaration;
 
 843     if (currentSegment != null) {
 
 844       currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
 849 PHPFunctionDeclaration MethodDeclarator() :
 
 851   final Token identifier;
 
 852   final StringBuffer methodDeclaration = new StringBuffer();
 
 853   final String formalParameters;
 
 854   final int pos = jj_input_stream.bufpos;
 
 857   [ <BIT_AND> {methodDeclaration.append("&");} ]
 
 858   identifier = <IDENTIFIER>
 
 859   {methodDeclaration.append(identifier);}
 
 860     formalParameters = FormalParameters()
 
 862     methodDeclaration.append(formalParameters);
 
 863     return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos);
 
 867 String FormalParameters() :
 
 870   final StringBuffer buff = new StringBuffer("(");
 
 875   } catch (ParseException e) {
 
 876     errorMessage = "Formal parameter expected after function identifier";
 
 878     jj_consume_token(token.kind);
 
 880             [ expr = FormalParameter()
 
 883                 <COMMA> expr = FormalParameter()
 
 884                 {buff.append(",").append(expr);}
 
 889   } catch (ParseException e) {
 
 890     errorMessage = "')' expected";
 
 896   return buff.toString();
 
 900 String FormalParameter() :
 
 902   final PHPVarDeclaration variableDeclaration;
 
 903   final StringBuffer buff = new StringBuffer();
 
 906   [<BIT_AND> {buff.append("&");}] variableDeclaration = VariableDeclarator()
 
 908     buff.append(variableDeclaration.toString());
 
 909     return buff.toString();
 
 944 String Expression() :
 
 947   final String assignOperator;
 
 951   expr = PrintExpression()
 
 954   expr = ListExpression()
 
 957   expr = ConditionalExpression()
 
 959     assignOperator = AssignmentOperator()
 
 962       {return expr + assignOperator + expr2;}
 
 963     } catch (ParseException e) {
 
 964       errorMessage = "expression expected";
 
 972 String AssignmentOperator() :
 
 989 | <RSIGNEDSHIFTASSIGN>
 
1003 String ConditionalExpression() :
 
1006   String expr2 = null;
 
1007   String expr3 = null;
 
1010   expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
 
1012   if (expr3 == null) {
 
1015     return expr + "?" + expr2 + ":" + expr3;
 
1020 String ConditionalOrExpression() :
 
1024   final StringBuffer buff = new StringBuffer();
 
1027   expr = ConditionalAndExpression()
 
1028   {buff.append(expr);}
 
1030     (operator = <SC_OR> | operator = <_ORL>) expr = ConditionalAndExpression()
 
1032       buff.append(operator.image);
 
1037     return buff.toString();
 
1041 String ConditionalAndExpression() :
 
1045   final StringBuffer buff = new StringBuffer();
 
1048   expr = ConcatExpression()
 
1049   {buff.append(expr);}
 
1051   (operator = <SC_AND> | operator = <_ANDL>) expr = ConcatExpression()
 
1053       buff.append(operator.image);
 
1057   {return buff.toString();}
 
1060 String ConcatExpression() :
 
1063   final StringBuffer buff = new StringBuffer();
 
1066   expr = InclusiveOrExpression()
 
1067   {buff.append(expr);}
 
1069   <DOT> expr = InclusiveOrExpression()
 
1070   {buff.append(".").append(expr);}
 
1072   {return buff.toString();}
 
1075 String InclusiveOrExpression() :
 
1078   final StringBuffer buff = new StringBuffer();
 
1081   expr = ExclusiveOrExpression()
 
1082   {buff.append(expr);}
 
1084   <BIT_OR> expr = ExclusiveOrExpression()
 
1085   {buff.append("|").append(expr);}
 
1087   {return buff.toString();}
 
1090 String ExclusiveOrExpression() :
 
1093   final StringBuffer buff = new StringBuffer();
 
1096   expr = AndExpression()
 
1101     <XOR> expr = AndExpression()
 
1108     return buff.toString();
 
1112 String AndExpression() :
 
1115   final StringBuffer buff = new StringBuffer();
 
1118   expr = EqualityExpression()
 
1123     <BIT_AND> expr = EqualityExpression()
 
1125     buff.append("&").append(expr);
 
1128   {return buff.toString();}
 
1131 String EqualityExpression() :
 
1135   final StringBuffer buff = new StringBuffer();
 
1138   expr = RelationalExpression()
 
1139   {buff.append(expr);}
 
1144     | operator = <BANGDOUBLEEQUAL>
 
1145     | operator = <TRIPLEEQUAL>
 
1147   expr = RelationalExpression()
 
1149     buff.append(operator.image);
 
1153   {return buff.toString();}
 
1156 String RelationalExpression() :
 
1160   final StringBuffer buff = new StringBuffer();
 
1163   expr = ShiftExpression()
 
1164   {buff.append(expr);}
 
1166   ( operator = <LT> | operator = <GT> | operator = <LE> | operator = <GE> ) expr = ShiftExpression()
 
1167   {buff.append(operator.image).append(expr);}
 
1169   {return buff.toString();}
 
1172 String ShiftExpression() :
 
1176   final StringBuffer buff = new StringBuffer();
 
1179   expr = AdditiveExpression()
 
1180   {buff.append(expr);}
 
1182   (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr = AdditiveExpression()
 
1184     buff.append(operator.image);
 
1188   {return buff.toString();}
 
1191 String AdditiveExpression() :
 
1195   final StringBuffer buff = new StringBuffer();
 
1198   expr = MultiplicativeExpression()
 
1199   {buff.append(expr);}
 
1201    ( operator = <PLUS> | operator = <MINUS> ) expr = MultiplicativeExpression()
 
1203     buff.append(operator.image);
 
1207   {return buff.toString();}
 
1210 String MultiplicativeExpression() :
 
1214   final StringBuffer buff = new StringBuffer();}
 
1216   expr = UnaryExpression()
 
1217   {buff.append(expr);}
 
1219   ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr = UnaryExpression()
 
1221     buff.append(operator.image);
 
1225   {return buff.toString();}
 
1229  * An unary expression starting with @, & or nothing
 
1231 String UnaryExpression() :
 
1235   final StringBuffer buff = new StringBuffer();
 
1238   token = <BIT_AND> expr = UnaryExpressionNoPrefix()
 
1240     if (token == null) {
 
1243     return token.image + expr;
 
1246   (<AT> {buff.append("@");})* expr = UnaryExpressionNoPrefix()
 
1247   {return buff.append(expr).toString();}
 
1250 String UnaryExpressionNoPrefix() :
 
1256   ( token = <PLUS> | token = <MINUS> ) expr = UnaryExpression()
 
1258     return token.image + expr;
 
1261   expr = PreIncrementExpression()
 
1264   expr = PreDecrementExpression()
 
1267   expr = UnaryExpressionNotPlusMinus()
 
1272 String PreIncrementExpression() :
 
1277   <INCR> expr = PrimaryExpression()
 
1281 String PreDecrementExpression() :
 
1286   <DECR> expr = PrimaryExpression()
 
1290 String UnaryExpressionNotPlusMinus() :
 
1295   <BANG> expr = UnaryExpression()
 
1296   {return "!" + expr;}
 
1298   LOOKAHEAD( <LPAREN> Type() <RPAREN> )
 
1299   expr = CastExpression()
 
1302   expr = PostfixExpression()
 
1308   <LPAREN> expr = Expression()<RPAREN>
 
1309   {return "("+expr+")";}
 
1312 String CastExpression() :
 
1314 final String type, expr;
 
1317   <LPAREN> type = Type() <RPAREN> expr = UnaryExpression()
 
1318   {return "(" + type + ")" + expr;}
 
1321 String PostfixExpression() :
 
1324   Token operator = null;
 
1327   expr = PrimaryExpression() [ operator = <INCR> | operator = <DECR> ]
 
1329     if (operator == null) {
 
1332     return expr + operator.image;
 
1336 String PrimaryExpression() :
 
1338   final Token identifier;
 
1340   final StringBuffer buff = new StringBuffer();
 
1344   identifier = <IDENTIFIER> <STATICCLASSACCESS> expr = ClassIdentifier()
 
1345   {buff.append(identifier.image).append("::").append(expr);}
 
1347   expr = PrimarySuffix()
 
1348   {buff.append(expr);}
 
1350   {return buff.toString();}
 
1352   expr = PrimaryPrefix()  {buff.append(expr);}
 
1353   ( expr = PrimarySuffix()  {buff.append(expr);} )*
 
1354   {return buff.toString();}
 
1356   expr = ArrayDeclarator()
 
1357   {return "array" + expr;}
 
1360 String ArrayDeclarator() :
 
1365   <ARRAY> expr = ArrayInitializer()
 
1366   {return "array" + expr;}
 
1369 String PrimaryPrefix() :
 
1375   token = <IDENTIFIER>
 
1376   {return token.image;}
 
1378   <NEW> expr = ClassIdentifier()
 
1380     return "new " + expr;
 
1383   expr = VariableDeclaratorId()
 
1387 String ClassIdentifier():
 
1393   token = <IDENTIFIER>
 
1394   {return token.image;}
 
1396   expr = VariableDeclaratorId()
 
1400 String PrimarySuffix() :
 
1408   expr = VariableSuffix()
 
1412 String VariableSuffix() :
 
1417   <CLASSACCESS> expr = VariableName()
 
1418   {return "->" + expr;}
 
1420   <LBRACKET> [ expr = Expression() ]
 
1423   } catch (ParseException e) {
 
1424     errorMessage = "']' expected";
 
1432     return "[" + expr + "]";
 
1442   token = <INTEGER_LITERAL>
 
1443   {return token.image;}
 
1445   token = <FLOATING_POINT_LITERAL>
 
1446   {return token.image;}
 
1448   token = <STRING_LITERAL>
 
1449   {return token.image;}
 
1451   expr = BooleanLiteral()
 
1454   expr = NullLiteral()
 
1458 String BooleanLiteral() :
 
1468 String NullLiteral() :
 
1475 String Arguments() :
 
1480   <LPAREN> [ expr = ArgumentList() ]
 
1483   } catch (ParseException e) {
 
1484     errorMessage = "')' expected to close the argument list";
 
1492   return "(" + expr + ")";
 
1496 String ArgumentList() :
 
1499 final StringBuffer buff = new StringBuffer();
 
1503   {buff.append(expr);}
 
1507       } catch (ParseException e) {
 
1508         errorMessage = "expression expected after a comma in argument list";
 
1513       buff.append(",").append(expr);
 
1516    {return buff.toString();}
 
1520  * Statement syntax follows.
 
1529     (<SEMICOLON> | <PHPEND>)
 
1530   } catch (ParseException e) {
 
1531     errorMessage = "';' expected";
 
1543   StatementExpression()
 
1546   } catch (ParseException e) {
 
1547     errorMessage = "';' expected after expression";
 
1572   [<AT>] IncludeStatement()
 
1579 void IncludeStatement() :
 
1582   final int pos = jj_input_stream.bufpos;
 
1588     if (currentSegment != null) {
 
1589       currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));
 
1593     (<SEMICOLON> | "?>")
 
1594   } catch (ParseException e) {
 
1595     errorMessage = "';' expected";
 
1603     if (currentSegment != null) {
 
1604       currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));
 
1608     (<SEMICOLON> | "?>")
 
1609   } catch (ParseException e) {
 
1610     errorMessage = "';' expected";
 
1618     if (currentSegment != null) {
 
1619       currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));
 
1623     (<SEMICOLON> | "?>")
 
1624   } catch (ParseException e) {
 
1625     errorMessage = "';' expected";
 
1633     if (currentSegment != null) {
 
1634       currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));
 
1638     (<SEMICOLON> | "?>")
 
1639   } catch (ParseException e) {
 
1640     errorMessage = "';' expected";
 
1646 String PrintExpression() :
 
1648   final StringBuffer buff = new StringBuffer("print ");
 
1652   <PRINT> expr = Expression()
 
1655     return buff.toString();
 
1659 String ListExpression() :
 
1661   final StringBuffer buff = new StringBuffer("list(");
 
1667     expr = VariableDeclaratorId()
 
1668     {buff.append(expr);}
 
1673     expr = VariableDeclaratorId()
 
1674     {buff.append(expr);}
 
1679     return buff.toString();
 
1683 void EchoStatement() :
 
1686   <ECHO> Expression() (<COMMA> Expression())*
 
1688     (<SEMICOLON> | "?>")
 
1689   } catch (ParseException e) {
 
1690     errorMessage = "';' expected after 'echo' statement";
 
1696 void GlobalStatement() :
 
1699   <GLOBAL> VariableDeclaratorId() (<COMMA> VariableDeclaratorId())*
 
1701     (<SEMICOLON> | "?>")
 
1702   } catch (ParseException e) {
 
1703     errorMessage = "';' expected";
 
1709 void StaticStatement() :
 
1712   <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
 
1714     (<SEMICOLON> | "?>")
 
1715   } catch (ParseException e) {
 
1716     errorMessage = "';' expected";
 
1722 void LabeledStatement() :
 
1725   <IDENTIFIER> <COLON> Statement()
 
1733   } catch (ParseException e) {
 
1734     errorMessage = "'{' expected";
 
1738   ( BlockStatement() )*
 
1742 void BlockStatement() :
 
1752 void LocalVariableDeclaration() :
 
1755   LocalVariableDeclarator() ( <COMMA> LocalVariableDeclarator() )*
 
1758 void LocalVariableDeclarator() :
 
1761   VariableDeclaratorId() [ <ASSIGN> Expression() ]
 
1764 void EmptyStatement() :
 
1770 void StatementExpression() :
 
1773   PreIncrementExpression()
 
1775   PreDecrementExpression()
 
1783     AssignmentOperator() Expression()
 
1787 void SwitchStatement() :
 
1789   Token breakToken = null;
 
1796   } catch (ParseException e) {
 
1797     errorMessage = "'(' expected after 'switch'";
 
1804   } catch (ParseException e) {
 
1805     errorMessage = "')' expected";
 
1811   } catch (ParseException e) {
 
1812     errorMessage = "'{' expected";
 
1817       line = SwitchLabel()
 
1818       ( BlockStatement() )*
 
1819       [ breakToken = <BREAK> ]
 
1822           if (breakToken == null) {
 
1823             setMarker(fileToParse,
 
1824                       "You should use put a 'break' at the end of your statement",
 
1829         } catch (CoreException e) {
 
1830           PHPeclipsePlugin.log(e);
 
1836   } catch (ParseException e) {
 
1837     errorMessage = "'}' expected";
 
1851   } catch (ParseException e) {
 
1852     if (errorMessage != null) throw e;
 
1853     errorMessage = "expression expected after 'case' keyword";
 
1859   } catch (ParseException e) {
 
1860     errorMessage = "':' expected after case expression";
 
1864   {return token.beginLine;}
 
1869   } catch (ParseException e) {
 
1870     errorMessage = "':' expected after 'default' keyword";
 
1874   {return token.beginLine;}
 
1877 void IfStatement() :
 
1880   final int pos = jj_input_stream.bufpos;
 
1883   token = <IF> Condition("if") IfStatement0(pos,pos+token.image.length())
 
1886 void Condition(final String keyword) :
 
1891   } catch (ParseException e) {
 
1892     errorMessage = "'(' expected after " + keyword + " keyword";
 
1899   } catch (ParseException e) {
 
1900     errorMessage = "')' expected after " + keyword + " keyword";
 
1906 void IfStatement0(final int start,final int end) :
 
1910   <COLON> (Statement())* (ElseIfStatementColon())* [ElseStatementColon()]
 
1913   setMarker(fileToParse,
 
1914             "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
 
1918             "Line " + token.beginLine);
 
1919   } catch (CoreException e) {
 
1920     PHPeclipsePlugin.log(e);
 
1924   } catch (ParseException e) {
 
1925     errorMessage = "'endif' expected";
 
1931   } catch (ParseException e) {
 
1932     errorMessage = "';' expected 'endif' keyword";
 
1937   Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
 
1940 void ElseIfStatementColon() :
 
1943   <ELSEIF> Condition("elseif") <COLON> (Statement())*
 
1946 void ElseStatementColon() :
 
1949   <ELSE> <COLON> (Statement())*
 
1952 void ElseIfStatement() :
 
1955   <ELSEIF> Condition("elseif") Statement()
 
1958 void WhileStatement() :
 
1961   final int pos = jj_input_stream.bufpos;
 
1964   token = <WHILE> Condition("while") WhileStatement0(pos,pos + token.image.length())
 
1967 void WhileStatement0(final int start, final int end) :
 
1970   <COLON> (Statement())*
 
1972   setMarker(fileToParse,
 
1973             "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
 
1977             "Line " + token.beginLine);
 
1978   } catch (CoreException e) {
 
1979     PHPeclipsePlugin.log(e);
 
1983   } catch (ParseException e) {
 
1984     errorMessage = "'endwhile' expected";
 
1989     (<SEMICOLON> | "?>")
 
1990   } catch (ParseException e) {
 
1991     errorMessage = "';' expected after 'endwhile' keyword";
 
1999 void DoStatement() :
 
2002   <DO> Statement() <WHILE> Condition("while")
 
2004     (<SEMICOLON> | "?>")
 
2005   } catch (ParseException e) {
 
2006     errorMessage = "';' expected";
 
2012 void ForeachStatement() :
 
2018   } catch (ParseException e) {
 
2019     errorMessage = "'(' expected after 'foreach' keyword";
 
2025   } catch (ParseException e) {
 
2026     errorMessage = "variable expected";
 
2030   [ VariableSuffix() ]
 
2033   } catch (ParseException e) {
 
2034     errorMessage = "'as' expected";
 
2040   } catch (ParseException e) {
 
2041     errorMessage = "variable expected";
 
2045   [ <ARRAYASSIGN> Expression() ]
 
2048   } catch (ParseException e) {
 
2049     errorMessage = "')' expected after 'foreach' keyword";
 
2055   } catch (ParseException e) {
 
2056     if (errorMessage != null) throw e;
 
2057     errorMessage = "statement expected";
 
2063 void ForStatement() :
 
2066 final int pos = jj_input_stream.bufpos;
 
2072   } catch (ParseException e) {
 
2073     errorMessage = "'(' expected after 'for' keyword";
 
2077      [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ ForUpdate() ] <RPAREN>
 
2081       <COLON> (Statement())*
 
2084         setMarker(fileToParse,
 
2085                   "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
 
2087                   pos+token.image.length(),
 
2089                   "Line " + token.beginLine);
 
2090         } catch (CoreException e) {
 
2091           PHPeclipsePlugin.log(e);
 
2096       } catch (ParseException e) {
 
2097         errorMessage = "'endfor' expected";
 
2103       } catch (ParseException e) {
 
2104         errorMessage = "';' expected 'endfor' keyword";
 
2114   LOOKAHEAD(LocalVariableDeclaration())
 
2115   LocalVariableDeclaration()
 
2117   StatementExpressionList()
 
2120 void StatementExpressionList() :
 
2123   StatementExpression() ( <COMMA> StatementExpression() )*
 
2129   StatementExpressionList()
 
2132 void BreakStatement() :
 
2135   <BREAK> [ <IDENTIFIER> ] <SEMICOLON>
 
2138 void ContinueStatement() :
 
2141   <CONTINUE> [ <IDENTIFIER> ] <SEMICOLON>
 
2144 void ReturnStatement() :
 
2147   <RETURN> [ Expression() ] <SEMICOLON>