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;
34 import java.text.MessageFormat;
36 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
37 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
38 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
39 import net.sourceforge.phpdt.internal.compiler.parser.PHPSegmentWithChildren;
40 import net.sourceforge.phpdt.internal.compiler.parser.PHPFunctionDeclaration;
41 import net.sourceforge.phpdt.internal.compiler.parser.PHPClassDeclaration;
42 import net.sourceforge.phpdt.internal.compiler.parser.PHPVarDeclaration;
43 import net.sourceforge.phpdt.internal.compiler.parser.PHPReqIncDeclaration;
47 * This php parser is inspired by the Java 1.2 grammar example
48 * given with JavaCC. You can get JavaCC at http://www.webgain.com
49 * You can test the parser with the PHPParserTestCase2.java
50 * @author Matthieu Casanova
52 public final class PHPParser extends PHPParserSuperclass {
54 /** The file that is parsed. */
55 private static IFile fileToParse;
57 /** The current segment */
58 private static PHPSegmentWithChildren currentSegment;
60 private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
61 private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
62 PHPOutlineInfo outlineInfo;
64 /** The error level of the current ParseException. */
65 private static int errorLevel = ERROR;
66 /** The message of the current ParseException. If it's null it's because the parse exception wasn't handled */
67 private static String errorMessage;
69 private static int errorStart = -1;
70 private static int errorEnd = -1;
75 public final void setFileToParse(final IFile fileToParse) {
76 this.fileToParse = fileToParse;
79 public PHPParser(final IFile fileToParse) {
80 this(new StringReader(""));
81 this.fileToParse = fileToParse;
84 public static final void phpParserTester(final String strEval) throws CoreException, ParseException {
85 PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
86 final StringReader stream = new StringReader(strEval);
87 if (jj_input_stream == null) {
88 jj_input_stream = new SimpleCharStream(stream, 1, 1);
90 ReInit(new StringReader(strEval));
94 public static final void htmlParserTester(final File fileName) throws CoreException, ParseException {
96 final Reader stream = new FileReader(fileName);
97 if (jj_input_stream == null) {
98 jj_input_stream = new SimpleCharStream(stream, 1, 1);
102 } catch (FileNotFoundException e) {
103 e.printStackTrace(); //To change body of catch statement use Options | File Templates.
104 } catch (ParseException e) {
105 e.printStackTrace(); //To change body of catch statement use Options | File Templates.
109 public static final void htmlParserTester(final String strEval) throws CoreException, ParseException {
110 final StringReader stream = new StringReader(strEval);
111 if (jj_input_stream == null) {
112 jj_input_stream = new SimpleCharStream(stream, 1, 1);
118 public final PHPOutlineInfo parseInfo(final Object parent, final String s) {
119 outlineInfo = new PHPOutlineInfo(parent);
120 currentSegment = outlineInfo.getDeclarations();
121 final StringReader stream = new StringReader(s);
122 if (jj_input_stream == null) {
123 jj_input_stream = new SimpleCharStream(stream, 1, 1);
128 } catch (ParseException e) {
129 processParseException(e);
135 * This method will process the parse exception.
136 * If the error message is null, the parse exception wasn't catched and a trace is written in the log
137 * @param e the ParseException
139 private static void processParseException(final ParseException e) {
140 if (errorMessage == null) {
141 PHPeclipsePlugin.log(e);
142 errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it";
143 errorStart = jj_input_stream.getPosition();
144 errorEnd = errorStart + 1;
151 * Create marker for the parse error
152 * @param e the ParseException
154 private static void setMarker(final ParseException e) {
156 if (errorStart == -1) {
157 setMarker(fileToParse,
159 jj_input_stream.tokenBegin,
160 jj_input_stream.tokenBegin + e.currentToken.image.length(),
162 "Line " + e.currentToken.beginLine);
164 setMarker(fileToParse,
169 "Line " + e.currentToken.beginLine);
173 } catch (CoreException e2) {
174 PHPeclipsePlugin.log(e2);
179 * Create markers according to the external parser output
181 private static void createMarkers(final String output, final IFile file) throws CoreException {
182 // delete all markers
183 file.deleteMarkers(IMarker.PROBLEM, false, 0);
188 while ((brIndx = output.indexOf("<br />", indx)) != -1) {
189 // newer php error output (tested with 4.2.3)
190 scanLine(output, file, indx, brIndx);
195 while ((brIndx = output.indexOf("<br>", indx)) != -1) {
196 // older php error output (tested with 4.2.3)
197 scanLine(output, file, indx, brIndx);
203 private static void scanLine(final String output,
206 final int brIndx) throws CoreException {
208 StringBuffer lineNumberBuffer = new StringBuffer(10);
210 current = output.substring(indx, brIndx);
212 if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
213 int onLine = current.indexOf("on line <b>");
215 lineNumberBuffer.delete(0, lineNumberBuffer.length());
216 for (int i = onLine; i < current.length(); i++) {
217 ch = current.charAt(i);
218 if ('0' <= ch && '9' >= ch) {
219 lineNumberBuffer.append(ch);
223 int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
225 Hashtable attributes = new Hashtable();
227 current = current.replaceAll("\n", "");
228 current = current.replaceAll("<b>", "");
229 current = current.replaceAll("</b>", "");
230 MarkerUtilities.setMessage(attributes, current);
232 if (current.indexOf(PARSE_ERROR_STRING) != -1)
233 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
234 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
235 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
237 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
238 MarkerUtilities.setLineNumber(attributes, lineNumber);
239 MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
244 public final void parse(final String s) throws CoreException {
245 final StringReader stream = new StringReader(s);
246 if (jj_input_stream == null) {
247 jj_input_stream = new SimpleCharStream(stream, 1, 1);
252 } catch (ParseException e) {
253 processParseException(e);
258 * Call the php parse command ( php -l -f <filename> )
259 * and create markers according to the external parser output
261 public static void phpExternalParse(final IFile file) {
262 final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
263 final String filename = file.getLocation().toString();
265 final String[] arguments = { filename };
266 final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
267 final String command = form.format(arguments);
269 final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
272 // parse the buffer to find the errors and warnings
273 createMarkers(parserResult, file);
274 } catch (CoreException e) {
275 PHPeclipsePlugin.log(e);
279 public static final void parse() throws ParseException {
284 PARSER_END(PHPParser)
288 <PHPSTARTSHORT : "<?"> : PHPPARSING
289 | <PHPSTARTLONG : "<?php"> : PHPPARSING
290 | <PHPECHOSTART : "<?="> : PHPPARSING
295 <PHPEND :"?>"> : DEFAULT
317 <PHPPARSING> SPECIAL_TOKEN :
319 "//" : IN_SINGLE_LINE_COMMENT
321 "#" : IN_SINGLE_LINE_COMMENT
323 <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
325 "/*" : IN_MULTI_LINE_COMMENT
328 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
330 <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
333 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
335 <SINGLE_LINE_COMMENT_PHPEND : "?>" > : DEFAULT
341 <FORMAL_COMMENT: "*/" > : PHPPARSING
344 <IN_MULTI_LINE_COMMENT>
347 <MULTI_LINE_COMMENT: "*/" > : PHPPARSING
350 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
360 | <FUNCTION : "function">
363 | <ELSEIF : "elseif">
369 /* LANGUAGE CONSTRUCT */
374 | <INCLUDE : "include">
375 | <REQUIRE : "require">
376 | <INCLUDE_ONCE : "include_once">
377 | <REQUIRE_ONCE : "require_once">
378 | <GLOBAL : "global">
379 | <STATIC : "static">
380 | <CLASSACCESS : "->">
381 | <STATICCLASSACCESS : "::">
382 | <ARRAYASSIGN : "=>">
389 /* RESERVED WORDS AND LITERALS */
395 | <CONTINUE : "continue">
396 | <_DEFAULT : "default">
398 | <EXTENDS : "extends">
403 | <RETURN : "return">
405 | <SWITCH : "switch">
410 | <ENDWHILE : "endwhile">
412 | <ENDFOR : "endfor">
413 | <FOREACH : "foreach">
422 | <OBJECT : "object">
424 | <BOOLEAN : "boolean">
426 | <DOUBLE : "double">
429 | <INTEGER : "integer">
443 <DECIMAL_LITERAL> (["l","L"])?
444 | <HEX_LITERAL> (["l","L"])?
445 | <OCTAL_LITERAL> (["l","L"])?
448 < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
450 < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
452 < #OCTAL_LITERAL: "0" (["0"-"7"])* >
454 < FLOATING_POINT_LITERAL:
455 (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
456 | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
457 | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
458 | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
461 < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
463 < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
498 < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
501 ["a"-"z"] | ["A"-"Z"]
509 "_" | ["\u007f"-"\u00ff"]
539 | <BANGDOUBLEEQUAL : "!==">
540 | <TRIPLEEQUAL : "===">
547 | <PLUSASSIGN : "+=">
548 | <MINUSASSIGN : "-=">
549 | <STARASSIGN : "*=">
550 | <SLASHASSIGN : "/=">
556 | <TILDEEQUAL : "~=">
580 | <RSIGNEDSHIFT : ">>">
581 | <RUNSIGNEDSHIFT : ">>>">
582 | <LSHIFTASSIGN : "<<=">
583 | <RSIGNEDSHIFTASSIGN : ">>=">
588 < DOLLAR_ID: <DOLLAR> <IDENTIFIER> >
604 } catch (TokenMgrError e) {
605 errorMessage = e.getMessage();
607 throw generateParseException();
613 final int start = jj_input_stream.getPosition();
616 <PHPECHOSTART> Expression() [ <SEMICOLON> ] <PHPEND>
621 setMarker(fileToParse,
622 "You should use '<?php' instead of '<?' it will avoid some problems with XML",
624 jj_input_stream.getPosition(),
626 "Line " + token.beginLine);
627 } catch (CoreException e) {
628 PHPeclipsePlugin.log(e);
634 } catch (ParseException e) {
635 errorMessage = "'?>' expected";
637 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
638 errorEnd = jj_input_stream.getPosition() + 1;
649 void ClassDeclaration() :
651 final PHPClassDeclaration classDeclaration;
652 final Token className;
658 {pos = jj_input_stream.getPosition();}
659 className = <IDENTIFIER>
660 } catch (ParseException e) {
661 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
663 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
664 errorEnd = jj_input_stream.getPosition() + 1;
671 } catch (ParseException e) {
672 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
674 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
675 errorEnd = jj_input_stream.getPosition() + 1;
680 if (currentSegment != null) {
681 classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
682 currentSegment.add(classDeclaration);
683 currentSegment = classDeclaration;
688 if (currentSegment != null) {
689 currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
699 } catch (ParseException e) {
700 errorMessage = "unexpected token : '"+ e.currentToken.next.image + "', '{' expected";
702 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
703 errorEnd = jj_input_stream.getPosition() + 1;
706 ( ClassBodyDeclaration() )*
709 } catch (ParseException e) {
710 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', 'var', 'function' or '}' expected";
712 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
713 errorEnd = jj_input_stream.getPosition() + 1;
718 void ClassBodyDeclaration() :
726 void FieldDeclaration() :
728 PHPVarDeclaration variableDeclaration;
731 <VAR> variableDeclaration = VariableDeclarator()
733 if (currentSegment != null) {
734 currentSegment.add(variableDeclaration);
738 variableDeclaration = VariableDeclarator()
740 if (currentSegment != null) {
741 currentSegment.add(variableDeclaration);
747 } catch (ParseException e) {
748 errorMessage = "';' expected after variable declaration";
750 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
751 errorEnd = jj_input_stream.getPosition() + 1;
756 PHPVarDeclaration VariableDeclarator() :
758 final String varName;
759 final String varValue;
760 final int pos = jj_input_stream.getPosition();
763 varName = VariableDeclaratorId()
767 varValue = VariableInitializer()
768 {return new PHPVarDeclaration(currentSegment,varName,pos,varValue);}
769 } catch (ParseException e) {
770 errorMessage = "Literal expression expected in variable initializer";
772 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
773 errorEnd = jj_input_stream.getPosition() + 1;
777 {return new PHPVarDeclaration(currentSegment,varName,pos);}
780 String VariableDeclaratorId() :
783 final StringBuffer buff = new StringBuffer();
789 ( LOOKAHEAD(2) expr = VariableSuffix()
792 {return buff.toString();}
793 } catch (ParseException e) {
794 errorMessage = "'$' expected for variable identifier";
796 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
797 errorEnd = jj_input_stream.getPosition() + 1;
808 token = <DOLLAR_ID> [<LBRACE> expr = Expression() <RBRACE>]
813 return token + "{" + expr + "}";
816 <DOLLAR> expr = VariableName()
820 String VariableName():
826 <LBRACE> expr = Expression() <RBRACE>
827 {return "{"+expr+"}";}
829 token = <IDENTIFIER> [<LBRACE> expr = Expression() <RBRACE>]
834 return token + "{" + expr + "}";
837 <DOLLAR> expr = VariableName()
841 {return token.image + expr;}
843 token = <DOLLAR_ID> [expr = VariableName()]
848 return token.image + expr;
852 String VariableInitializer() :
861 <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
862 {return "-" + token.image;}
864 <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
865 {return "+" + token.image;}
867 expr = ArrayDeclarator()
871 {return token.image;}
874 String ArrayVariable() :
877 final StringBuffer buff = new StringBuffer();
882 [<ARRAYASSIGN> expr = Expression()
883 {buff.append("=>").append(expr);}]
884 {return buff.toString();}
887 String ArrayInitializer() :
890 final StringBuffer buff = new StringBuffer("(");
893 <LPAREN> [ expr = ArrayVariable()
895 ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
896 {buff.append(",").append(expr);}
901 return buff.toString();
905 void MethodDeclaration() :
907 final PHPFunctionDeclaration functionDeclaration;
912 functionDeclaration = MethodDeclarator()
913 } catch (ParseException e) {
914 if (errorMessage != null) {
917 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
919 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
920 errorEnd = jj_input_stream.getPosition() + 1;
924 if (currentSegment != null) {
925 currentSegment.add(functionDeclaration);
926 currentSegment = functionDeclaration;
931 if (currentSegment != null) {
932 currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
938 * A MethodDeclarator contains [&] IDENTIFIER(parameters ...).
939 * @return a function description for the outline
941 PHPFunctionDeclaration MethodDeclarator() :
943 final Token identifier;
944 final StringBuffer methodDeclaration = new StringBuffer();
945 final String formalParameters;
946 final int pos = jj_input_stream.getPosition();
949 [ <BIT_AND> {methodDeclaration.append("&");} ]
950 identifier = <IDENTIFIER>
951 {methodDeclaration.append(identifier);}
952 formalParameters = FormalParameters()
954 methodDeclaration.append(formalParameters);
955 return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos);
959 String FormalParameters() :
962 final StringBuffer buff = new StringBuffer("(");
967 } catch (ParseException e) {
968 errorMessage = "Formal parameter expected after function identifier";
970 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
971 errorEnd = jj_input_stream.getPosition() + 1;
974 [ expr = FormalParameter()
977 <COMMA> expr = FormalParameter()
978 {buff.append(",").append(expr);}
983 } catch (ParseException e) {
984 errorMessage = "')' expected";
986 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
987 errorEnd = jj_input_stream.getPosition() + 1;
992 return buff.toString();
996 String FormalParameter() :
998 final PHPVarDeclaration variableDeclaration;
999 final StringBuffer buff = new StringBuffer();
1002 [<BIT_AND> {buff.append("&");}] variableDeclaration = VariableDeclarator()
1004 buff.append(variableDeclaration.toString());
1005 return buff.toString();
1040 String Expression() :
1043 final String assignOperator;
1047 expr = PrintExpression()
1050 expr = ListExpression()
1053 expr = ConditionalExpression()
1055 assignOperator = AssignmentOperator()
1057 expr2 = Expression()
1058 {return expr + assignOperator + expr2;}
1059 } catch (ParseException e) {
1060 errorMessage = "expression expected";
1062 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1063 errorEnd = jj_input_stream.getPosition() + 1;
1070 String AssignmentOperator() :
1087 | <RSIGNEDSHIFTASSIGN>
1101 String ConditionalExpression() :
1104 String expr2 = null;
1105 String expr3 = null;
1108 expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
1110 if (expr3 == null) {
1113 return expr + "?" + expr2 + ":" + expr3;
1118 String ConditionalOrExpression() :
1122 final StringBuffer buff = new StringBuffer();
1125 expr = ConditionalAndExpression()
1126 {buff.append(expr);}
1128 (operator = <SC_OR> | operator = <_ORL>) expr = ConditionalAndExpression()
1130 buff.append(operator.image);
1135 return buff.toString();
1139 String ConditionalAndExpression() :
1143 final StringBuffer buff = new StringBuffer();
1146 expr = ConcatExpression()
1147 {buff.append(expr);}
1149 (operator = <SC_AND> | operator = <_ANDL>) expr = ConcatExpression()
1151 buff.append(operator.image);
1155 {return buff.toString();}
1158 String ConcatExpression() :
1161 final StringBuffer buff = new StringBuffer();
1164 expr = InclusiveOrExpression()
1165 {buff.append(expr);}
1167 <DOT> expr = InclusiveOrExpression()
1168 {buff.append(".").append(expr);}
1170 {return buff.toString();}
1173 String InclusiveOrExpression() :
1176 final StringBuffer buff = new StringBuffer();
1179 expr = ExclusiveOrExpression()
1180 {buff.append(expr);}
1182 <BIT_OR> expr = ExclusiveOrExpression()
1183 {buff.append("|").append(expr);}
1185 {return buff.toString();}
1188 String ExclusiveOrExpression() :
1191 final StringBuffer buff = new StringBuffer();
1194 expr = AndExpression()
1199 <XOR> expr = AndExpression()
1206 return buff.toString();
1210 String AndExpression() :
1213 final StringBuffer buff = new StringBuffer();
1216 expr = EqualityExpression()
1221 <BIT_AND> expr = EqualityExpression()
1223 buff.append("&").append(expr);
1226 {return buff.toString();}
1229 String EqualityExpression() :
1233 final StringBuffer buff = new StringBuffer();
1236 expr = RelationalExpression()
1237 {buff.append(expr);}
1242 | operator = <BANGDOUBLEEQUAL>
1243 | operator = <TRIPLEEQUAL>
1246 expr = RelationalExpression()
1247 } catch (ParseException e) {
1248 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected after '"+operator.image+"'";
1250 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1251 errorEnd = jj_input_stream.getPosition() + 1;
1255 buff.append(operator.image);
1259 {return buff.toString();}
1262 String RelationalExpression() :
1266 final StringBuffer buff = new StringBuffer();
1269 expr = ShiftExpression()
1270 {buff.append(expr);}
1272 ( operator = <LT> | operator = <GT> | operator = <LE> | operator = <GE> ) expr = ShiftExpression()
1273 {buff.append(operator.image).append(expr);}
1275 {return buff.toString();}
1278 String ShiftExpression() :
1282 final StringBuffer buff = new StringBuffer();
1285 expr = AdditiveExpression()
1286 {buff.append(expr);}
1288 (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr = AdditiveExpression()
1290 buff.append(operator.image);
1294 {return buff.toString();}
1297 String AdditiveExpression() :
1301 final StringBuffer buff = new StringBuffer();
1304 expr = MultiplicativeExpression()
1305 {buff.append(expr);}
1307 ( operator = <PLUS> | operator = <MINUS> ) expr = MultiplicativeExpression()
1309 buff.append(operator.image);
1313 {return buff.toString();}
1316 String MultiplicativeExpression() :
1320 final StringBuffer buff = new StringBuffer();}
1323 expr = UnaryExpression()
1324 } catch (ParseException e) {
1325 errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
1327 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1328 errorEnd = jj_input_stream.getPosition() + 1;
1331 {buff.append(expr);}
1333 ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr = UnaryExpression()
1335 buff.append(operator.image);
1339 {return buff.toString();}
1343 * An unary expression starting with @, & or nothing
1345 String UnaryExpression() :
1349 final StringBuffer buff = new StringBuffer();
1352 token = <BIT_AND> expr = UnaryExpressionNoPrefix()
1354 if (token == null) {
1357 return token.image + expr;
1360 (<AT> {buff.append("@");})* expr = UnaryExpressionNoPrefix()
1361 {return buff.append(expr).toString();}
1364 String UnaryExpressionNoPrefix() :
1370 ( token = <PLUS> | token = <MINUS> ) expr = UnaryExpression()
1372 return token.image + expr;
1375 expr = PreIncrementExpression()
1378 expr = PreDecrementExpression()
1381 expr = UnaryExpressionNotPlusMinus()
1386 String PreIncrementExpression() :
1391 <INCR> expr = PrimaryExpression()
1395 String PreDecrementExpression() :
1400 <DECR> expr = PrimaryExpression()
1404 String UnaryExpressionNotPlusMinus() :
1409 <BANG> expr = UnaryExpression()
1410 {return "!" + expr;}
1412 LOOKAHEAD( <LPAREN> Type() <RPAREN> )
1413 expr = CastExpression()
1416 expr = PostfixExpression()
1422 <LPAREN> expr = Expression()
1425 } catch (ParseException e) {
1426 errorMessage = "')' expected";
1428 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1429 errorEnd = jj_input_stream.getPosition() + 1;
1432 {return "("+expr+")";}
1435 String CastExpression() :
1437 final String type, expr;
1440 <LPAREN> type = Type() <RPAREN> expr = UnaryExpression()
1441 {return "(" + type + ")" + expr;}
1444 String PostfixExpression() :
1447 Token operator = null;
1450 expr = PrimaryExpression() [ operator = <INCR> | operator = <DECR> ]
1452 if (operator == null) {
1455 return expr + operator.image;
1459 String PrimaryExpression() :
1461 final Token identifier;
1463 final StringBuffer buff = new StringBuffer();
1467 identifier = <IDENTIFIER> <STATICCLASSACCESS> expr = ClassIdentifier()
1468 {buff.append(identifier.image).append("::").append(expr);}
1470 expr = PrimarySuffix()
1471 {buff.append(expr);}
1473 {return buff.toString();}
1475 expr = PrimaryPrefix() {buff.append(expr);}
1476 ( expr = PrimarySuffix() {buff.append(expr);} )*
1477 {return buff.toString();}
1479 expr = ArrayDeclarator()
1480 {return "array" + expr;}
1483 String ArrayDeclarator() :
1488 <ARRAY> expr = ArrayInitializer()
1489 {return "array" + expr;}
1492 String PrimaryPrefix() :
1498 token = <IDENTIFIER>
1499 {return token.image;}
1501 <NEW> expr = ClassIdentifier()
1503 return "new " + expr;
1506 expr = VariableDeclaratorId()
1510 String classInstantiation() :
1513 final StringBuffer buff = new StringBuffer("new ");
1516 <NEW> expr = ClassIdentifier()
1517 {buff.append(expr);}
1519 expr = PrimaryExpression()
1520 {buff.append(expr);}
1522 {return buff.toString();}
1525 String ClassIdentifier():
1531 token = <IDENTIFIER>
1532 {return token.image;}
1534 expr = VariableDeclaratorId()
1538 String PrimarySuffix() :
1546 expr = VariableSuffix()
1550 String VariableSuffix() :
1557 expr = VariableName()
1558 } catch (ParseException e) {
1559 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
1561 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1562 errorEnd = jj_input_stream.getPosition() + 1;
1565 {return "->" + expr;}
1567 <LBRACKET> [ expr = Expression() ]
1570 } catch (ParseException e) {
1571 errorMessage = "']' expected";
1573 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1574 errorEnd = jj_input_stream.getPosition() + 1;
1581 return "[" + expr + "]";
1591 token = <INTEGER_LITERAL>
1592 {return token.image;}
1594 token = <FLOATING_POINT_LITERAL>
1595 {return token.image;}
1597 token = <STRING_LITERAL>
1598 {return token.image;}
1600 expr = BooleanLiteral()
1603 expr = NullLiteral()
1607 String BooleanLiteral() :
1617 String NullLiteral() :
1624 String Arguments() :
1629 <LPAREN> [ expr = ArgumentList() ]
1632 } catch (ParseException e) {
1633 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
1635 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1636 errorEnd = jj_input_stream.getPosition() + 1;
1643 return "(" + expr + ")";
1647 String ArgumentList() :
1650 final StringBuffer buff = new StringBuffer();
1654 {buff.append(expr);}
1658 } catch (ParseException e) {
1659 errorMessage = "expression expected after a comma in argument list";
1661 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1662 errorEnd = jj_input_stream.getPosition() + 1;
1666 buff.append(",").append(expr);
1669 {return buff.toString();}
1673 * A Statement without break
1675 void StatementNoBreak() :
1681 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1682 } catch (ParseException e) {
1683 errorMessage = "';' expected";
1685 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1686 errorEnd = jj_input_stream.getPosition() + 1;
1697 StatementExpression()
1700 } catch (ParseException e) {
1701 errorMessage = "';' expected after expression";
1703 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1704 errorEnd = jj_input_stream.getPosition() + 1;
1726 [<AT>] IncludeStatement()
1734 * A Normal statement
1744 void IncludeStatement() :
1747 final int pos = jj_input_stream.getPosition();
1753 if (currentSegment != null) {
1754 currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require",pos,expr));
1758 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1759 } catch (ParseException e) {
1760 errorMessage = "';' expected";
1762 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1763 errorEnd = jj_input_stream.getPosition() + 1;
1770 if (currentSegment != null) {
1771 currentSegment.add(new PHPReqIncDeclaration(currentSegment, "require_once",pos,expr));
1775 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1776 } catch (ParseException e) {
1777 errorMessage = "';' expected";
1779 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1780 errorEnd = jj_input_stream.getPosition() + 1;
1787 if (currentSegment != null) {
1788 currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include",pos,expr));
1792 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1793 } catch (ParseException e) {
1794 errorMessage = "';' expected";
1796 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1797 errorEnd = jj_input_stream.getPosition() + 1;
1804 if (currentSegment != null) {
1805 currentSegment.add(new PHPReqIncDeclaration(currentSegment, "include_once",pos,expr));
1809 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1810 } catch (ParseException e) {
1811 errorMessage = "';' expected";
1813 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1814 errorEnd = jj_input_stream.getPosition() + 1;
1819 String PrintExpression() :
1821 final StringBuffer buff = new StringBuffer("print ");
1825 <PRINT> expr = Expression()
1828 return buff.toString();
1832 String ListExpression() :
1834 final StringBuffer buff = new StringBuffer("list(");
1841 } catch (ParseException e) {
1842 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
1844 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1845 errorEnd = jj_input_stream.getPosition() + 1;
1849 expr = VariableDeclaratorId()
1850 {buff.append(expr);}
1855 } catch (ParseException e) {
1856 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
1858 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1859 errorEnd = jj_input_stream.getPosition() + 1;
1862 expr = VariableDeclaratorId()
1863 {buff.append(",").append(expr);}
1868 } catch (ParseException e) {
1869 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
1871 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1872 errorEnd = jj_input_stream.getPosition() + 1;
1875 [ <ASSIGN> expr = Expression() {buff.append("(").append(expr);}]
1876 {return buff.toString();}
1879 void EchoStatement() :
1882 <ECHO> Expression() (<COMMA> Expression())*
1884 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1885 } catch (ParseException e) {
1886 errorMessage = "';' expected after 'echo' statement";
1888 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1889 errorEnd = jj_input_stream.getPosition() + 1;
1894 void GlobalStatement() :
1897 <GLOBAL> VariableDeclaratorId() (<COMMA> VariableDeclaratorId())*
1899 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1900 } catch (ParseException e) {
1901 errorMessage = "';' expected";
1903 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1904 errorEnd = jj_input_stream.getPosition() + 1;
1909 void StaticStatement() :
1912 <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
1914 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
1915 } catch (ParseException e) {
1916 errorMessage = "';' expected";
1918 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1919 errorEnd = jj_input_stream.getPosition() + 1;
1924 void LabeledStatement() :
1927 <IDENTIFIER> <COLON> Statement()
1935 } catch (ParseException e) {
1936 errorMessage = "'{' expected";
1938 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1939 errorEnd = jj_input_stream.getPosition() + 1;
1942 ( BlockStatement() )*
1945 } catch (ParseException e) {
1946 errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
1948 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
1949 errorEnd = jj_input_stream.getPosition() + 1;
1954 void BlockStatement() :
1965 * A Block statement that will not contain any 'break'
1967 void BlockStatementNoBreak() :
1977 void LocalVariableDeclaration() :
1980 LocalVariableDeclarator() ( <COMMA> LocalVariableDeclarator() )*
1983 void LocalVariableDeclarator() :
1986 VariableDeclaratorId() [ <ASSIGN> Expression() ]
1989 void EmptyStatement() :
1995 void StatementExpression() :
1998 PreIncrementExpression()
2000 PreDecrementExpression()
2008 AssignmentOperator() Expression()
2012 void SwitchStatement() :
2014 Token breakToken = null;
2021 } catch (ParseException e) {
2022 errorMessage = "'(' expected after 'switch'";
2024 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2025 errorEnd = jj_input_stream.getPosition() + 1;
2031 } catch (ParseException e) {
2032 errorMessage = "')' expected";
2034 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2035 errorEnd = jj_input_stream.getPosition() + 1;
2040 } catch (ParseException e) {
2041 errorMessage = "'{' expected";
2043 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2044 errorEnd = jj_input_stream.getPosition() + 1;
2048 line = SwitchLabel()
2049 ( BlockStatementNoBreak() )*
2050 [ breakToken = BreakStatement() ]
2053 if (breakToken == null) {
2054 setMarker(fileToParse,
2055 "You should use put a 'break' at the end of your statement",
2060 } catch (CoreException e) {
2061 PHPeclipsePlugin.log(e);
2067 } catch (ParseException e) {
2068 errorMessage = "'}' expected";
2070 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2071 errorEnd = jj_input_stream.getPosition() + 1;
2076 Token BreakStatement() :
2081 token = <BREAK> [ Expression() ]
2084 } catch (ParseException e) {
2085 errorMessage = "';' expected after 'break' keyword";
2087 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2088 errorEnd = jj_input_stream.getPosition() + 1;
2102 } catch (ParseException e) {
2103 if (errorMessage != null) throw e;
2104 errorMessage = "expression expected after 'case' keyword";
2106 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2107 errorEnd = jj_input_stream.getPosition() + 1;
2112 } catch (ParseException e) {
2113 errorMessage = "':' expected after case expression";
2115 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2116 errorEnd = jj_input_stream.getPosition() + 1;
2119 {return token.beginLine;}
2124 } catch (ParseException e) {
2125 errorMessage = "':' expected after 'default' keyword";
2127 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2128 errorEnd = jj_input_stream.getPosition() + 1;
2131 {return token.beginLine;}
2134 void IfStatement() :
2137 final int pos = jj_input_stream.getPosition();
2140 token = <IF> Condition("if") IfStatement0(pos,pos+token.image.length())
2143 void Condition(final String keyword) :
2148 } catch (ParseException e) {
2149 errorMessage = "'(' expected after " + keyword + " keyword";
2151 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length();
2152 errorEnd = errorStart +1;
2153 processParseException(e);
2158 } catch (ParseException e) {
2159 errorMessage = "')' expected after " + keyword + " keyword";
2161 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2162 errorEnd = jj_input_stream.getPosition() + 1;
2167 void IfStatement0(final int start,final int end) :
2170 <COLON> (Statement())* (ElseIfStatementColon())* [ElseStatementColon()]
2173 setMarker(fileToParse,
2174 "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
2178 "Line " + token.beginLine);
2179 } catch (CoreException e) {
2180 PHPeclipsePlugin.log(e);
2184 } catch (ParseException e) {
2185 errorMessage = "'endif' expected";
2187 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2188 errorEnd = jj_input_stream.getPosition() + 1;
2193 } catch (ParseException e) {
2194 errorMessage = "';' expected after 'endif' keyword";
2196 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2197 errorEnd = jj_input_stream.getPosition() + 1;
2201 Statement() ( LOOKAHEAD(1) ElseIfStatement() )* [ LOOKAHEAD(1) <ELSE> Statement() ]
2204 void ElseIfStatementColon() :
2207 <ELSEIF> Condition("elseif") <COLON> (Statement())*
2210 void ElseStatementColon() :
2213 <ELSE> <COLON> (Statement())*
2216 void ElseIfStatement() :
2219 <ELSEIF> Condition("elseif") Statement()
2222 void WhileStatement() :
2225 final int pos = jj_input_stream.getPosition();
2228 token = <WHILE> Condition("while") WhileStatement0(pos,pos + token.image.length())
2231 void WhileStatement0(final int start, final int end) :
2234 <COLON> (Statement())*
2236 setMarker(fileToParse,
2237 "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
2241 "Line " + token.beginLine);
2242 } catch (CoreException e) {
2243 PHPeclipsePlugin.log(e);
2247 } catch (ParseException e) {
2248 errorMessage = "'endwhile' expected";
2250 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2251 errorEnd = jj_input_stream.getPosition() + 1;
2255 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
2256 } catch (ParseException e) {
2257 errorMessage = "';' expected after 'endwhile' keyword";
2259 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2260 errorEnd = jj_input_stream.getPosition() + 1;
2267 void DoStatement() :
2270 <DO> Statement() <WHILE> Condition("while")
2272 (<SEMICOLON> | <PHPEND> {PHPParserTokenManager.SwitchTo(PHPParserTokenManager.DEFAULT);})
2273 } catch (ParseException e) {
2274 errorMessage = "';' expected";
2276 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2277 errorEnd = jj_input_stream.getPosition() + 1;
2282 void ForeachStatement() :
2288 } catch (ParseException e) {
2289 errorMessage = "'(' expected after 'foreach' keyword";
2291 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2292 errorEnd = jj_input_stream.getPosition() + 1;
2297 } catch (ParseException e) {
2298 errorMessage = "variable expected";
2300 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2301 errorEnd = jj_input_stream.getPosition() + 1;
2304 [ VariableSuffix() ]
2307 } catch (ParseException e) {
2308 errorMessage = "'as' expected";
2310 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2311 errorEnd = jj_input_stream.getPosition() + 1;
2316 } catch (ParseException e) {
2317 errorMessage = "variable expected";
2319 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2320 errorEnd = jj_input_stream.getPosition() + 1;
2323 [ <ARRAYASSIGN> Expression() ]
2326 } catch (ParseException e) {
2327 errorMessage = "')' expected after 'foreach' keyword";
2329 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2330 errorEnd = jj_input_stream.getPosition() + 1;
2335 } catch (ParseException e) {
2336 if (errorMessage != null) throw e;
2337 errorMessage = "statement expected";
2339 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2340 errorEnd = jj_input_stream.getPosition() + 1;
2345 void ForStatement() :
2348 final int pos = jj_input_stream.getPosition();
2354 } catch (ParseException e) {
2355 errorMessage = "'(' expected after 'for' keyword";
2357 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2358 errorEnd = jj_input_stream.getPosition() + 1;
2361 [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ StatementExpressionList() ] <RPAREN>
2365 <COLON> (Statement())*
2368 setMarker(fileToParse,
2369 "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
2371 pos+token.image.length(),
2373 "Line " + token.beginLine);
2374 } catch (CoreException e) {
2375 PHPeclipsePlugin.log(e);
2380 } catch (ParseException e) {
2381 errorMessage = "'endfor' expected";
2383 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2384 errorEnd = jj_input_stream.getPosition() + 1;
2389 } catch (ParseException e) {
2390 errorMessage = "';' expected after 'endfor' keyword";
2392 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2393 errorEnd = jj_input_stream.getPosition() + 1;
2402 LOOKAHEAD(LocalVariableDeclaration())
2403 LocalVariableDeclaration()
2405 StatementExpressionList()
2408 void StatementExpressionList() :
2411 StatementExpression() ( <COMMA> StatementExpression() )*
2414 void ContinueStatement() :
2417 <CONTINUE> [ <IDENTIFIER> ]
2420 } catch (ParseException e) {
2421 errorMessage = "';' expected after 'continue' statement";
2423 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2424 errorEnd = jj_input_stream.getPosition() + 1;
2429 void ReturnStatement() :
2432 <RETURN> [ Expression() ]
2435 } catch (ParseException e) {
2436 errorMessage = "';' expected after 'return' statement";
2438 errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
2439 errorEnd = jj_input_stream.getPosition() + 1;