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, errorMessage, jj_input_stream.tokenBegin,jj_input_stream.tokenBegin+e.currentToken.image.length(), errorLevel);
131 } catch (CoreException e2) {
132 PHPeclipsePlugin.log(e2);
137 * Create markers according to the external parser output
139 private static void createMarkers(String output, IFile file) throws CoreException {
140 // delete all markers
141 file.deleteMarkers(IMarker.PROBLEM, false, 0);
146 while ((brIndx = output.indexOf("<br />", indx)) != -1) {
147 // newer php error output (tested with 4.2.3)
148 scanLine(output, file, indx, brIndx);
153 while ((brIndx = output.indexOf("<br>", indx)) != -1) {
154 // older php error output (tested with 4.2.3)
155 scanLine(output, file, indx, brIndx);
161 private static void scanLine(String output, IFile file, int indx, int brIndx) throws CoreException {
163 StringBuffer lineNumberBuffer = new StringBuffer(10);
165 current = output.substring(indx, brIndx);
167 if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
168 int onLine = current.indexOf("on line <b>");
170 lineNumberBuffer.delete(0, lineNumberBuffer.length());
171 for (int i = onLine; i < current.length(); i++) {
172 ch = current.charAt(i);
173 if ('0' <= ch && '9' >= ch) {
174 lineNumberBuffer.append(ch);
178 int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
180 Hashtable attributes = new Hashtable();
182 current = current.replaceAll("\n", "");
183 current = current.replaceAll("<b>", "");
184 current = current.replaceAll("</b>", "");
185 MarkerUtilities.setMessage(attributes, current);
187 if (current.indexOf(PARSE_ERROR_STRING) != -1)
188 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
189 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
190 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
192 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
193 MarkerUtilities.setLineNumber(attributes, lineNumber);
194 MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
199 public void parse(String s) throws CoreException {
200 ReInit(new StringReader(s));
203 } catch (ParseException e) {
204 processParseException(e);
209 * Call the php parse command ( php -l -f <filename> )
210 * and create markers according to the external parser output
212 public static void phpExternalParse(IFile file) {
213 IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
214 String filename = file.getLocation().toString();
216 String[] arguments = { filename };
217 MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
218 String command = form.format(arguments);
220 String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
223 // parse the buffer to find the errors and warnings
224 createMarkers(parserResult, file);
225 } catch (CoreException e) {
226 PHPeclipsePlugin.log(e);
230 public void parse() throws ParseException {
235 PARSER_END(PHPParser)
239 <PHPSTART : "<?php" | "<?"> : PHPPARSING
244 <PHPEND :"?>"> : DEFAULT
268 "//" : IN_SINGLE_LINE_COMMENT
270 <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
272 "/*" : IN_MULTI_LINE_COMMENT
275 <IN_SINGLE_LINE_COMMENT>
278 <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" | "?>" > : PHPPARSING
284 <FORMAL_COMMENT: "*/" > : PHPPARSING
287 <IN_MULTI_LINE_COMMENT>
290 <MULTI_LINE_COMMENT: "*/" > : PHPPARSING
293 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
303 | <FUNCTION : "function">
306 | <ELSEIF : "elseif">
311 /* LANGUAGE CONSTRUCT */
316 | <INCLUDE : "include">
317 | <REQUIRE : "require">
318 | <INCLUDE_ONCE : "include_once">
319 | <REQUIRE_ONCE : "require_once">
320 | <GLOBAL : "global">
321 | <STATIC : "static">
322 | <CLASSACCESS: "->">
323 | <STATICCLASSACCESS: "::">
324 | <ARRAYASSIGN: "=>">
327 /* RESERVED WORDS AND LITERALS */
334 | < CONTINUE: "continue" >
335 | < _DEFAULT: "default" >
337 | < EXTENDS: "extends" >
343 | < RETURN: "return" >
345 | < SWITCH: "switch" >
349 | < ENDWHILE : "endwhile" >
357 | <OBJECT : "object">
359 | <BOOLEAN : "boolean">
361 | <DOUBLE : "double">
364 | <INTEGER : "integer">
378 <DECIMAL_LITERAL> (["l","L"])?
379 | <HEX_LITERAL> (["l","L"])?
380 | <OCTAL_LITERAL> (["l","L"])?
383 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
385 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
387 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
389 < FLOATING_POINT_LITERAL:
390 (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
391 | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
392 | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
393 | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
396 < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
398 < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
433 < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
436 ["a"-"z"] | ["A"-"Z"]
492 | <RSIGNEDSHIFT: ">>" >
493 | <RUNSIGNEDSHIFT: ">>>" >
494 | <PLUSASSIGN: "+=" >
495 | <MINUSASSIGN: "-=" >
496 | <STARASSIGN: "*=" >
497 | <SLASHASSIGN: "/=" >
503 | <LSHIFTASSIGN: "<<=" >
504 | <RSIGNEDSHIFTASSIGN: ">>=" >
505 | <RUNSIGNEDSHIFTASSIGN: ">>>=" >
510 < DOLLAR_ID: <DOLLAR> <IDENTIFIER> >
513 /*****************************************
514 * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
515 *****************************************/
518 * Program structuring syntax follows.
531 (<PHPSTART> Php() <PHPEND>)*
541 void ClassDeclaration() :
543 PHPClassDeclaration classDeclaration;
545 int pos = jj_input_stream.bufpos;
548 <CLASS> className = <IDENTIFIER> [ <EXTENDS> <IDENTIFIER> ]
550 classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
551 currentSegment.add(classDeclaration);
552 currentSegment = classDeclaration;
556 currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
565 } catch (ParseException e) {
566 errorMessage = "'{' expected";
570 ( ClassBodyDeclaration() )*
573 } catch (ParseException e) {
574 errorMessage = "'var', 'function' or '}' expected";
580 void ClassBodyDeclaration() :
588 void FieldDeclaration() :
590 PHPVarDeclaration variableDeclaration;
593 <VAR> variableDeclaration = VariableDeclarator()
594 {currentSegment.add(variableDeclaration);}
596 variableDeclaration = VariableDeclarator()
597 {currentSegment.add(variableDeclaration);}
601 } catch (ParseException e) {
602 errorMessage = "';' expected after variable declaration";
608 PHPVarDeclaration VariableDeclarator() :
611 String varValue = null;
612 int pos = jj_input_stream.bufpos;
615 varName = VariableDeclaratorId()
619 varValue = VariableInitializer()
620 } catch (ParseException e) {
621 errorMessage = "Literal expression expected in variable initializer";
627 if (varValue == null) {
628 return new PHPVarDeclaration(currentSegment,varName,pos);
630 return new PHPVarDeclaration(currentSegment,varName,pos,varValue);
634 String VariableDeclaratorId() :
637 StringBuffer buff = new StringBuffer();
643 ( LOOKAHEAD(2) expr = VariableSuffix()
646 {return buff.toString();}
647 } catch (ParseException e) {
648 errorMessage = "'$' expected for variable identifier";
660 token = <DOLLAR_ID> [<LBRACE> expr = Expression() <RBRACE>]
665 return token + "{" + expr + "}";
668 <DOLLAR> expr = VariableName()
672 String VariableName():
678 <LBRACE> expr = Expression() <RBRACE>
679 {return "{"+expr+"}";}
681 token = <IDENTIFIER> [<LBRACE> expr = Expression() <RBRACE>]
686 return token + "{" + expr + "}";
689 <DOLLAR> expr = VariableName()
692 token = <DOLLAR_ID> [expr = VariableName()]
697 return token.image + expr;
701 String VariableInitializer() :
709 expr = ArrayDeclarator()
713 String ArrayVariable() :
716 StringBuffer buff = new StringBuffer();
721 [<ARRAYASSIGN> expr = Expression()
722 {buff.append("=>").append(expr);}]
723 {return buff.toString();}
726 String ArrayInitializer() :
729 StringBuffer buff = new StringBuffer("(");
732 <LPAREN> [ expr = ArrayVariable()
734 ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
735 {buff.append(",").append(expr);}
740 return buff.toString();
744 void MethodDeclaration() :
746 PHPFunctionDeclaration functionDeclaration;
749 <FUNCTION> functionDeclaration = MethodDeclarator()
751 currentSegment.add(functionDeclaration);
752 currentSegment = functionDeclaration;
756 currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
760 PHPFunctionDeclaration MethodDeclarator() :
763 StringBuffer methodDeclaration = new StringBuffer();
764 String formalParameters;
765 int pos = jj_input_stream.bufpos;
768 [ <BIT_AND> {methodDeclaration.append("&");} ]
769 identifier = <IDENTIFIER>
770 {methodDeclaration.append(identifier);}
771 formalParameters = FormalParameters()
773 methodDeclaration.append(formalParameters);
774 return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos);
778 String FormalParameters() :
781 final StringBuffer buff = new StringBuffer("(");
786 } catch (ParseException e) {
787 errorMessage = "Formal parameter expected after function identifier";
789 jj_consume_token(token.kind);
791 [ expr = FormalParameter()
794 <COMMA> expr = FormalParameter()
795 {buff.append(",").append(expr);}
800 } catch (ParseException e) {
801 errorMessage = "')' expected";
807 return buff.toString();
811 String FormalParameter() :
813 PHPVarDeclaration variableDeclaration;
814 StringBuffer buff = new StringBuffer();
817 [<BIT_AND> {buff.append("&");}] variableDeclaration = VariableDeclarator()
819 buff.append(variableDeclaration.toString());
820 return buff.toString();
852 String Expression() :
855 String assignOperator = null;
859 expr = PrintExpression()
862 expr = ConditionalExpression()
864 assignOperator = AssignmentOperator()
867 } catch (ParseException e) {
868 errorMessage = "expression expected";
870 throw generateParseException();
877 return expr + assignOperator + expr2;
882 String AssignmentOperator() :
899 | <RSIGNEDSHIFTASSIGN>
901 | <RUNSIGNEDSHIFTASSIGN>
913 String ConditionalExpression() :
920 expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
925 return expr + "?" + expr2 + ":" + expr3;
930 String ConditionalOrExpression() :
935 StringBuffer buff = new StringBuffer();
938 expr = ConditionalAndExpression()
943 (operator = <SC_OR> | operator = <_ORL>) expr2 = ConditionalAndExpression()
945 buff.append(operator.image);
950 return buff.toString();
954 String ConditionalAndExpression() :
959 StringBuffer buff = new StringBuffer();
962 expr = ConcatExpression()
967 (operator = <SC_AND> | operator = <_ANDL>) expr2 = ConcatExpression()
969 buff.append(operator.image);
974 return buff.toString();
978 String ConcatExpression() :
982 StringBuffer buff = new StringBuffer();
985 expr = InclusiveOrExpression()
990 <DOT> expr2 = InclusiveOrExpression()
997 return buff.toString();
1001 String InclusiveOrExpression() :
1004 String expr2 = null;
1005 StringBuffer buff = new StringBuffer();
1008 expr = ExclusiveOrExpression()
1013 <BIT_OR> expr2 = ExclusiveOrExpression()
1020 return buff.toString();
1024 String ExclusiveOrExpression() :
1027 String expr2 = null;
1028 StringBuffer buff = new StringBuffer();
1031 expr = AndExpression()
1036 <XOR> expr2 = AndExpression()
1043 return buff.toString();
1047 String AndExpression() :
1050 String expr2 = null;
1051 StringBuffer buff = new StringBuffer();
1054 expr = EqualityExpression()
1059 <BIT_AND> expr2 = EqualityExpression()
1066 return buff.toString();
1070 String EqualityExpression() :
1075 StringBuffer buff = new StringBuffer();
1078 expr = RelationalExpression()
1079 {buff.append(expr);}
1081 ( operator = <EQ> | operator = <NE> ) expr2 = RelationalExpression()
1083 buff.append(operator.image);
1087 {return buff.toString();}
1090 String RelationalExpression() :
1095 StringBuffer buff = new StringBuffer();
1098 expr = ShiftExpression()
1099 {buff.append(expr);}
1101 ( operator = <LT> | operator = <GT> | operator = <LE> | operator = <GE> ) expr2 = ShiftExpression()
1103 buff.append(operator.image);
1107 {return buff.toString();}
1110 String ShiftExpression() :
1115 StringBuffer buff = new StringBuffer();
1118 expr = AdditiveExpression()
1119 {buff.append(expr);}
1121 (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr2 = AdditiveExpression()
1123 buff.append(operator.image);
1127 {return buff.toString();}
1130 String AdditiveExpression() :
1135 StringBuffer buff = new StringBuffer();
1138 expr = MultiplicativeExpression()
1139 {buff.append(expr);}
1141 ( operator = <PLUS> | operator = <MINUS> ) expr2 = MultiplicativeExpression()
1143 buff.append(operator.image);
1147 {return buff.toString();}
1150 String MultiplicativeExpression() :
1154 final StringBuffer buff = new StringBuffer();}
1156 expr = UnaryExpression()
1157 {buff.append(expr);}
1159 ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr2 = UnaryExpression()
1161 buff.append(operator.image);
1165 {return buff.toString();}
1168 String UnaryExpression() :
1174 <AT> expr = UnaryExpression()
1175 {return "@" + expr;}
1177 ( token = <PLUS> | token = <MINUS> ) expr = UnaryExpression()
1179 return token.image + expr;
1182 expr = PreIncrementExpression()
1185 expr = PreDecrementExpression()
1188 expr = UnaryExpressionNotPlusMinus()
1192 String PreIncrementExpression() :
1197 <INCR> expr = PrimaryExpression()
1201 String PreDecrementExpression() :
1206 <DECR> expr = PrimaryExpression()
1210 String UnaryExpressionNotPlusMinus() :
1215 <BANG> expr = UnaryExpression()
1216 {return "!" + expr;}
1218 LOOKAHEAD( <LPAREN> Type() <RPAREN> )
1219 expr = CastExpression()
1222 expr = PostfixExpression()
1228 <LPAREN> expr = Expression()<RPAREN>
1229 {return "("+expr+")";}
1232 String CastExpression() :
1238 <LPAREN> type = Type() <RPAREN> expr = UnaryExpression()
1239 {return "(" + type + ")" + expr;}
1242 String PostfixExpression() :
1245 Token operator = null;
1248 expr = PrimaryExpression() [ operator = <INCR> | operator = <DECR> ]
1250 if (operator == null) {
1253 return expr + operator.image;
1257 String PrimaryExpression() :
1261 final StringBuffer buff = new StringBuffer();
1265 identifier = <IDENTIFIER> <STATICCLASSACCESS> expr = ClassIdentifier()
1266 {buff.append(identifier.image).append("::").append(expr);}
1268 expr = PrimarySuffix()
1269 {buff.append(expr);}
1271 {return buff.toString();}
1273 expr = PrimaryPrefix() {buff.append(expr);}
1274 ( expr = PrimarySuffix() {buff.append(expr);} )*
1275 {return buff.toString();}
1277 expr = ArrayDeclarator()
1278 {return "array" + expr;}
1281 String ArrayDeclarator() :
1286 <ARRAY> expr = ArrayInitializer()
1287 {return "array" + expr;}
1290 String PrimaryPrefix() :
1296 token = <IDENTIFIER>
1297 {return token.image;}
1299 [token = <BIT_AND>] <NEW> expr = ClassIdentifier()
1301 if (token == null) {
1302 return "new " + expr;
1304 return "new &" + expr;
1307 expr = VariableDeclaratorId()
1311 String ClassIdentifier():
1317 token = <IDENTIFIER>
1318 {return token.image;}
1320 expr = VariableDeclaratorId()
1324 String PrimarySuffix() :
1332 expr = VariableSuffix()
1336 String VariableSuffix() :
1341 <CLASSACCESS> expr = VariableName()
1342 {return "->" + expr;}
1344 <LBRACKET> [ expr = Expression() ]
1347 } catch (ParseException e) {
1348 errorMessage = "']' expected";
1350 throw generateParseException();
1356 return "[" + expr + "]";
1366 token = <INTEGER_LITERAL>
1367 {return token.image;}
1369 token = <FLOATING_POINT_LITERAL>
1370 {return token.image;}
1373 token = <STRING_LITERAL>
1374 {return token.image;}
1375 } catch (TokenMgrError e) {
1376 errorMessage = "unterminated string";
1378 throw generateParseException();
1381 expr = BooleanLiteral()
1384 expr = NullLiteral()
1388 String BooleanLiteral() :
1398 String NullLiteral() :
1405 String Arguments() :
1410 <LPAREN> [ expr = ArgumentList() ]
1413 } catch (ParseException e) {
1414 errorMessage = "')' expected to close the argument list";
1422 return "(" + expr + ")";
1426 String ArgumentList() :
1429 StringBuffer buff = new StringBuffer();
1433 {buff.append(expr);}
1437 } catch (ParseException e) {
1438 errorMessage = "expression expected after a comma in argument list";
1443 buff.append(",").append("expr");
1446 {return buff.toString();}
1450 * Statement syntax follows.
1459 (<SEMICOLON> | "?>")
1460 } catch (ParseException e) {
1461 errorMessage = "';' expected";
1473 StatementExpression()
1476 } catch (ParseException e) {
1477 errorMessage = "';' expected after expression";
1500 [<AT>] IncludeStatement()
1507 void IncludeStatement() :
1510 int pos = jj_input_stream.bufpos;
1515 {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));}
1517 (<SEMICOLON> | "?>")
1518 } catch (ParseException e) {
1519 errorMessage = "';' expected";
1526 {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));}
1528 (<SEMICOLON> | "?>")
1529 } catch (ParseException e) {
1530 errorMessage = "';' expected";
1537 {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));}
1539 (<SEMICOLON> | "?>")
1540 } catch (ParseException e) {
1541 errorMessage = "';' expected";
1548 {currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));}
1550 (<SEMICOLON> | "?>")
1551 } catch (ParseException e) {
1552 errorMessage = "';' expected";
1558 String PrintExpression() :
1560 StringBuffer buff = new StringBuffer("print ");
1564 <PRINT> expr = Expression()
1567 return buff.toString();
1571 void EchoStatement() :
1574 <ECHO> Expression() (<COMMA> Expression())*
1576 (<SEMICOLON> | "?>")
1577 } catch (ParseException e) {
1578 errorMessage = "';' expected after 'echo' statement";
1584 void GlobalStatement() :
1587 <GLOBAL> VariableDeclaratorId() (<COMMA> VariableDeclaratorId())*
1589 (<SEMICOLON> | "?>")
1590 } catch (ParseException e) {
1591 errorMessage = "';' expected";
1597 void StaticStatement() :
1600 <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
1602 (<SEMICOLON> | "?>")
1603 } catch (ParseException e) {
1604 errorMessage = "';' expected";
1610 void LabeledStatement() :
1613 <IDENTIFIER> <COLON> Statement()
1621 } catch (ParseException e) {
1622 errorMessage = "'{' expected";
1626 ( BlockStatement() )*
1630 void BlockStatement() :
1640 void LocalVariableDeclaration() :
1643 VariableDeclarator() ( <COMMA> VariableDeclarator() )*
1646 void EmptyStatement() :
1652 void StatementExpression() :
1655 PreIncrementExpression()
1657 PreDecrementExpression()
1665 AssignmentOperator() Expression()
1669 void SwitchStatement() :
1672 <SWITCH> <LPAREN> Expression() <RPAREN> <LBRACE>
1673 ( SwitchLabel() ( BlockStatement() )* )*
1677 void SwitchLabel() :
1680 <CASE> Expression() <COLON>
1685 void IfStatement() :
1687 * The disambiguating algorithm of JavaCC automatically binds dangling
1688 * else's to the innermost if statement. The LOOKAHEAD specification
1689 * is to tell JavaCC that we know what we are doing.
1693 <IF> Condition("if") Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
1696 void Condition(String keyword) :
1701 } catch (ParseException e) {
1702 errorMessage = "'(' expected after " + keyword + " keyword";
1709 } catch (ParseException e) {
1710 errorMessage = "')' expected after " + keyword + " keyword";
1716 void ElseIfStatement() :
1719 <ELSEIF> Condition("elseif") Statement()
1722 void WhileStatement() :
1725 <WHILE> Condition("while") WhileStatement0()
1728 void WhileStatement0() :
1731 <COLON> (Statement())* <ENDWHILE>
1733 (<SEMICOLON> | "?>")
1734 } catch (ParseException e) {
1735 errorMessage = "';' expected";
1743 void DoStatement() :
1746 <DO> Statement() <WHILE> Condition("while")
1748 (<SEMICOLON> | "?>")
1749 } catch (ParseException e) {
1750 errorMessage = "';' expected";
1756 void ForStatement() :
1759 <FOR> <LPAREN> [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ ForUpdate() ] <RPAREN> Statement()
1765 LOOKAHEAD(LocalVariableDeclaration())
1766 LocalVariableDeclaration()
1768 StatementExpressionList()
1771 void StatementExpressionList() :
1774 StatementExpression() ( <COMMA> StatementExpression() )*
1780 StatementExpressionList()
1783 void BreakStatement() :
1786 <BREAK> [ <IDENTIFIER> ] <SEMICOLON>
1789 void ContinueStatement() :
1792 <CONTINUE> [ <IDENTIFIER> ] <SEMICOLON>
1795 void ReturnStatement() :
1798 <RETURN> [ Expression() ] <SEMICOLON>