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 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 void setFileToParse(IFile fileToParse) {
 
  68     this.fileToParse = fileToParse;
 
  71   public PHPParser(IFile fileToParse) {
 
  72     this(new StringReader(""));
 
  73     this.fileToParse = fileToParse;
 
  76   public void phpParserTester(String strEval) throws CoreException, ParseException {
 
  77     PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
 
  78     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 void htmlParserTester(String strEval) throws CoreException, ParseException {
 
  87     StringReader stream = new StringReader(strEval);
 
  88     if (jj_input_stream == null) {
 
  89       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
  95   public PHPOutlineInfo parseInfo(Object parent, String s) {
 
  96     outlineInfo = new PHPOutlineInfo(parent);
 
  97     currentSegment = outlineInfo.getDeclarations();
 
  98     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
 
 128   private static void setMarker(ParseException e) {
 
 130       setMarker(fileToParse,
 
 132                 jj_input_stream.tokenBegin,
 
 133                 jj_input_stream.tokenBegin + e.currentToken.image.length(),
 
 135                 "Line " + e.currentToken.beginLine);
 
 136     } catch (CoreException e2) {
 
 137       PHPeclipsePlugin.log(e2);
 
 142    * Create markers according to the external parser output
 
 144   private static void createMarkers(String output, IFile file) throws CoreException {
 
 145     // delete all markers
 
 146     file.deleteMarkers(IMarker.PROBLEM, false, 0);
 
 151     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
 
 152       // newer php error output (tested with 4.2.3)
 
 153       scanLine(output, file, indx, brIndx);
 
 158       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
 
 159         // older php error output (tested with 4.2.3)
 
 160         scanLine(output, file, indx, brIndx);
 
 166   private static void scanLine(String output, IFile file, int indx, int brIndx) throws CoreException {
 
 168     StringBuffer lineNumberBuffer = new StringBuffer(10);
 
 170     current = output.substring(indx, brIndx);
 
 172     if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
 
 173       int onLine = current.indexOf("on line <b>");
 
 175         lineNumberBuffer.delete(0, lineNumberBuffer.length());
 
 176         for (int i = onLine; i < current.length(); i++) {
 
 177           ch = current.charAt(i);
 
 178           if ('0' <= ch && '9' >= ch) {
 
 179             lineNumberBuffer.append(ch);
 
 183         int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
 
 185         Hashtable attributes = new Hashtable();
 
 187         current = current.replaceAll("\n", "");
 
 188         current = current.replaceAll("<b>", "");
 
 189         current = current.replaceAll("</b>", "");
 
 190         MarkerUtilities.setMessage(attributes, current);
 
 192         if (current.indexOf(PARSE_ERROR_STRING) != -1)
 
 193           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
 
 194         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
 
 195           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
 
 197           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
 
 198         MarkerUtilities.setLineNumber(attributes, lineNumber);
 
 199         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
 
 204   public void parse(String s) throws CoreException {
 
 205     ReInit(new StringReader(s));
 
 208     } catch (ParseException e) {
 
 209       processParseException(e);
 
 214    * Call the php parse command ( php -l -f <filename> )
 
 215    * and create markers according to the external parser output
 
 217   public static void phpExternalParse(IFile file) {
 
 218     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
 
 219     String filename = file.getLocation().toString();
 
 221     String[] arguments = { filename };
 
 222     MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
 
 223     String command = form.format(arguments);
 
 225     String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
 
 228       // parse the buffer to find the errors and warnings
 
 229       createMarkers(parserResult, file);
 
 230     } catch (CoreException e) {
 
 231       PHPeclipsePlugin.log(e);
 
 235   public void parse() throws ParseException {
 
 240 PARSER_END(PHPParser)
 
 244   <PHPSTART : "<?php" | "<?"> : PHPPARSING
 
 249   <PHPEND :"?>"> : DEFAULT
 
 273   "//" : IN_SINGLE_LINE_COMMENT
 
 275   <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
 
 277   "/*" : IN_MULTI_LINE_COMMENT
 
 280 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 
 282   <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
 
 285 <IN_SINGLE_LINE_COMMENT> TOKEN :
 
 287   <SINGLE_LINE_COMMENT_PHPEND : "?>" > : DEFAULT
 
 293   <FORMAL_COMMENT: "*/" > : PHPPARSING
 
 296 <IN_MULTI_LINE_COMMENT>
 
 299   <MULTI_LINE_COMMENT: "*/" > : PHPPARSING
 
 302 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
 
 312 | <FUNCTION : "function">
 
 315 | <ELSEIF   : "elseif">
 
 320 /* LANGUAGE CONSTRUCT */
 
 325 | <INCLUDE : "include">
 
 326 | <REQUIRE : "require">
 
 327 | <INCLUDE_ONCE : "include_once">
 
 328 | <REQUIRE_ONCE : "require_once">
 
 329 | <GLOBAL : "global">
 
 330 | <STATIC : "static">
 
 331 | <CLASSACCESS: "->">
 
 332 | <STATICCLASSACCESS: "::">
 
 333 | <ARRAYASSIGN: "=>">
 
 336 /* RESERVED WORDS AND LITERALS */
 
 343 | < CONTINUE: "continue" >
 
 344 | < _DEFAULT: "default" >
 
 346 | < EXTENDS: "extends" >
 
 352 | < RETURN: "return" >
 
 354 | < SWITCH: "switch" >
 
 358 | < ENDWHILE : "endwhile" >
 
 359 | <FOREACH : "foreach" >
 
 368 | <OBJECT : "object">
 
 370 | <BOOLEAN : "boolean">
 
 372 | <DOUBLE : "double">
 
 375 | <INTEGER : "integer">
 
 389         <DECIMAL_LITERAL> (["l","L"])?
 
 390       | <HEX_LITERAL> (["l","L"])?
 
 391       | <OCTAL_LITERAL> (["l","L"])?
 
 394   < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
 
 396   < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
 
 398   < #OCTAL_LITERAL: "0" (["0"-"7"])* >
 
 400   < FLOATING_POINT_LITERAL:
 
 401         (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
 
 402       | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
 
 403       | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
 
 404       | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
 
 407   < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
 
 409   < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
 
 444   < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
 
 447       ["a"-"z"] | ["A"-"Z"]
 
 455     "_" | ["\u007f"-"\u00ff"]
 
 503 | <RSIGNEDSHIFT: ">>" >
 
 504 | <RUNSIGNEDSHIFT: ">>>" >
 
 505 | <PLUSASSIGN: "+=" >
 
 506 | <MINUSASSIGN: "-=" >
 
 507 | <STARASSIGN: "*=" >
 
 508 | <SLASHASSIGN: "/=" >
 
 514 | <LSHIFTASSIGN: "<<=" >
 
 515 | <RSIGNEDSHIFTASSIGN: ">>=" >
 
 516 | <BANGDOUBLEEQUAL: "!==" >
 
 517 | <TRIPLEEQUAL: "===" >
 
 518 | <TILDEEQUAL: "~=" >
 
 523   < DOLLAR_ID: <DOLLAR> <IDENTIFIER>  >
 
 526 /*****************************************
 
 527  * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
 
 528  *****************************************/
 
 531  * Program structuring syntax follows.
 
 545   (<PHPSTART> Php() <PHPEND>)*
 
 547   } catch (TokenMgrError e) {
 
 548     errorMessage = e.getMessage();
 
 550     throw generateParseException();
 
 560 void ClassDeclaration() :
 
 562   PHPClassDeclaration classDeclaration;
 
 564   int pos = jj_input_stream.bufpos;
 
 567   <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
 
 569     classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
 
 570     currentSegment.add(classDeclaration);
 
 571     currentSegment = classDeclaration;
 
 575     currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
 584   } catch (ParseException e) {
 
 585     errorMessage = "'{' expected";
 
 589   ( ClassBodyDeclaration() )*
 
 592   } catch (ParseException e) {
 
 593     errorMessage = "'var', 'function' or '}' expected";
 
 599 void ClassBodyDeclaration() :
 
 607 void FieldDeclaration() :
 
 609   PHPVarDeclaration variableDeclaration;
 
 612   <VAR> variableDeclaration = VariableDeclarator()
 
 613   {currentSegment.add(variableDeclaration);}
 
 615     variableDeclaration = VariableDeclarator()
 
 616     {currentSegment.add(variableDeclaration);}
 
 620   } catch (ParseException e) {
 
 621     errorMessage = "';' expected after variable declaration";
 
 627 PHPVarDeclaration VariableDeclarator() :
 
 630   String varValue = null;
 
 631   int pos = jj_input_stream.bufpos;
 
 634   varName = VariableDeclaratorId()
 
 638       varValue = VariableInitializer()
 
 639     } catch (ParseException e) {
 
 640       errorMessage = "Literal expression expected in variable initializer";
 
 646     if (varValue == null) {
 
 647       return new PHPVarDeclaration(currentSegment,varName,pos);
 
 649     return new PHPVarDeclaration(currentSegment,varName,pos,varValue);
 
 653 String VariableDeclaratorId() :
 
 656   StringBuffer buff = new StringBuffer();
 
 662     ( LOOKAHEAD(2) expr = VariableSuffix()
 
 665     {return buff.toString();}
 
 666   } catch (ParseException e) {
 
 667     errorMessage = "'$' expected for variable identifier";
 
 679   token = <DOLLAR_ID> [<LBRACE> expr = Expression() <RBRACE>]
 
 684     return token + "{" + expr + "}";
 
 687   <DOLLAR> expr = VariableName()
 
 691 String VariableName():
 
 697   <LBRACE> expr = Expression() <RBRACE>
 
 698   {return "{"+expr+"}";}
 
 700   token = <IDENTIFIER> [<LBRACE> expr = Expression() <RBRACE>]
 
 705     return token + "{" + expr + "}";
 
 708   <DOLLAR> expr = VariableName()
 
 711   token = <DOLLAR_ID> [expr = VariableName()]
 
 716   return token.image + expr;
 
 720 String VariableInitializer() :
 
 729   <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 730   {return "-" + token.image;}
 
 732   <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 733   {return "+" + token.image;}
 
 735   expr = ArrayDeclarator()
 
 739   {return token.image;}
 
 742 String ArrayVariable() :
 
 745 StringBuffer buff = new StringBuffer();
 
 750    [<ARRAYASSIGN> expr = Expression()
 
 751    {buff.append("=>").append(expr);}]
 
 752   {return buff.toString();}
 
 755 String ArrayInitializer() :
 
 758 StringBuffer buff = new StringBuffer("(");
 
 761   <LPAREN> [ expr = ArrayVariable()
 
 763             ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
 
 764             {buff.append(",").append(expr);}
 
 769     return buff.toString();
 
 773 void MethodDeclaration() :
 
 775   PHPFunctionDeclaration functionDeclaration;
 
 778   <FUNCTION> functionDeclaration = MethodDeclarator()
 
 780     currentSegment.add(functionDeclaration);
 
 781     currentSegment = functionDeclaration;
 
 785     currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
 789 PHPFunctionDeclaration MethodDeclarator() :
 
 792   StringBuffer methodDeclaration = new StringBuffer();
 
 793   String formalParameters;
 
 794   int pos = jj_input_stream.bufpos;
 
 797   [ <BIT_AND> {methodDeclaration.append("&");} ]
 
 798   identifier = <IDENTIFIER>
 
 799   {methodDeclaration.append(identifier);}
 
 800     formalParameters = FormalParameters()
 
 802     methodDeclaration.append(formalParameters);
 
 803     return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos);
 
 807 String FormalParameters() :
 
 810   final StringBuffer buff = new StringBuffer("(");
 
 815   } catch (ParseException e) {
 
 816     errorMessage = "Formal parameter expected after function identifier";
 
 818     jj_consume_token(token.kind);
 
 820             [ expr = FormalParameter()
 
 823                 <COMMA> expr = FormalParameter()
 
 824                 {buff.append(",").append(expr);}
 
 829   } catch (ParseException e) {
 
 830     errorMessage = "')' expected";
 
 836   return buff.toString();
 
 840 String FormalParameter() :
 
 842   PHPVarDeclaration variableDeclaration;
 
 843   StringBuffer buff = new StringBuffer();
 
 846   [<BIT_AND> {buff.append("&");}] variableDeclaration = VariableDeclarator()
 
 848     buff.append(variableDeclaration.toString());
 
 849     return buff.toString();
 
 884 String Expression() :
 
 887   String assignOperator = null;
 
 891   expr = PrintExpression()
 
 894   expr = ConditionalExpression()
 
 896     assignOperator = AssignmentOperator()
 
 899     } catch (ParseException e) {
 
 900       errorMessage = "expression expected";
 
 909       return expr + assignOperator + expr2;
 
 914 String AssignmentOperator() :
 
 931 | <RSIGNEDSHIFTASSIGN>
 
 945 String ConditionalExpression() :
 
 952   expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
 
 957     return expr + "?" + expr2 + ":" + expr3;
 
 962 String ConditionalOrExpression() :
 
 967   StringBuffer buff = new StringBuffer();
 
 970   expr = ConditionalAndExpression()
 
 975     (operator = <SC_OR> | operator = <_ORL>) expr2 = ConditionalAndExpression()
 
 977       buff.append(operator.image);
 
 982     return buff.toString();
 
 986 String ConditionalAndExpression() :
 
 991   StringBuffer buff = new StringBuffer();
 
 994   expr = ConcatExpression()
 
 999   (operator = <SC_AND> | operator = <_ANDL>) expr2 = ConcatExpression()
 
1001       buff.append(operator.image);
 
1006     return buff.toString();
 
1010 String ConcatExpression() :
 
1013   String expr2 = null;
 
1014   StringBuffer buff = new StringBuffer();
 
1017   expr = InclusiveOrExpression()
 
1022   <DOT> expr2 = InclusiveOrExpression()
 
1029     return buff.toString();
 
1033 String InclusiveOrExpression() :
 
1036   String expr2 = null;
 
1037   StringBuffer buff = new StringBuffer();
 
1040   expr = ExclusiveOrExpression()
 
1045   <BIT_OR> expr2 = ExclusiveOrExpression()
 
1052     return buff.toString();
 
1056 String ExclusiveOrExpression() :
 
1059   String expr2 = null;
 
1060   StringBuffer buff = new StringBuffer();
 
1063   expr = AndExpression()
 
1068     <XOR> expr2 = AndExpression()
 
1075     return buff.toString();
 
1079 String AndExpression() :
 
1082   String expr2 = null;
 
1083   StringBuffer buff = new StringBuffer();
 
1086   expr = EqualityExpression()
 
1091     <BIT_AND> expr2 = EqualityExpression()
 
1098     return buff.toString();
 
1102 String EqualityExpression() :
 
1107   StringBuffer buff = new StringBuffer();
 
1110   expr = RelationalExpression()
 
1111   {buff.append(expr);}
 
1115     | operator = <BANGDOUBLEEQUAL>
 
1116     | operator = <TRIPLEEQUAL>
 
1118   expr2 = RelationalExpression()
 
1120     buff.append(operator.image);
 
1124   {return buff.toString();}
 
1127 String RelationalExpression() :
 
1132   StringBuffer buff = new StringBuffer();
 
1135   expr = ShiftExpression()
 
1136   {buff.append(expr);}
 
1138   ( operator = <LT> | operator = <GT> | operator = <LE> | operator = <GE> ) expr2 = ShiftExpression()
 
1140     buff.append(operator.image);
 
1144   {return buff.toString();}
 
1147 String ShiftExpression() :
 
1152   StringBuffer buff = new StringBuffer();
 
1155   expr = AdditiveExpression()
 
1156   {buff.append(expr);}
 
1158   (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr2 = AdditiveExpression()
 
1160     buff.append(operator.image);
 
1164   {return buff.toString();}
 
1167 String AdditiveExpression() :
 
1172   StringBuffer buff = new StringBuffer();
 
1175   expr = MultiplicativeExpression()
 
1176   {buff.append(expr);}
 
1178    ( operator = <PLUS> | operator = <MINUS> ) expr2 = MultiplicativeExpression()
 
1180     buff.append(operator.image);
 
1184   {return buff.toString();}
 
1187 String MultiplicativeExpression() :
 
1191   final StringBuffer buff = new StringBuffer();}
 
1193   expr = UnaryExpression()
 
1194   {buff.append(expr);}
 
1196   ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr2 = UnaryExpression()
 
1198     buff.append(operator.image);
 
1202   {return buff.toString();}
 
1206  * An unary expression starting with @, & or nothing
 
1208 String UnaryExpression() :
 
1212   final StringBuffer buff = new StringBuffer();
 
1215   token = <BIT_AND> expr = UnaryExpressionNoPrefix()
 
1217     if (token == null) {
 
1220     return token.image + expr;
 
1223   (<AT> {buff.append("@");})* expr = UnaryExpressionNoPrefix()
 
1224   {return buff.append(expr).toString();}
 
1227 String UnaryExpressionNoPrefix() :
 
1233   ( token = <PLUS> | token = <MINUS> ) expr = UnaryExpression()
 
1235     return token.image + expr;
 
1238   expr = PreIncrementExpression()
 
1241   expr = PreDecrementExpression()
 
1244   expr = UnaryExpressionNotPlusMinus()
 
1249 String PreIncrementExpression() :
 
1254   <INCR> expr = PrimaryExpression()
 
1258 String PreDecrementExpression() :
 
1263   <DECR> expr = PrimaryExpression()
 
1267 String UnaryExpressionNotPlusMinus() :
 
1272   <BANG> expr = UnaryExpression()
 
1273   {return "!" + expr;}
 
1275   LOOKAHEAD( <LPAREN> Type() <RPAREN> )
 
1276   expr = CastExpression()
 
1279   expr = PostfixExpression()
 
1285   <LPAREN> expr = Expression()<RPAREN>
 
1286   {return "("+expr+")";}
 
1289 String CastExpression() :
 
1295   <LPAREN> type = Type() <RPAREN> expr = UnaryExpression()
 
1296   {return "(" + type + ")" + expr;}
 
1299 String PostfixExpression() :
 
1302   Token operator = null;
 
1305   expr = PrimaryExpression() [ operator = <INCR> | operator = <DECR> ]
 
1307     if (operator == null) {
 
1310     return expr + operator.image;
 
1314 String PrimaryExpression() :
 
1318   final StringBuffer buff = new StringBuffer();
 
1322   identifier = <IDENTIFIER> <STATICCLASSACCESS> expr = ClassIdentifier()
 
1323   {buff.append(identifier.image).append("::").append(expr);}
 
1325   expr = PrimarySuffix()
 
1326   {buff.append(expr);}
 
1328   {return buff.toString();}
 
1330   expr = PrimaryPrefix()  {buff.append(expr);}
 
1331   ( expr = PrimarySuffix()  {buff.append(expr);} )*
 
1332   {return buff.toString();}
 
1334   expr = ArrayDeclarator()
 
1335   {return "array" + expr;}
 
1338 String ArrayDeclarator() :
 
1343   <ARRAY> expr = ArrayInitializer()
 
1344   {return "array" + expr;}
 
1347 String PrimaryPrefix() :
 
1353   token = <IDENTIFIER>
 
1354   {return token.image;}
 
1356   <NEW> expr = ClassIdentifier()
 
1358     return "new " + expr;
 
1361   expr = VariableDeclaratorId()
 
1365 String ClassIdentifier():
 
1371   token = <IDENTIFIER>
 
1372   {return token.image;}
 
1374   expr = VariableDeclaratorId()
 
1378 String PrimarySuffix() :
 
1386   expr = VariableSuffix()
 
1390 String VariableSuffix() :
 
1395   <CLASSACCESS> expr = VariableName()
 
1396   {return "->" + expr;}
 
1398   <LBRACKET> [ expr = Expression() ]
 
1401   } catch (ParseException e) {
 
1402     errorMessage = "']' expected";
 
1410     return "[" + expr + "]";
 
1420   token = <INTEGER_LITERAL>
 
1421   {return token.image;}
 
1423   token = <FLOATING_POINT_LITERAL>
 
1424   {return token.image;}
 
1426   token = <STRING_LITERAL>
 
1427   {return token.image;}
 
1429   expr = BooleanLiteral()
 
1432   expr = NullLiteral()
 
1436 String BooleanLiteral() :
 
1446 String NullLiteral() :
 
1453 String Arguments() :
 
1458   <LPAREN> [ expr = ArgumentList() ]
 
1461   } catch (ParseException e) {
 
1462     errorMessage = "')' expected to close the argument list";
 
1470   return "(" + expr + ")";
 
1474 String ArgumentList() :
 
1477 StringBuffer buff = new StringBuffer();
 
1481   {buff.append(expr);}
 
1485       } catch (ParseException e) {
 
1486         errorMessage = "expression expected after a comma in argument list";
 
1491       buff.append(",").append("expr");
 
1494    {return buff.toString();}
 
1498  * Statement syntax follows.
 
1507     (<SEMICOLON> | "?>")
 
1508   } catch (ParseException e) {
 
1509     errorMessage = "';' expected";
 
1521   StatementExpression()
 
1524   } catch (ParseException e) {
 
1525     errorMessage = "';' expected after expression";
 
1550   [<AT>] IncludeStatement()
 
1557 void IncludeStatement() :
 
1560   int pos = jj_input_stream.bufpos;
 
1565   {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));}
 
1567     (<SEMICOLON> | "?>")
 
1568   } catch (ParseException e) {
 
1569     errorMessage = "';' expected";
 
1576   {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));}
 
1578     (<SEMICOLON> | "?>")
 
1579   } catch (ParseException e) {
 
1580     errorMessage = "';' expected";
 
1587   {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));}
 
1589     (<SEMICOLON> | "?>")
 
1590   } catch (ParseException e) {
 
1591     errorMessage = "';' expected";
 
1598   {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));}
 
1600     (<SEMICOLON> | "?>")
 
1601   } catch (ParseException e) {
 
1602     errorMessage = "';' expected";
 
1608 String PrintExpression() :
 
1610   StringBuffer buff = new StringBuffer("print ");
 
1614   <PRINT> expr = Expression()
 
1617     return buff.toString();
 
1621 void EchoStatement() :
 
1624   <ECHO> Expression() (<COMMA> Expression())*
 
1626     (<SEMICOLON> | "?>")
 
1627   } catch (ParseException e) {
 
1628     errorMessage = "';' expected after 'echo' statement";
 
1634 void GlobalStatement() :
 
1637   <GLOBAL> VariableDeclaratorId() (<COMMA> VariableDeclaratorId())*
 
1639     (<SEMICOLON> | "?>")
 
1640   } catch (ParseException e) {
 
1641     errorMessage = "';' expected";
 
1647 void StaticStatement() :
 
1650   <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
 
1652     (<SEMICOLON> | "?>")
 
1653   } catch (ParseException e) {
 
1654     errorMessage = "';' expected";
 
1660 void LabeledStatement() :
 
1663   <IDENTIFIER> <COLON> Statement()
 
1671   } catch (ParseException e) {
 
1672     errorMessage = "'{' expected";
 
1676   ( BlockStatement() )*
 
1680 void BlockStatement() :
 
1690 void LocalVariableDeclaration() :
 
1693   VariableDeclarator() ( <COMMA> VariableDeclarator() )*
 
1696 void EmptyStatement() :
 
1702 void StatementExpression() :
 
1705   PreIncrementExpression()
 
1707   PreDecrementExpression()
 
1715     AssignmentOperator() Expression()
 
1719 void SwitchStatement() :
 
1722   <SWITCH> <LPAREN> Expression() <RPAREN> <LBRACE>
 
1723     ( SwitchLabel() ( BlockStatement() )* )*
 
1727 void SwitchLabel() :
 
1730   <CASE> Expression() <COLON>
 
1735 void IfStatement() :
 
1737  * The disambiguating algorithm of JavaCC automatically binds dangling
 
1738  * else's to the innermost if statement.  The LOOKAHEAD specification
 
1739  * is to tell JavaCC that we know what we are doing.
 
1743   <IF> Condition("if") Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
 
1746 void Condition(String keyword) :
 
1751   } catch (ParseException e) {
 
1752     errorMessage = "'(' expected after " + keyword + " keyword";
 
1759   } catch (ParseException e) {
 
1760     errorMessage = "')' expected after " + keyword + " keyword";
 
1766 void ElseIfStatement() :
 
1769   <ELSEIF> Condition("elseif") Statement()
 
1772 void WhileStatement() :
 
1775   <WHILE> Condition("while") WhileStatement0()
 
1778 void WhileStatement0() :
 
1781   <COLON> (Statement())* <ENDWHILE>
 
1783     (<SEMICOLON> | "?>")
 
1784   } catch (ParseException e) {
 
1785     errorMessage = "';' expected";
 
1793 void DoStatement() :
 
1796   <DO> Statement() <WHILE> Condition("while")
 
1798     (<SEMICOLON> | "?>")
 
1799   } catch (ParseException e) {
 
1800     errorMessage = "';' expected";
 
1806 void ForeachStatement() :
 
1809   <FOREACH> <LPAREN> Variable() <AS> Variable() [ <ARRAYASSIGN> Expression() ] <RPAREN> Statement()
 
1812 void ForStatement() :
 
1815   <FOR> <LPAREN> [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ ForUpdate() ] <RPAREN> Statement()
 
1821   LOOKAHEAD(LocalVariableDeclaration())
 
1822   LocalVariableDeclaration()
 
1824   StatementExpressionList()
 
1827 void StatementExpressionList() :
 
1830   StatementExpression() ( <COMMA> StatementExpression() )*
 
1836   StatementExpressionList()
 
1839 void BreakStatement() :
 
1842   <BREAK> [ <IDENTIFIER> ] <SEMICOLON>
 
1845 void ContinueStatement() :
 
1848   <CONTINUE> [ <IDENTIFIER> ] <SEMICOLON>
 
1851 void ReturnStatement() :
 
1854   <RETURN> [ Expression() ] <SEMICOLON>