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;
20 COMMON_TOKEN_ACTION = true;
23 PARSER_BEGIN(PHPParser)
26 import org.eclipse.core.resources.IFile;
27 import org.eclipse.core.resources.IMarker;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.ui.texteditor.MarkerUtilities;
30 import org.eclipse.jface.preference.IPreferenceStore;
32 import java.util.Hashtable;
33 import java.util.ArrayList;
34 import java.io.StringReader;
36 import java.text.MessageFormat;
38 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
39 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
40 import net.sourceforge.phpdt.internal.compiler.ast.*;
41 import net.sourceforge.phpdt.internal.compiler.parser.OutlineableWithChildren;
42 import net.sourceforge.phpdt.internal.compiler.parser.Outlineable;
43 import net.sourceforge.phpdt.internal.compiler.parser.PHPOutlineInfo;
44 import net.sourceforge.phpdt.internal.corext.Assert;
48 * This php parser is inspired by the Java 1.2 grammar example
49 * given with JavaCC. You can get JavaCC at http://www.webgain.com
50 * You can test the parser with the PHPParserTestCase2.java
51 * @author Matthieu Casanova
53 public final class PHPParser extends PHPParserSuperclass {
55 /** The current segment. */
56 private static OutlineableWithChildren 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 static PHPOutlineInfo outlineInfo;
62 /** The error level of the current ParseException. */
63 private static int errorLevel = ERROR;
64 /** The message of the current ParseException. If it's null it's because the parse exception wasn't handled */
65 private static String errorMessage;
67 private static int errorStart = -1;
68 private static int errorEnd = -1;
69 private static PHPDocument phpDocument;
71 private static final String SYNTAX_ERROR_CHAR = "syntax error";
73 * The point where html starts.
74 * It will be used by the token manager to create HTMLCode objects
76 public static int htmlStart;
79 private final static int AstStackIncrement = 100;
80 /** The stack of node. */
81 private static AstNode[] nodes;
82 /** The cursor in expression stack. */
83 private static int nodePtr;
85 private static final boolean PARSER_DEBUG = false;
87 public final void setFileToParse(final IFile fileToParse) {
88 PHPParser.fileToParse = fileToParse;
94 public PHPParser(final IFile fileToParse) {
95 this(new StringReader(""));
96 PHPParser.fileToParse = fileToParse;
99 public static final void phpParserTester(final String strEval) throws ParseException {
100 final StringReader stream = new StringReader(strEval);
101 if (jj_input_stream == null) {
102 jj_input_stream = new SimpleCharStream(stream, 1, 1);
104 ReInit(new StringReader(strEval));
106 phpDocument = new PHPDocument(null,"_root".toCharArray());
107 currentSegment = phpDocument;
108 outlineInfo = new PHPOutlineInfo(null, currentSegment);
109 PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
113 public static final void htmlParserTester(final File fileName) throws FileNotFoundException, ParseException {
114 final Reader stream = new FileReader(fileName);
115 if (jj_input_stream == null) {
116 jj_input_stream = new SimpleCharStream(stream, 1, 1);
120 phpDocument = new PHPDocument(null,"_root".toCharArray());
121 currentSegment = phpDocument;
122 outlineInfo = new PHPOutlineInfo(null, currentSegment);
126 public static final void htmlParserTester(final String strEval) throws ParseException {
127 final StringReader stream = new StringReader(strEval);
128 if (jj_input_stream == null) {
129 jj_input_stream = new SimpleCharStream(stream, 1, 1);
133 phpDocument = new PHPDocument(null,"_root".toCharArray());
134 currentSegment = phpDocument;
135 outlineInfo = new PHPOutlineInfo(null, currentSegment);
140 * Reinitialize the parser.
142 private static final void init() {
143 nodes = new AstNode[AstStackIncrement];
149 * Add an php node on the stack.
150 * @param node the node that will be added to the stack
152 private static final void pushOnAstNodes(final AstNode node) {
154 nodes[++nodePtr] = node;
155 } catch (IndexOutOfBoundsException e) {
156 final int oldStackLength = nodes.length;
157 final AstNode[] oldStack = nodes;
158 nodes = new AstNode[oldStackLength + AstStackIncrement];
159 System.arraycopy(oldStack, 0, nodes, 0, oldStackLength);
160 nodePtr = oldStackLength;
161 nodes[nodePtr] = node;
165 public final PHPOutlineInfo parseInfo(final Object parent, final String s) {
166 phpDocument = new PHPDocument(parent,"_root".toCharArray());
167 currentSegment = phpDocument;
168 outlineInfo = new PHPOutlineInfo(parent, currentSegment);
169 final StringReader stream = new StringReader(s);
170 if (jj_input_stream == null) {
171 jj_input_stream = new SimpleCharStream(stream, 1, 1);
177 phpDocument.nodes = new AstNode[nodes.length];
178 System.arraycopy(nodes,0,phpDocument.nodes,0,nodes.length);
179 if (PHPeclipsePlugin.DEBUG) {
180 PHPeclipsePlugin.log(1,phpDocument.toString());
182 } catch (ParseException e) {
183 processParseException(e);
188 private static void processParseExceptionDebug(final ParseException e) throws ParseException {
192 processParseException(e);
195 * This method will process the parse exception.
196 * If the error message is null, the parse exception wasn't catched and a trace is written in the log
197 * @param e the ParseException
199 private static void processParseException(final ParseException e) {
200 if (errorMessage == null) {
201 PHPeclipsePlugin.log(e);
202 errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it";
203 errorStart = e.currentToken.sourceStart;
204 errorEnd = e.currentToken.sourceEnd;
208 // if (PHPeclipsePlugin.DEBUG) PHPeclipsePlugin.log(e);
212 * Create marker for the parse error.
213 * @param e the ParseException
215 private static void setMarker(final ParseException e) {
217 if (errorStart == -1) {
218 setMarker(fileToParse,
220 e.currentToken.sourceStart,
221 e.currentToken.sourceEnd,
223 "Line " + e.currentToken.beginLine);
225 setMarker(fileToParse,
230 "Line " + e.currentToken.beginLine);
234 } catch (CoreException e2) {
235 PHPeclipsePlugin.log(e2);
239 private static void scanLine(final String output,
242 final int brIndx) throws CoreException {
244 final StringBuffer lineNumberBuffer = new StringBuffer(10);
246 current = output.substring(indx, brIndx);
248 if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
249 final int onLine = current.indexOf("on line <b>");
251 lineNumberBuffer.delete(0, lineNumberBuffer.length());
252 for (int i = onLine; i < current.length(); i++) {
253 ch = current.charAt(i);
254 if ('0' <= ch && '9' >= ch) {
255 lineNumberBuffer.append(ch);
259 final int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
261 final Hashtable attributes = new Hashtable();
263 current = current.replaceAll("\n", "");
264 current = current.replaceAll("<b>", "");
265 current = current.replaceAll("</b>", "");
266 MarkerUtilities.setMessage(attributes, current);
268 if (current.indexOf(PARSE_ERROR_STRING) != -1)
269 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
270 else if (current.indexOf(PARSE_WARNING_STRING) != -1)
271 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
273 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
274 MarkerUtilities.setLineNumber(attributes, lineNumber);
275 MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
280 public final void parse(final String s) {
281 final StringReader stream = new StringReader(s);
282 if (jj_input_stream == null) {
283 jj_input_stream = new SimpleCharStream(stream, 1, 1);
289 } catch (ParseException e) {
290 processParseException(e);
295 * Call the php parse command ( php -l -f <filename> )
296 * and create markers according to the external parser output
298 public static void phpExternalParse(final IFile file) {
299 final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
300 final String filename = file.getLocation().toString();
302 final String[] arguments = { filename };
303 final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
304 final String command = form.format(arguments);
306 final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
309 // parse the buffer to find the errors and warnings
310 createMarkers(parserResult, file);
311 } catch (CoreException e) {
312 PHPeclipsePlugin.log(e);
317 * Put a new html block in the stack.
319 public static final void createNewHTMLCode() {
320 final int currentPosition = SimpleCharStream.getPosition();
321 if (currentPosition == htmlStart || currentPosition > SimpleCharStream.currentBuffer.length()) {
324 final char[] chars = SimpleCharStream.currentBuffer.substring(htmlStart,currentPosition+1).toCharArray();
325 pushOnAstNodes(new HTMLCode(chars, htmlStart,currentPosition));
328 /** Create a new task. */
329 public static final void createNewTask() {
330 final int currentPosition = SimpleCharStream.getPosition();
331 final String todo = SimpleCharStream.currentBuffer.substring(currentPosition-3,
332 SimpleCharStream.currentBuffer.indexOf("\n",
334 PHPeclipsePlugin.log(1,SimpleCharStream.currentBuffer.toString());
336 setMarker(fileToParse,
338 SimpleCharStream.getBeginLine(),
340 "Line "+SimpleCharStream.getBeginLine());
341 } catch (CoreException e) {
342 PHPeclipsePlugin.log(e);
346 private static final void parse() throws ParseException {
351 PARSER_END(PHPParser)
355 // CommonTokenAction: use the begins/ends fields added to the Jack
356 // CharStream class to set corresponding fields in each Token (which was
357 // also extended with new fields). By default Jack doesn't supply absolute
358 // offsets, just line/column offsets
359 static void CommonTokenAction(Token t) {
360 t.sourceStart = input_stream.beginOffset;
361 t.sourceEnd = input_stream.endOffset;
362 } // CommonTokenAction
367 <PHPSTARTSHORT : "<?"> {PHPParser.createNewHTMLCode();} : PHPPARSING
368 | <PHPSTARTLONG : "<?php"> {PHPParser.createNewHTMLCode();} : PHPPARSING
369 | <PHPECHOSTART : "<?="> {PHPParser.createNewHTMLCode();} : PHPPARSING
372 <PHPPARSING, IN_SINGLE_LINE_COMMENT> TOKEN :
374 <PHPEND :"?>"> {PHPParser.htmlStart = SimpleCharStream.getPosition();} : DEFAULT
377 /* Skip any character if we are not in php mode */
395 <PHPPARSING> SPECIAL_TOKEN :
397 "//" : IN_SINGLE_LINE_COMMENT
398 | "#" : IN_SINGLE_LINE_COMMENT
399 | <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
400 | "/*" : IN_MULTI_LINE_COMMENT
403 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
405 <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
409 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT> SPECIAL_TOKEN :
411 "todo" {PHPParser.createNewTask();}
414 <IN_FORMAL_COMMENT> SPECIAL_TOKEN :
419 <IN_MULTI_LINE_COMMENT> SPECIAL_TOKEN :
424 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
434 | <FUNCTION : "function">
437 | <ELSEIF : "elseif">
444 /* LANGUAGE CONSTRUCT */
449 | <INCLUDE : "include">
450 | <REQUIRE : "require">
451 | <INCLUDE_ONCE : "include_once">
452 | <REQUIRE_ONCE : "require_once">
453 | <GLOBAL : "global">
454 | <DEFINE : "define">
455 | <STATIC : "static">
456 | <CLASSACCESS : "->">
457 | <STATICCLASSACCESS : "::">
458 | <ARRAYASSIGN : "=>">
461 /* RESERVED WORDS AND LITERALS */
467 | <CONTINUE : "continue">
468 | <_DEFAULT : "default">
470 | <EXTENDS : "extends">
475 | <RETURN : "return">
477 | <SWITCH : "switch">
482 | <ENDWHILE : "endwhile">
483 | <ENDSWITCH: "endswitch">
485 | <ENDFOR : "endfor">
486 | <FOREACH : "foreach">
494 | <OBJECT : "object">
496 | <BOOLEAN : "boolean">
498 | <DOUBLE : "double">
501 | <INTEGER : "integer">
521 | <MINUS_MINUS : "--">
531 | <RSIGNEDSHIFT : ">>">
532 | <RUNSIGNEDSHIFT : ">>>">
541 <DECIMAL_LITERAL> (["l","L"])?
542 | <HEX_LITERAL> (["l","L"])?
543 | <OCTAL_LITERAL> (["l","L"])?
546 <#DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
548 <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
550 <#OCTAL_LITERAL: "0" (["0"-"7"])* >
552 <FLOATING_POINT_LITERAL:
553 (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
554 | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
555 | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
556 | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
559 <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
561 <STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
562 | <STRING_1: "\"" ( ~["\"","\\"] | "\\" ~[] )* "\"">
563 | <STRING_2: "'" ( ~["'","\\"] | "\\" ~[] )* "'">
564 | <STRING_3: "`" ( ~["`","\\"] | "\\" ~[] )* "`">
571 <IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
574 ["a"-"z"] | ["A"-"Z"]
582 "_" | ["\u007f"-"\u00ff"]
607 | <EQUAL_EQUAL : "==">
612 | <BANGDOUBLEEQUAL : "!==">
613 | <TRIPLEEQUAL : "===">
620 | <PLUSASSIGN : "+=">
621 | <MINUSASSIGN : "-=">
622 | <STARASSIGN : "*=">
623 | <SLASHASSIGN : "/=">
629 | <TILDEEQUAL : "~=">
630 | <LSHIFTASSIGN : "<<=">
631 | <RSIGNEDSHIFTASSIGN : ">>=">
636 <DOLLAR_ID: <DOLLAR> <IDENTIFIER>>
651 {PHPParser.createNewHTMLCode();}
652 } catch (TokenMgrError e) {
653 PHPeclipsePlugin.log(e);
654 errorStart = SimpleCharStream.getPosition();
655 errorEnd = errorStart + 1;
656 errorMessage = e.getMessage();
658 throw generateParseException();
663 * A php block is a <?= expression [;]?>
664 * or <?php somephpcode ?>
665 * or <? somephpcode ?>
669 final int start = SimpleCharStream.getPosition();
670 final PHPEchoBlock phpEchoBlock;
673 phpEchoBlock = phpEchoBlock()
674 {pushOnAstNodes(phpEchoBlock);}
679 setMarker(fileToParse,
680 "You should use '<?php' instead of '<?' it will avoid some problems with XML",
682 SimpleCharStream.getPosition(),
684 "Line " + token.beginLine);
685 } catch (CoreException e) {
686 PHPeclipsePlugin.log(e);
692 } catch (ParseException e) {
693 errorMessage = "'?>' expected";
695 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
696 errorEnd = SimpleCharStream.getPosition() + 1;
697 processParseExceptionDebug(e);
701 PHPEchoBlock phpEchoBlock() :
703 final Expression expr;
704 final PHPEchoBlock echoBlock;
705 final Token token, token2;
708 token = <PHPECHOSTART> expr = Expression() [ <SEMICOLON> ] token2 = <PHPEND>
710 echoBlock = new PHPEchoBlock(expr,token.sourceStart,token.sourceEnd);
711 pushOnAstNodes(echoBlock);
721 ClassDeclaration ClassDeclaration() :
723 final ClassDeclaration classDeclaration;
724 Token className = null;
725 final Token superclassName, token;
726 String classNameImage = SYNTAX_ERROR_CHAR;
727 String superclassNameImage = null;
732 className = <IDENTIFIER>
733 {classNameImage = className.image;}
734 } catch (ParseException e) {
735 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
737 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
738 errorEnd = SimpleCharStream.getPosition() + 1;
739 processParseExceptionDebug(e);
744 superclassName = <IDENTIFIER>
745 {superclassNameImage = superclassName.image;}
746 } catch (ParseException e) {
747 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
749 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
750 errorEnd = SimpleCharStream.getPosition() + 1;
751 processParseExceptionDebug(e);
752 superclassNameImage = SYNTAX_ERROR_CHAR;
757 if (className == null) {
758 start = token.sourceStart;
759 end = token.sourceEnd;
761 start = className.sourceStart;
762 end = className.sourceEnd;
764 if (superclassNameImage == null) {
766 classDeclaration = new ClassDeclaration(currentSegment,
771 classDeclaration = new ClassDeclaration(currentSegment,
777 currentSegment.add(classDeclaration);
778 currentSegment = classDeclaration;
780 ClassBody(classDeclaration)
781 {currentSegment = (OutlineableWithChildren) currentSegment.getParent();
782 classDeclaration.sourceEnd = SimpleCharStream.getPosition();
783 pushOnAstNodes(classDeclaration);
784 return classDeclaration;}
787 void ClassBody(final ClassDeclaration classDeclaration) :
792 } catch (ParseException e) {
793 errorMessage = "unexpected token : '"+ e.currentToken.next.image + "'. '{' expected";
795 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
796 errorEnd = SimpleCharStream.getPosition() + 1;
797 processParseExceptionDebug(e);
799 ( ClassBodyDeclaration(classDeclaration) )*
802 } catch (ParseException e) {
803 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. 'var', 'function' or '}' expected";
805 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
806 errorEnd = SimpleCharStream.getPosition() + 1;
807 processParseExceptionDebug(e);
812 * A class can contain only methods and fields.
814 void ClassBodyDeclaration(final ClassDeclaration classDeclaration) :
816 final MethodDeclaration method;
817 final FieldDeclaration field;
820 method = MethodDeclaration() {method.analyzeCode();
821 classDeclaration.addMethod(method);}
822 | field = FieldDeclaration() {classDeclaration.addField(field);}
826 * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;.
827 * it is only used by ClassBodyDeclaration()
829 FieldDeclaration FieldDeclaration() :
831 VariableDeclaration variableDeclaration;
832 final VariableDeclaration[] list;
833 final ArrayList arrayList = new ArrayList();
834 final int pos = SimpleCharStream.getPosition();
839 token = <VAR> variableDeclaration = VariableDeclaratorNoSuffix()
840 {arrayList.add(variableDeclaration);
841 outlineInfo.addVariable(variableDeclaration.name());}
843 <COMMA> variableDeclaration = VariableDeclaratorNoSuffix()
844 {arrayList.add(variableDeclaration);
845 outlineInfo.addVariable(variableDeclaration.name());}
849 } catch (ParseException e) {
850 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected after variable declaration";
852 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
853 errorEnd = SimpleCharStream.getPosition() + 1;
854 processParseExceptionDebug(e);
857 {list = new VariableDeclaration[arrayList.size()];
858 arrayList.toArray(list);
860 if (token2 == null) {
861 end = list[list.length-1].sourceEnd;
863 end = token2.sourceEnd;
865 return new FieldDeclaration(list,
872 * a strict variable declarator : there cannot be a suffix here.
873 * It will be used by fields and formal parameters
875 VariableDeclaration VariableDeclaratorNoSuffix() :
878 Expression initializer = null;
881 varName = <DOLLAR_ID>
885 initializer = VariableInitializer()
886 } catch (ParseException e) {
887 errorMessage = "Literal expression expected in variable initializer";
889 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
890 errorEnd = SimpleCharStream.getPosition() + 1;
891 processParseExceptionDebug(e);
895 if (initializer == null) {
896 return new VariableDeclaration(currentSegment,
897 new Variable(varName.image.substring(1),
903 return new VariableDeclaration(currentSegment,
904 new Variable(varName.image.substring(1),
908 VariableDeclaration.EQUAL,
909 varName.sourceStart);
914 * this will be used by static statement
916 VariableDeclaration VariableDeclarator() :
918 final AbstractVariable variable;
919 Expression initializer = null;
922 variable = VariableDeclaratorId()
926 initializer = VariableInitializer()
927 } catch (ParseException e) {
928 errorMessage = "Literal expression expected in variable initializer";
930 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
931 errorEnd = SimpleCharStream.getPosition() + 1;
932 processParseExceptionDebug(e);
936 if (initializer == null) {
937 return new VariableDeclaration(currentSegment,
939 variable.sourceStart,
942 return new VariableDeclaration(currentSegment,
945 VariableDeclaration.EQUAL,
946 variable.sourceStart);
952 * @return the variable name (with suffix)
954 AbstractVariable VariableDeclaratorId() :
957 AbstractVariable expression = null;
958 final int pos = SimpleCharStream.getPosition();
965 expression = VariableSuffix(var)
968 if (expression == null) {
973 } catch (ParseException e) {
974 errorMessage = "'$' expected for variable identifier";
976 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
977 errorEnd = SimpleCharStream.getPosition() + 1;
983 * Return a variablename without the $.
984 * @return a variable name
988 final StringBuffer buff;
989 Expression expression = null;
996 [<LBRACE> expression = Expression() <RBRACE>]
998 if (expression == null) {
999 return new Variable(token.image.substring(1),
1003 String s = expression.toStringExpression();
1004 buff = new StringBuffer(token.image.length()+s.length()+2);
1005 buff.append(token.image);
1009 s = buff.toString();
1010 return new Variable(s,token.sourceStart,token.sourceEnd);
1014 expr = VariableName()
1015 {return new Variable(expr,token.sourceStart,expr.sourceEnd);}
1018 Variable Variable() :
1020 Variable variable = null;
1024 token = <DOLLAR_ID> [variable = Var(token)]
1026 if (variable == null) {
1027 return new Variable(token.image.substring(1),token.sourceStart,token.sourceEnd);
1029 final StringBuffer buff = new StringBuffer();
1030 buff.append(token.image.substring(1));
1031 buff.append(variable.toStringExpression());
1032 return new Variable(buff.toString(),token.sourceStart,variable.sourceEnd);
1035 token = <DOLLAR> variable = Var(token)
1037 return new Variable(variable,token.sourceStart,variable.sourceEnd);
1041 Variable Var(final Token dollar) :
1043 Variable variable = null;
1045 ConstantIdentifier constant;
1048 token = <DOLLAR_ID> [variable = Var(token)]
1049 {if (variable == null) {
1050 return new Variable(token.image.substring(1),token.sourceStart,token.sourceEnd);
1052 final StringBuffer buff = new StringBuffer();
1053 buff.append(token.image.substring(1));
1054 buff.append(variable.toStringExpression());
1055 return new Variable(buff.toString(),dollar.sourceStart,variable.sourceEnd);
1058 LOOKAHEAD(<DOLLAR> <DOLLAR>)
1059 token = <DOLLAR> variable = Var(token)
1060 {return new Variable(variable,dollar.sourceStart,variable.sourceEnd);}
1062 constant = VariableName()
1063 {return new Variable(constant.name,dollar.sourceStart,constant.sourceEnd);}
1067 * A Variable name (without the $)
1068 * @return a variable name String
1070 ConstantIdentifier VariableName():
1072 final StringBuffer buff;
1075 Expression expression = null;
1077 Token token2 = null;
1081 token = <LBRACE> expression = Expression() token2 = <RBRACE>
1082 {expr = expression.toStringExpression();
1083 buff = new StringBuffer(expr.length()+2);
1087 pos = SimpleCharStream.getPosition();
1088 expr = buff.toString();
1089 return new ConstantIdentifier(expr,
1095 token = <IDENTIFIER>
1096 [<LBRACE> expression = Expression() token2 = <RBRACE>]
1098 if (expression == null) {
1099 return new ConstantIdentifier(token.image,
1103 expr = expression.toStringExpression();
1104 buff = new StringBuffer(token.image.length()+expr.length()+2);
1105 buff.append(token.image);
1109 expr = buff.toString();
1110 return new ConstantIdentifier(expr,
1116 var = VariableName()
1118 return new Variable(var,
1125 return new Variable(token.image,
1131 Expression VariableInitializer() :
1133 final Expression expr;
1134 final Token token, token2;
1140 token2 = <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1141 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1143 token2.sourceStart);}
1145 token2 = <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1146 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1148 token2.sourceStart);}
1150 expr = ArrayDeclarator()
1153 token = <IDENTIFIER>
1154 {return new ConstantIdentifier(token);}
1157 ArrayVariableDeclaration ArrayVariable() :
1159 final Expression expr,expr2;
1164 <ARRAYASSIGN> expr2 = Expression()
1165 {return new ArrayVariableDeclaration(expr,expr2);}
1167 {return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());}
1170 ArrayVariableDeclaration[] ArrayInitializer() :
1172 ArrayVariableDeclaration expr;
1173 final ArrayList list = new ArrayList();
1178 expr = ArrayVariable()
1180 ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
1185 <COMMA> {list.add(null);}
1189 final ArrayVariableDeclaration[] vars = new ArrayVariableDeclaration[list.size()];
1195 * A Method Declaration.
1196 * <b>function</b> MetodDeclarator() Block()
1198 MethodDeclaration MethodDeclaration() :
1200 final MethodDeclaration functionDeclaration;
1202 final OutlineableWithChildren seg = currentSegment;
1208 functionDeclaration = MethodDeclarator(token.sourceStart)
1209 {outlineInfo.addVariable(new String(functionDeclaration.name));}
1210 } catch (ParseException e) {
1211 if (errorMessage != null) throw e;
1212 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1214 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1215 errorEnd = SimpleCharStream.getPosition() + 1;
1218 {currentSegment = functionDeclaration;}
1220 {functionDeclaration.statements = block.statements;
1221 currentSegment = seg;
1222 return functionDeclaration;}
1226 * A MethodDeclarator.
1227 * [&] IDENTIFIER(parameters ...).
1228 * @return a function description for the outline
1230 MethodDeclaration MethodDeclarator(final int start) :
1232 Token identifier = null;
1233 Token reference = null;
1234 final Hashtable formalParameters = new Hashtable();
1235 String identifierChar = SYNTAX_ERROR_CHAR;
1239 [reference = <BIT_AND>]
1241 identifier = <IDENTIFIER>
1242 {identifierChar = identifier.image;}
1243 } catch (ParseException e) {
1244 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1246 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1247 errorEnd = SimpleCharStream.getPosition() + 1;
1248 processParseExceptionDebug(e);
1250 end = FormalParameters(formalParameters)
1252 int nameStart, nameEnd;
1253 if (identifier == null) {
1254 if (reference == null) {
1255 nameStart = start + 9;
1256 nameEnd = start + 10;
1258 nameStart = reference.sourceEnd + 1;
1259 nameEnd = reference.sourceEnd + 2;
1262 nameStart = identifier.sourceStart;
1263 nameEnd = identifier.sourceEnd;
1265 return new MethodDeclaration(currentSegment,
1277 * FormalParameters follows method identifier.
1278 * (FormalParameter())
1280 int FormalParameters(final Hashtable parameters) :
1282 VariableDeclaration var;
1289 } catch (ParseException e) {
1290 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected after function identifier";
1292 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1293 errorEnd = SimpleCharStream.getPosition() + 1;
1294 processParseExceptionDebug(e);
1297 var = FormalParameter()
1298 {parameters.put(new String(var.name()),var);}
1300 <COMMA> var = FormalParameter()
1301 {parameters.put(new String(var.name()),var);}
1306 {end = token.sourceEnd;}
1307 } catch (ParseException e) {
1308 errorMessage = "')' expected";
1310 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1311 errorEnd = SimpleCharStream.getPosition() + 1;
1312 processParseExceptionDebug(e);
1313 end = e.currentToken.sourceStart;
1319 * A formal parameter.
1320 * $varname[=value] (,$varname[=value])
1322 VariableDeclaration FormalParameter() :
1324 final VariableDeclaration variableDeclaration;
1328 [token = <BIT_AND>] variableDeclaration = VariableDeclaratorNoSuffix()
1330 if (token != null) {
1331 variableDeclaration.setReference(true);
1333 return variableDeclaration;}
1336 ConstantIdentifier Type() :
1337 {final Token token;}
1339 token = <STRING> {return new ConstantIdentifier(token);}
1340 | token = <BOOL> {return new ConstantIdentifier(token);}
1341 | token = <BOOLEAN> {return new ConstantIdentifier(token);}
1342 | token = <REAL> {return new ConstantIdentifier(token);}
1343 | token = <DOUBLE> {return new ConstantIdentifier(token);}
1344 | token = <FLOAT> {return new ConstantIdentifier(token);}
1345 | token = <INT> {return new ConstantIdentifier(token);}
1346 | token = <INTEGER> {return new ConstantIdentifier(token);}
1347 | token = <OBJECT> {return new ConstantIdentifier(token);}
1350 Expression Expression() :
1352 final Expression expr;
1353 Expression initializer = null;
1354 int assignOperator = -1;
1358 expr = ConditionalExpression()
1360 assignOperator = AssignmentOperator()
1362 initializer = Expression()
1363 } catch (ParseException e) {
1364 if (errorMessage != null) {
1367 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1369 errorEnd = SimpleCharStream.getPosition();
1374 if (assignOperator != -1) {// todo : change this, very very bad :(
1375 if (expr instanceof AbstractVariable) {
1376 return new VariableDeclaration(currentSegment,
1377 (AbstractVariable) expr,
1380 initializer.sourceEnd);
1382 String varName = expr.toStringExpression().substring(1);
1383 return new VariableDeclaration(currentSegment,
1384 new Variable(varName,
1388 initializer.sourceEnd);
1392 | expr = ExpressionWBang() {return expr;}
1395 Expression ExpressionWBang() :
1397 final Expression expr;
1401 token = <BANG> expr = ExpressionWBang()
1402 {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,token.sourceStart);}
1403 | expr = ExpressionNoBang() {return expr;}
1406 Expression ExpressionNoBang() :
1411 expr = ListExpression() {return expr;}
1413 expr = PrintExpression() {return expr;}
1417 * Any assignement operator.
1418 * @return the assignement operator id
1420 int AssignmentOperator() :
1423 <ASSIGN> {return VariableDeclaration.EQUAL;}
1424 | <STARASSIGN> {return VariableDeclaration.STAR_EQUAL;}
1425 | <SLASHASSIGN> {return VariableDeclaration.SLASH_EQUAL;}
1426 | <REMASSIGN> {return VariableDeclaration.REM_EQUAL;}
1427 | <PLUSASSIGN> {return VariableDeclaration.PLUS_EQUAL;}
1428 | <MINUSASSIGN> {return VariableDeclaration.MINUS_EQUAL;}
1429 | <LSHIFTASSIGN> {return VariableDeclaration.LSHIFT_EQUAL;}
1430 | <RSIGNEDSHIFTASSIGN> {return VariableDeclaration.RSIGNEDSHIFT_EQUAL;}
1431 | <ANDASSIGN> {return VariableDeclaration.AND_EQUAL;}
1432 | <XORASSIGN> {return VariableDeclaration.XOR_EQUAL;}
1433 | <ORASSIGN> {return VariableDeclaration.OR_EQUAL;}
1434 | <DOTASSIGN> {return VariableDeclaration.DOT_EQUAL;}
1435 | <TILDEEQUAL> {return VariableDeclaration.TILDE_EQUAL;}
1438 Expression ConditionalExpression() :
1440 final Expression expr;
1441 Expression expr2 = null;
1442 Expression expr3 = null;
1445 expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
1447 if (expr3 == null) {
1450 return new ConditionalExpression(expr,expr2,expr3);
1454 Expression ConditionalOrExpression() :
1456 Expression expr,expr2;
1460 expr = ConditionalAndExpression()
1463 <OR_OR> {operator = OperatorIds.OR_OR;}
1464 | <_ORL> {operator = OperatorIds.ORL;}
1466 expr2 = ConditionalAndExpression()
1468 expr = new BinaryExpression(expr,expr2,operator);
1474 Expression ConditionalAndExpression() :
1476 Expression expr,expr2;
1480 expr = ConcatExpression()
1482 ( <AND_AND> {operator = OperatorIds.AND_AND;}
1483 | <_ANDL> {operator = OperatorIds.ANDL;})
1484 expr2 = ConcatExpression() {expr = new BinaryExpression(expr,expr2,operator);}
1489 Expression ConcatExpression() :
1491 Expression expr,expr2;
1494 expr = InclusiveOrExpression()
1496 <DOT> expr2 = InclusiveOrExpression()
1497 {expr = new BinaryExpression(expr,expr2,OperatorIds.DOT);}
1502 Expression InclusiveOrExpression() :
1504 Expression expr,expr2;
1507 expr = ExclusiveOrExpression()
1508 (<BIT_OR> expr2 = ExclusiveOrExpression()
1509 {expr = new BinaryExpression(expr,expr2,OperatorIds.OR);}
1514 Expression ExclusiveOrExpression() :
1516 Expression expr,expr2;
1519 expr = AndExpression()
1521 <XOR> expr2 = AndExpression()
1522 {expr = new BinaryExpression(expr,expr2,OperatorIds.XOR);}
1527 Expression AndExpression() :
1529 Expression expr,expr2;
1532 expr = EqualityExpression()
1535 <BIT_AND> expr2 = EqualityExpression()
1536 {expr = new BinaryExpression(expr,expr2,OperatorIds.AND);}
1541 Expression EqualityExpression() :
1543 Expression expr,expr2;
1547 expr = RelationalExpression()
1549 ( <EQUAL_EQUAL> {operator = OperatorIds.EQUAL_EQUAL;}
1550 | <DIF> {operator = OperatorIds.DIF;}
1551 | <NOT_EQUAL> {operator = OperatorIds.DIF;}
1552 | <BANGDOUBLEEQUAL> {operator = OperatorIds.BANG_EQUAL_EQUAL;}
1553 | <TRIPLEEQUAL> {operator = OperatorIds.EQUAL_EQUAL_EQUAL;}
1556 expr2 = RelationalExpression()
1557 } catch (ParseException e) {
1558 if (errorMessage != null) {
1561 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1563 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1564 errorEnd = SimpleCharStream.getPosition() + 1;
1568 expr = new BinaryExpression(expr,expr2,operator);
1574 Expression RelationalExpression() :
1576 Expression expr,expr2;
1580 expr = ShiftExpression()
1582 ( <LT> {operator = OperatorIds.LESS;}
1583 | <GT> {operator = OperatorIds.GREATER;}
1584 | <LE> {operator = OperatorIds.LESS_EQUAL;}
1585 | <GE> {operator = OperatorIds.GREATER_EQUAL;})
1586 expr2 = ShiftExpression()
1587 {expr = new BinaryExpression(expr,expr2,operator);}
1592 Expression ShiftExpression() :
1594 Expression expr,expr2;
1598 expr = AdditiveExpression()
1600 ( <LSHIFT> {operator = OperatorIds.LEFT_SHIFT;}
1601 | <RSIGNEDSHIFT> {operator = OperatorIds.RIGHT_SHIFT;}
1602 | <RUNSIGNEDSHIFT> {operator = OperatorIds.UNSIGNED_RIGHT_SHIFT;})
1603 expr2 = AdditiveExpression()
1604 {expr = new BinaryExpression(expr,expr2,operator);}
1609 Expression AdditiveExpression() :
1611 Expression expr,expr2;
1615 expr = MultiplicativeExpression()
1618 ( <PLUS> {operator = OperatorIds.PLUS;}
1619 | <MINUS> {operator = OperatorIds.MINUS;}
1621 expr2 = MultiplicativeExpression()
1622 {expr = new BinaryExpression(expr,expr2,operator);}
1627 Expression MultiplicativeExpression() :
1629 Expression expr,expr2;
1634 expr = UnaryExpression()
1635 } catch (ParseException e) {
1636 if (errorMessage != null) throw e;
1637 errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
1639 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1640 errorEnd = SimpleCharStream.getPosition() + 1;
1644 ( <STAR> {operator = OperatorIds.MULTIPLY;}
1645 | <SLASH> {operator = OperatorIds.DIVIDE;}
1646 | <REMAINDER> {operator = OperatorIds.REMAINDER;})
1647 expr2 = UnaryExpression()
1648 {expr = new BinaryExpression(expr,expr2,operator);}
1654 * An unary expression starting with @, & or nothing
1656 Expression UnaryExpression() :
1658 final Expression expr;
1661 /* <BIT_AND> expr = UnaryExpressionNoPrefix() //why did I had that ?
1662 {return new PrefixedUnaryExpression(expr,OperatorIds.AND,pos);}
1664 expr = AtNotUnaryExpression() {return expr;}
1668 * An expression prefixed (or not) by one or more @ and !.
1669 * @return the expression
1671 Expression AtNotUnaryExpression() :
1673 final Expression expr;
1678 expr = AtNotUnaryExpression()
1679 {return new PrefixedUnaryExpression(expr,OperatorIds.AT,token.sourceStart);}
1682 expr = AtNotUnaryExpression()
1683 {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,token.sourceStart);}
1685 expr = UnaryExpressionNoPrefix()
1690 Expression UnaryExpressionNoPrefix() :
1692 final Expression expr;
1696 token = <PLUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,
1698 token.sourceStart);}
1700 token = <MINUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,
1702 token.sourceStart);}
1704 expr = PreIncDecExpression()
1707 expr = UnaryExpressionNotPlusMinus()
1712 Expression PreIncDecExpression() :
1714 final Expression expr;
1720 token = <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1722 token = <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1724 expr = PrimaryExpression()
1725 {return new PrefixedUnaryExpression(expr,operator,token.sourceStart);}
1728 Expression UnaryExpressionNotPlusMinus() :
1730 final Expression expr;
1733 LOOKAHEAD( <LPAREN> (Type() | <ARRAY>) <RPAREN> )
1734 expr = CastExpression() {return expr;}
1735 | expr = PostfixExpression() {return expr;}
1736 | expr = Literal() {return expr;}
1737 | <LPAREN> expr = Expression()
1740 } catch (ParseException e) {
1741 errorMessage = "')' expected";
1743 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1744 errorEnd = SimpleCharStream.getPosition() + 1;
1750 CastExpression CastExpression() :
1752 final ConstantIdentifier type;
1753 final Expression expr;
1754 final Token token,token1;
1761 token = <ARRAY> {type = new ConstantIdentifier(token);}
1763 <RPAREN> expr = UnaryExpression()
1764 {return new CastExpression(type,expr,token1.sourceStart,expr.sourceEnd);}
1767 Expression PostfixExpression() :
1769 final Expression expr;
1774 expr = PrimaryExpression()
1776 token = <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1778 token = <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1781 if (operator == -1) {
1784 return new PostfixedUnaryExpression(expr,operator,token.sourceEnd);
1788 Expression PrimaryExpression() :
1790 Expression expr = null;
1794 [token = <BIT_AND>] expr = refPrimaryExpression(token)
1797 expr = ArrayDeclarator()
1801 Expression refPrimaryExpression(final Token reference) :
1803 Expression expr = null;
1804 Expression expr2 = null;
1805 int assignOperator = -1;
1806 final Token identifier;
1810 identifier = <IDENTIFIER>
1812 expr = new ConstantIdentifier(identifier);
1815 <STATICCLASSACCESS> expr2 = ClassIdentifier()
1816 {expr = new ClassAccess(expr,
1818 ClassAccess.STATIC);}
1820 [ expr2 = Arguments(expr) ]
1822 if (expr2 == null) {
1823 if (reference != null) {
1824 ParseException e = generateParseException();
1825 errorMessage = "you cannot use a constant by reference";
1827 errorStart = reference.sourceStart;
1828 errorEnd = reference.sourceEnd;
1829 processParseExceptionDebug(e);
1836 expr = VariableDeclaratorId() //todo use the reference parameter ...
1837 [ expr = Arguments(expr) ]
1841 expr = ClassIdentifier()
1844 if (reference == null) {
1845 start = token.sourceStart;
1847 start = reference.sourceStart;
1849 expr = new ClassInstantiation(expr,
1853 [ expr = Arguments(expr) ]
1858 * An array declarator.
1862 ArrayInitializer ArrayDeclarator() :
1864 final ArrayVariableDeclaration[] vars;
1868 token = <ARRAY> vars = ArrayInitializer()
1869 {return new ArrayInitializer(vars,token.sourceStart,SimpleCharStream.getPosition());}
1872 Expression ClassIdentifier():
1874 final Expression expr;
1876 final ConstantIdentifier type;
1879 token = <IDENTIFIER> {return new ConstantIdentifier(token);}
1880 | expr = Type() {return expr;}
1881 | expr = VariableDeclaratorId() {return expr;}
1885 * Used by Variabledeclaratorid and primarysuffix
1887 AbstractVariable VariableSuffix(final AbstractVariable prefix) :
1889 Variable expr = null;
1890 final int pos = SimpleCharStream.getPosition();
1891 Expression expression = null;
1896 expression = VariableName()
1897 } catch (ParseException e) {
1898 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
1900 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1901 errorEnd = SimpleCharStream.getPosition() + 1;
1904 {return new ClassAccess(prefix,
1906 ClassAccess.NORMAL);}
1908 <LBRACKET> [ expression = Expression() | expression = Type() ] //Not good
1911 } catch (ParseException e) {
1912 errorMessage = "']' expected";
1914 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1915 errorEnd = SimpleCharStream.getPosition() + 1;
1918 {return new ArrayDeclarator(prefix,expression,SimpleCharStream.getPosition());}
1926 token = <INTEGER_LITERAL> {return new NumberLiteral(token);}
1927 | token = <FLOATING_POINT_LITERAL> {return new NumberLiteral(token);}
1928 | token = <STRING_LITERAL> {return new StringLiteral(token);}
1929 | token = <TRUE> {return new TrueLiteral(token);}
1930 | token = <FALSE> {return new FalseLiteral(token);}
1931 | token = <NULL> {return new NullLiteral(token);}
1934 FunctionCall Arguments(final Expression func) :
1936 Expression[] args = null;
1940 <LPAREN> [ args = ArgumentList() ]
1943 } catch (ParseException e) {
1944 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
1946 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1947 errorEnd = SimpleCharStream.getPosition() + 1;
1950 {return new FunctionCall(func,args,token.sourceEnd);}
1954 * An argument list is a list of arguments separated by comma :
1955 * argumentDeclaration() (, argumentDeclaration)*
1956 * @return an array of arguments
1958 Expression[] ArgumentList() :
1961 final ArrayList list = new ArrayList();
1970 } catch (ParseException e) {
1971 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. An expression expected after a comma in argument list";
1973 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1974 errorEnd = SimpleCharStream.getPosition() + 1;
1979 final Expression[] arguments = new Expression[list.size()];
1980 list.toArray(arguments);
1985 * A Statement without break.
1986 * @return a statement
1988 Statement StatementNoBreak() :
1990 final Statement statement;
1995 statement = expressionStatement() {return statement;}
1997 statement = LabeledStatement() {return statement;}
1998 | statement = Block() {return statement;}
1999 | statement = EmptyStatement() {return statement;}
2000 | statement = SwitchStatement() {return statement;}
2001 | statement = IfStatement() {return statement;}
2002 | statement = WhileStatement() {return statement;}
2003 | statement = DoStatement() {return statement;}
2004 | statement = ForStatement() {return statement;}
2005 | statement = ForeachStatement() {return statement;}
2006 | statement = ContinueStatement() {return statement;}
2007 | statement = ReturnStatement() {return statement;}
2008 | statement = EchoStatement() {return statement;}
2009 | [token=<AT>] statement = IncludeStatement()
2010 {if (token != null) {
2011 ((InclusionStatement)statement).silent = true;
2012 statement.sourceStart = token.sourceStart;
2015 | statement = StaticStatement() {return statement;}
2016 | statement = GlobalStatement() {return statement;}
2017 | statement = defineStatement() {currentSegment.add((Outlineable)statement);return statement;}
2021 * A statement expression.
2023 * @return an expression
2025 Statement expressionStatement() :
2027 final Statement statement;
2031 statement = Expression()
2034 {statement.sourceEnd = token.sourceEnd;}
2035 } catch (ParseException e) {
2036 if (e.currentToken.next.kind != PHPParserConstants.PHPEND) {
2037 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2039 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2040 errorEnd = SimpleCharStream.getPosition() + 1;
2047 Define defineStatement() :
2049 final int start = SimpleCharStream.getPosition();
2050 Expression defineName,defineValue;
2056 } catch (ParseException e) {
2057 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
2059 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2060 errorEnd = SimpleCharStream.getPosition() + 1;
2061 processParseExceptionDebug(e);
2064 defineName = Expression()
2065 } catch (ParseException e) {
2066 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
2068 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2069 errorEnd = SimpleCharStream.getPosition() + 1;
2074 } catch (ParseException e) {
2075 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
2077 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2078 errorEnd = SimpleCharStream.getPosition() + 1;
2079 processParseExceptionDebug(e);
2082 defineValue = Expression()
2083 } catch (ParseException e) {
2084 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
2086 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2087 errorEnd = SimpleCharStream.getPosition() + 1;
2092 } catch (ParseException e) {
2093 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2095 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2096 errorEnd = SimpleCharStream.getPosition() + 1;
2097 processParseExceptionDebug(e);
2099 {return new Define(currentSegment,
2103 SimpleCharStream.getPosition());}
2107 * A Normal statement.
2109 Statement Statement() :
2111 final Statement statement;
2114 statement = StatementNoBreak() {return statement;}
2115 | statement = BreakStatement() {return statement;}
2119 * An html block inside a php syntax.
2121 HTMLBlock htmlBlock() :
2123 final int startIndex = nodePtr;
2124 final AstNode[] blockNodes;
2128 <PHPEND> (phpEchoBlock())*
2130 (<PHPSTARTLONG> | <PHPSTARTSHORT>)
2131 } catch (ParseException e) {
2132 errorMessage = "unexpected end of file , '<?php' expected";
2134 errorStart = SimpleCharStream.getPosition();
2135 errorEnd = SimpleCharStream.getPosition();
2139 nbNodes = nodePtr - startIndex;
2140 blockNodes = new AstNode[nbNodes];
2141 System.arraycopy(nodes,startIndex,blockNodes,0,nbNodes);
2142 nodePtr = startIndex;
2143 return new HTMLBlock(blockNodes);}
2147 * An include statement. It's "include" an expression;
2149 InclusionStatement IncludeStatement() :
2151 final Expression expr;
2153 final InclusionStatement inclusionStatement;
2154 final Token token, token2;
2157 ( token = <REQUIRE> {keyword = InclusionStatement.REQUIRE;}
2158 | token = <REQUIRE_ONCE> {keyword = InclusionStatement.REQUIRE_ONCE;}
2159 | token = <INCLUDE> {keyword = InclusionStatement.INCLUDE;}
2160 | token = <INCLUDE_ONCE> {keyword = InclusionStatement.INCLUDE_ONCE;})
2163 } catch (ParseException e) {
2164 if (errorMessage != null) {
2167 errorMessage = "unexpected token '"+ e.currentToken.next.image+"', expression expected";
2169 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2170 errorEnd = SimpleCharStream.getPosition() + 1;
2173 {inclusionStatement = new InclusionStatement(currentSegment,
2177 currentSegment.add(inclusionStatement);
2180 token2 = <SEMICOLON>
2181 } catch (ParseException e) {
2182 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2184 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2185 errorEnd = SimpleCharStream.getPosition() + 1;
2188 {inclusionStatement.sourceEnd = token2.sourceEnd;
2189 return inclusionStatement;}
2192 PrintExpression PrintExpression() :
2194 final Expression expr;
2195 final int pos = SimpleCharStream.getPosition();
2198 <PRINT> expr = Expression() {return new PrintExpression(expr,pos,SimpleCharStream.getPosition());}
2201 ListExpression ListExpression() :
2203 Expression expr = null;
2204 final Expression expression;
2205 final ArrayList list = new ArrayList();
2206 final int pos = SimpleCharStream.getPosition();
2212 } catch (ParseException e) {
2213 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
2215 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2216 errorEnd = SimpleCharStream.getPosition() + 1;
2220 expr = VariableDeclaratorId()
2223 {if (expr == null) list.add(null);}
2227 } catch (ParseException e) {
2228 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
2230 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2231 errorEnd = SimpleCharStream.getPosition() + 1;
2234 [expr = VariableDeclaratorId() {list.add(expr);}]
2238 } catch (ParseException e) {
2239 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2241 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2242 errorEnd = SimpleCharStream.getPosition() + 1;
2245 [ <ASSIGN> expression = Expression()
2247 final Variable[] vars = new Variable[list.size()];
2249 return new ListExpression(vars,
2252 SimpleCharStream.getPosition());}
2255 final Variable[] vars = new Variable[list.size()];
2257 return new ListExpression(vars,pos,SimpleCharStream.getPosition());}
2261 * An echo statement.
2262 * echo anyexpression (, otherexpression)*
2264 EchoStatement EchoStatement() :
2266 final ArrayList expressions = new ArrayList();
2269 Token token2 = null;
2272 token = <ECHO> expr = Expression()
2273 {expressions.add(expr);}
2275 <COMMA> expr = Expression()
2276 {expressions.add(expr);}
2279 token2 = <SEMICOLON>
2280 } catch (ParseException e) {
2281 if (e.currentToken.next.kind != 4) {
2282 errorMessage = "';' expected after 'echo' statement";
2284 errorStart = e.currentToken.sourceEnd;
2285 errorEnd = e.currentToken.sourceEnd;
2286 processParseExceptionDebug(e);
2290 final Expression[] exprs = new Expression[expressions.size()];
2291 expressions.toArray(exprs);
2292 if (token2 == null) {
2293 return new EchoStatement(exprs,token.sourceStart, exprs[exprs.length-1].sourceEnd);
2295 return new EchoStatement(exprs,token.sourceStart, token2.sourceEnd);
2299 GlobalStatement GlobalStatement() :
2302 final ArrayList vars = new ArrayList();
2303 final GlobalStatement global;
2304 final Token token, token2;
2315 token2 = <SEMICOLON>
2317 final Variable[] variables = new Variable[vars.size()];
2318 vars.toArray(variables);
2319 global = new GlobalStatement(currentSegment,
2323 currentSegment.add(global);
2325 } catch (ParseException e) {
2326 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2328 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2329 errorEnd = SimpleCharStream.getPosition() + 1;
2334 StaticStatement StaticStatement() :
2336 final ArrayList vars = new ArrayList();
2337 VariableDeclaration expr;
2338 final Token token, token2;
2341 token = <STATIC> expr = VariableDeclarator() {vars.add(expr);}
2343 <COMMA> expr = VariableDeclarator() {vars.add(expr);}
2346 token2 = <SEMICOLON>
2348 final VariableDeclaration[] variables = new VariableDeclaration[vars.size()];
2349 vars.toArray(variables);
2350 return new StaticStatement(variables,
2353 } catch (ParseException e) {
2354 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2356 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2357 errorEnd = SimpleCharStream.getPosition() + 1;
2362 LabeledStatement LabeledStatement() :
2365 final Statement statement;
2368 label = <IDENTIFIER> <COLON> statement = Statement()
2369 {return new LabeledStatement(label.image,statement,label.sourceStart,statement.sourceEnd);}
2381 final ArrayList list = new ArrayList();
2382 Statement statement;
2383 final Token token, token2;
2388 } catch (ParseException e) {
2389 errorMessage = "'{' expected";
2391 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2392 errorEnd = SimpleCharStream.getPosition() + 1;
2395 ( statement = BlockStatement() {list.add(statement);}
2396 | statement = htmlBlock() {list.add(statement);})*
2399 } catch (ParseException e) {
2400 errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
2402 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2403 errorEnd = SimpleCharStream.getPosition() + 1;
2407 final Statement[] statements = new Statement[list.size()];
2408 list.toArray(statements);
2409 return new Block(statements,token.sourceStart,token2.sourceEnd);}
2412 Statement BlockStatement() :
2414 final Statement statement;
2418 statement = Statement() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2420 } catch (ParseException e) {
2421 errorMessage = "unexpected token : '"+ e.currentToken.image +"', a statement was expected";
2423 errorStart = e.currentToken.sourceStart;
2424 errorEnd = e.currentToken.sourceEnd;
2427 | statement = ClassDeclaration() {return statement;}
2428 | statement = MethodDeclaration() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2429 currentSegment.add((MethodDeclaration) statement);
2430 ((MethodDeclaration) statement).analyzeCode();
2435 * A Block statement that will not contain any 'break'
2437 Statement BlockStatementNoBreak() :
2439 final Statement statement;
2442 statement = StatementNoBreak() {return statement;}
2443 | statement = ClassDeclaration() {return statement;}
2444 | statement = MethodDeclaration() {currentSegment.add((MethodDeclaration) statement);
2445 ((MethodDeclaration) statement).analyzeCode();
2450 * used only by ForInit()
2452 VariableDeclaration[] LocalVariableDeclaration() :
2454 final ArrayList list = new ArrayList();
2455 VariableDeclaration var;
2458 var = LocalVariableDeclarator()
2460 ( <COMMA> var = LocalVariableDeclarator() {list.add(var);})*
2462 final VariableDeclaration[] vars = new VariableDeclaration[list.size()];
2468 * used only by LocalVariableDeclaration().
2470 VariableDeclaration LocalVariableDeclarator() :
2472 final Variable varName;
2473 Expression initializer = null;
2476 varName = Variable() [ <ASSIGN> initializer = Expression() ]
2478 if (initializer == null) {
2479 return new VariableDeclaration(currentSegment,
2481 varName.sourceStart,
2484 return new VariableDeclaration(currentSegment,
2487 VariableDeclaration.EQUAL,
2488 varName.sourceStart);
2492 EmptyStatement EmptyStatement() :
2498 {return new EmptyStatement(token.sourceStart,token.sourceEnd);}
2502 * used only by StatementExpressionList() which is used only by ForInit() and ForStatement()
2504 Expression StatementExpression() :
2506 final Expression expr,expr2;
2510 expr = PreIncDecExpression() {return expr;}
2512 expr = PrimaryExpression()
2513 [ <PLUS_PLUS> {return new PostfixedUnaryExpression(expr,
2514 OperatorIds.PLUS_PLUS,
2515 SimpleCharStream.getPosition());}
2516 | <MINUS_MINUS> {return new PostfixedUnaryExpression(expr,
2517 OperatorIds.MINUS_MINUS,
2518 SimpleCharStream.getPosition());}
2523 SwitchStatement SwitchStatement() :
2525 final Expression variable;
2526 final AbstractCase[] cases;
2527 final int pos = SimpleCharStream.getPosition();
2533 } catch (ParseException e) {
2534 errorMessage = "'(' expected after 'switch'";
2536 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2537 errorEnd = SimpleCharStream.getPosition() + 1;
2541 variable = Expression()
2542 } catch (ParseException e) {
2543 if (errorMessage != null) {
2546 errorMessage = "expression expected";
2548 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2549 errorEnd = SimpleCharStream.getPosition() + 1;
2554 } catch (ParseException e) {
2555 errorMessage = "')' expected";
2557 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2558 errorEnd = SimpleCharStream.getPosition() + 1;
2561 (cases = switchStatementBrace() | cases = switchStatementColon(pos, pos + 6))
2562 {return new SwitchStatement(variable,cases,pos,SimpleCharStream.getPosition());}
2565 AbstractCase[] switchStatementBrace() :
2568 final ArrayList cases = new ArrayList();
2572 ( cas = switchLabel0() {cases.add(cas);})*
2576 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2577 cases.toArray(abcase);
2579 } catch (ParseException e) {
2580 errorMessage = "'}' expected";
2582 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2583 errorEnd = SimpleCharStream.getPosition() + 1;
2588 * A Switch statement with : ... endswitch;
2589 * @param start the begin offset of the switch
2590 * @param end the end offset of the switch
2592 AbstractCase[] switchStatementColon(final int start, final int end) :
2595 final ArrayList cases = new ArrayList();
2600 setMarker(fileToParse,
2601 "Ugly syntax detected, you should switch () {...} instead of switch (): ... enswitch;",
2605 "Line " + token.beginLine);
2606 } catch (CoreException e) {
2607 PHPeclipsePlugin.log(e);
2609 ( cas = switchLabel0() {cases.add(cas);})*
2612 } catch (ParseException e) {
2613 errorMessage = "'endswitch' expected";
2615 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2616 errorEnd = SimpleCharStream.getPosition() + 1;
2622 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2623 cases.toArray(abcase);
2625 } catch (ParseException e) {
2626 errorMessage = "';' expected after 'endswitch' keyword";
2628 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2629 errorEnd = SimpleCharStream.getPosition() + 1;
2634 AbstractCase switchLabel0() :
2636 final Expression expr;
2637 Statement statement;
2638 final ArrayList stmts = new ArrayList();
2639 final int pos = SimpleCharStream.getPosition();
2642 expr = SwitchLabel()
2643 ( statement = BlockStatementNoBreak() {stmts.add(statement);}
2644 | statement = htmlBlock() {stmts.add(statement);})*
2645 [ statement = BreakStatement() {stmts.add(statement);}]
2647 final Statement[] stmtsArray = new Statement[stmts.size()];
2648 stmts.toArray(stmtsArray);
2649 if (expr == null) {//it's a default
2650 return new DefaultCase(stmtsArray,pos,SimpleCharStream.getPosition());
2652 return new Case(expr,stmtsArray,pos,SimpleCharStream.getPosition());}
2657 * case Expression() :
2659 * @return the if it was a case and null if not
2661 Expression SwitchLabel() :
2663 final Expression expr;
2669 } catch (ParseException e) {
2670 if (errorMessage != null) throw e;
2671 errorMessage = "expression expected after 'case' keyword";
2673 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2674 errorEnd = SimpleCharStream.getPosition() + 1;
2680 } catch (ParseException e) {
2681 errorMessage = "':' expected after case expression";
2683 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2684 errorEnd = SimpleCharStream.getPosition() + 1;
2692 } catch (ParseException e) {
2693 errorMessage = "':' expected after 'default' keyword";
2695 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2696 errorEnd = SimpleCharStream.getPosition() + 1;
2701 Break BreakStatement() :
2703 Expression expression = null;
2704 final Token token, token2;
2707 token = <BREAK> [ expression = Expression() ]
2709 token2 = <SEMICOLON>
2710 } catch (ParseException e) {
2711 errorMessage = "';' expected after 'break' keyword";
2713 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2714 errorEnd = SimpleCharStream.getPosition() + 1;
2717 {return new Break(expression, token.sourceStart, token2.sourceEnd);}
2720 IfStatement IfStatement() :
2722 final int pos = SimpleCharStream.getPosition();
2723 final Expression condition;
2724 final IfStatement ifStatement;
2728 token = <IF> condition = Condition("if") ifStatement = IfStatement0(condition,
2729 token.sourceStart,token.sourceStart+2)
2730 {return ifStatement;}
2734 Expression Condition(final String keyword) :
2736 final Expression condition;
2741 } catch (ParseException e) {
2742 errorMessage = "'(' expected after " + keyword + " keyword";
2744 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length();
2745 errorEnd = errorStart +1;
2746 processParseExceptionDebug(e);
2748 condition = Expression()
2751 } catch (ParseException e) {
2752 errorMessage = "')' expected after " + keyword + " keyword";
2754 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2755 errorEnd = SimpleCharStream.getPosition() + 1;
2756 processParseExceptionDebug(e);
2761 IfStatement IfStatement0(final Expression condition, final int start,final int end) :
2763 Statement statement;
2764 final Statement stmt;
2765 final Statement[] statementsArray;
2766 ElseIf elseifStatement;
2767 Else elseStatement = null;
2768 final ArrayList stmts;
2769 final ArrayList elseIfList = new ArrayList();
2770 final ElseIf[] elseIfs;
2771 int pos = SimpleCharStream.getPosition();
2772 final int endStatements;
2776 {stmts = new ArrayList();}
2777 ( statement = Statement() {stmts.add(statement);}
2778 | statement = htmlBlock() {stmts.add(statement);})*
2779 {endStatements = SimpleCharStream.getPosition();}
2780 (elseifStatement = ElseIfStatementColon() {elseIfList.add(elseifStatement);})*
2781 [elseStatement = ElseStatementColon()]
2784 setMarker(fileToParse,
2785 "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
2789 "Line " + token.beginLine);
2790 } catch (CoreException e) {
2791 PHPeclipsePlugin.log(e);
2795 } catch (ParseException e) {
2796 errorMessage = "'endif' expected";
2798 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2799 errorEnd = SimpleCharStream.getPosition() + 1;
2804 } catch (ParseException e) {
2805 errorMessage = "';' expected after 'endif' keyword";
2807 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2808 errorEnd = SimpleCharStream.getPosition() + 1;
2812 elseIfs = new ElseIf[elseIfList.size()];
2813 elseIfList.toArray(elseIfs);
2814 if (stmts.size() == 1) {
2815 return new IfStatement(condition,
2816 (Statement) stmts.get(0),
2820 SimpleCharStream.getPosition());
2822 statementsArray = new Statement[stmts.size()];
2823 stmts.toArray(statementsArray);
2824 return new IfStatement(condition,
2825 new Block(statementsArray,pos,endStatements),
2829 SimpleCharStream.getPosition());
2834 (stmt = Statement() | stmt = htmlBlock())
2835 ( LOOKAHEAD(1) elseifStatement = ElseIfStatement() {elseIfList.add(elseifStatement);})*
2839 {pos = SimpleCharStream.getPosition();}
2840 statement = Statement()
2841 {elseStatement = new Else(statement,pos,SimpleCharStream.getPosition());}
2842 } catch (ParseException e) {
2843 if (errorMessage != null) {
2846 errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected";
2848 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2849 errorEnd = SimpleCharStream.getPosition() + 1;
2854 elseIfs = new ElseIf[elseIfList.size()];
2855 elseIfList.toArray(elseIfs);
2856 return new IfStatement(condition,
2861 SimpleCharStream.getPosition());}
2864 ElseIf ElseIfStatementColon() :
2866 final Expression condition;
2867 Statement statement;
2868 final ArrayList list = new ArrayList();
2869 final int pos = SimpleCharStream.getPosition();
2872 <ELSEIF> condition = Condition("elseif")
2873 <COLON> ( statement = Statement() {list.add(statement);}
2874 | statement = htmlBlock() {list.add(statement);})*
2876 final Statement[] stmtsArray = new Statement[list.size()];
2877 list.toArray(stmtsArray);
2878 return new ElseIf(condition,stmtsArray ,pos,SimpleCharStream.getPosition());}
2881 Else ElseStatementColon() :
2883 Statement statement;
2884 final ArrayList list = new ArrayList();
2885 final int pos = SimpleCharStream.getPosition();
2888 <ELSE> <COLON> ( statement = Statement() {list.add(statement);}
2889 | statement = htmlBlock() {list.add(statement);})*
2891 final Statement[] stmtsArray = new Statement[list.size()];
2892 list.toArray(stmtsArray);
2893 return new Else(stmtsArray,pos,SimpleCharStream.getPosition());}
2896 ElseIf ElseIfStatement() :
2898 final Expression condition;
2899 final Statement statement;
2900 final ArrayList list = new ArrayList();
2901 final int pos = SimpleCharStream.getPosition();
2904 <ELSEIF> condition = Condition("elseif") statement = Statement() {list.add(statement);/*todo:do better*/}
2906 final Statement[] stmtsArray = new Statement[list.size()];
2907 list.toArray(stmtsArray);
2908 return new ElseIf(condition,stmtsArray,pos,SimpleCharStream.getPosition());}
2911 WhileStatement WhileStatement() :
2913 final Expression condition;
2914 final Statement action;
2915 final int pos = SimpleCharStream.getPosition();
2919 condition = Condition("while")
2920 action = WhileStatement0(pos,pos + 5)
2921 {return new WhileStatement(condition,action,pos,SimpleCharStream.getPosition());}
2924 Statement WhileStatement0(final int start, final int end) :
2926 Statement statement;
2927 final ArrayList stmts = new ArrayList();
2928 final int pos = SimpleCharStream.getPosition();
2931 <COLON> (statement = Statement() {stmts.add(statement);})*
2933 setMarker(fileToParse,
2934 "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
2938 "Line " + token.beginLine);
2939 } catch (CoreException e) {
2940 PHPeclipsePlugin.log(e);
2944 } catch (ParseException e) {
2945 errorMessage = "'endwhile' expected";
2947 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2948 errorEnd = SimpleCharStream.getPosition() + 1;
2954 final Statement[] stmtsArray = new Statement[stmts.size()];
2955 stmts.toArray(stmtsArray);
2956 return new Block(stmtsArray,pos,SimpleCharStream.getPosition());}
2957 } catch (ParseException e) {
2958 errorMessage = "';' expected after 'endwhile' keyword";
2960 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2961 errorEnd = SimpleCharStream.getPosition() + 1;
2965 statement = Statement()
2969 DoStatement DoStatement() :
2971 final Statement action;
2972 final Expression condition;
2973 final Token token, token2;
2976 token = <DO> action = Statement() <WHILE> condition = Condition("while")
2978 token2 = <SEMICOLON>
2979 {return new DoStatement(condition,action,token.sourceStart,token2.sourceEnd);}
2980 } catch (ParseException e) {
2981 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2983 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2984 errorEnd = SimpleCharStream.getPosition() + 1;
2989 ForeachStatement ForeachStatement() :
2991 Statement statement;
2992 Expression expression;
2993 ArrayVariableDeclaration variable;
3000 } catch (ParseException e) {
3001 errorMessage = "'(' expected after 'foreach' keyword";
3003 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3004 errorEnd = SimpleCharStream.getPosition() + 1;
3008 expression = Expression()
3009 } catch (ParseException e) {
3010 errorMessage = "variable expected";
3012 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3013 errorEnd = SimpleCharStream.getPosition() + 1;
3018 } catch (ParseException e) {
3019 errorMessage = "'as' expected";
3021 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3022 errorEnd = SimpleCharStream.getPosition() + 1;
3026 variable = ArrayVariable()
3027 } catch (ParseException e) {
3028 errorMessage = "variable expected";
3030 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3031 errorEnd = SimpleCharStream.getPosition() + 1;
3036 } catch (ParseException e) {
3037 errorMessage = "')' expected after 'foreach' keyword";
3039 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3040 errorEnd = SimpleCharStream.getPosition() + 1;
3044 statement = Statement()
3045 } catch (ParseException e) {
3046 if (errorMessage != null) throw e;
3047 errorMessage = "statement expected";
3049 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3050 errorEnd = SimpleCharStream.getPosition() + 1;
3053 {return new ForeachStatement(expression,
3057 statement.sourceEnd);}
3061 ForStatement ForStatement() :
3063 final Token token,token2;
3064 final int pos = SimpleCharStream.getPosition();
3065 Expression[] initializations = null;
3066 Expression condition = null;
3067 Expression[] increments = null;
3069 final ArrayList list = new ArrayList();
3070 final int startBlock, endBlock;
3076 } catch (ParseException e) {
3077 errorMessage = "'(' expected after 'for' keyword";
3079 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3080 errorEnd = SimpleCharStream.getPosition() + 1;
3083 [ initializations = ForInit() ] <SEMICOLON>
3084 [ condition = Expression() ] <SEMICOLON>
3085 [ increments = StatementExpressionList() ] <RPAREN>
3087 action = Statement()
3088 {return new ForStatement(initializations,
3096 {startBlock = SimpleCharStream.getPosition();}
3097 (action = Statement() {list.add(action);})*
3100 setMarker(fileToParse,
3101 "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
3103 pos+token.image.length(),
3105 "Line " + token.beginLine);
3106 } catch (CoreException e) {
3107 PHPeclipsePlugin.log(e);
3110 {endBlock = SimpleCharStream.getPosition();}
3113 } catch (ParseException e) {
3114 errorMessage = "'endfor' expected";
3116 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3117 errorEnd = SimpleCharStream.getPosition() + 1;
3121 token2 = <SEMICOLON>
3123 final Statement[] stmtsArray = new Statement[list.size()];
3124 list.toArray(stmtsArray);
3125 return new ForStatement(initializations,
3128 new Block(stmtsArray,
3129 stmtsArray[0].sourceStart,
3130 stmtsArray[stmtsArray.length-1].sourceEnd),
3133 } catch (ParseException e) {
3134 errorMessage = "';' expected after 'endfor' keyword";
3136 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3137 errorEnd = SimpleCharStream.getPosition() + 1;
3143 Expression[] ForInit() :
3145 final Expression[] exprs;
3148 LOOKAHEAD(LocalVariableDeclaration())
3149 exprs = LocalVariableDeclaration()
3152 exprs = StatementExpressionList()
3156 Expression[] StatementExpressionList() :
3158 final ArrayList list = new ArrayList();
3159 final Expression expr;
3162 expr = StatementExpression() {list.add(expr);}
3163 (<COMMA> StatementExpression() {list.add(expr);})*
3165 final Expression[] exprsArray = new Expression[list.size()];
3166 list.toArray(exprsArray);
3171 Continue ContinueStatement() :
3173 Expression expr = null;
3174 final Token token,token2;
3177 token = <CONTINUE> [ expr = Expression() ]
3179 token2 = <SEMICOLON>
3180 {return new Continue(expr,token.sourceStart,token2.sourceEnd);}
3181 } catch (ParseException e) {
3182 errorMessage = "';' expected after 'continue' statement";
3184 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3185 errorEnd = SimpleCharStream.getPosition() + 1;
3190 ReturnStatement ReturnStatement() :
3192 Expression expr = null;
3193 final Token token,token2;
3196 token = <RETURN> [ expr = Expression() ]
3198 token2 = <SEMICOLON>
3199 {return new ReturnStatement(expr,token.sourceStart,token2.sourceEnd);}
3200 } catch (ParseException e) {
3201 errorMessage = "';' expected after 'return' statement";
3203 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3204 errorEnd = SimpleCharStream.getPosition() + 1;