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 char[] SYNTAX_ERROR_CHAR = {'s','y','n','t','a','x',' ','e','r','r','o','r'};
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 SimpleCharStream.tokenBegin,
221 SimpleCharStream.tokenBegin + e.currentToken.image.length(),
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
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 int pos = SimpleCharStream.getPosition();
705 final PHPEchoBlock echoBlock;
708 <PHPECHOSTART> expr = Expression() [ <SEMICOLON> ] <PHPEND>
710 echoBlock = new PHPEchoBlock(expr,pos,SimpleCharStream.getPosition());
711 pushOnAstNodes(echoBlock);
721 ClassDeclaration ClassDeclaration() :
723 final ClassDeclaration classDeclaration;
724 final Token className,superclassName;
726 char[] classNameImage = SYNTAX_ERROR_CHAR;
727 char[] superclassNameImage = null;
731 {pos = SimpleCharStream.getPosition();}
733 className = <IDENTIFIER>
734 {classNameImage = className.image.toCharArray();}
735 } catch (ParseException e) {
736 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
738 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
739 errorEnd = SimpleCharStream.getPosition() + 1;
740 processParseExceptionDebug(e);
745 superclassName = <IDENTIFIER>
746 {superclassNameImage = superclassName.image.toCharArray();}
747 } catch (ParseException e) {
748 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
750 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
751 errorEnd = SimpleCharStream.getPosition() + 1;
752 processParseExceptionDebug(e);
753 superclassNameImage = SYNTAX_ERROR_CHAR;
757 if (superclassNameImage == null) {
758 classDeclaration = new ClassDeclaration(currentSegment,
763 classDeclaration = new ClassDeclaration(currentSegment,
769 currentSegment.add(classDeclaration);
770 currentSegment = classDeclaration;
772 ClassBody(classDeclaration)
773 {currentSegment = (OutlineableWithChildren) currentSegment.getParent();
774 classDeclaration.sourceEnd = SimpleCharStream.getPosition();
775 pushOnAstNodes(classDeclaration);
776 return classDeclaration;}
779 void ClassBody(final ClassDeclaration classDeclaration) :
784 } catch (ParseException e) {
785 errorMessage = "unexpected token : '"+ e.currentToken.next.image + "'. '{' expected";
787 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
788 errorEnd = SimpleCharStream.getPosition() + 1;
789 processParseExceptionDebug(e);
791 ( ClassBodyDeclaration(classDeclaration) )*
794 } catch (ParseException e) {
795 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. 'var', 'function' or '}' expected";
797 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
798 errorEnd = SimpleCharStream.getPosition() + 1;
799 processParseExceptionDebug(e);
804 * A class can contain only methods and fields.
806 void ClassBodyDeclaration(final ClassDeclaration classDeclaration) :
808 final MethodDeclaration method;
809 final FieldDeclaration field;
812 method = MethodDeclaration() {method.analyzeCode();
813 classDeclaration.addMethod(method);}
814 | field = FieldDeclaration() {classDeclaration.addField(field);}
818 * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;.
819 * it is only used by ClassBodyDeclaration()
821 FieldDeclaration FieldDeclaration() :
823 VariableDeclaration variableDeclaration;
824 final VariableDeclaration[] list;
825 final ArrayList arrayList = new ArrayList();
826 final int pos = SimpleCharStream.getPosition();
829 <VAR> variableDeclaration = VariableDeclaratorNoSuffix()
830 {arrayList.add(variableDeclaration);
831 outlineInfo.addVariable(new String(variableDeclaration.name()));}
833 <COMMA> variableDeclaration = VariableDeclaratorNoSuffix()
834 {arrayList.add(variableDeclaration);
835 outlineInfo.addVariable(new String(variableDeclaration.name()));}
839 } catch (ParseException e) {
840 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected after variable declaration";
842 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
843 errorEnd = SimpleCharStream.getPosition() + 1;
844 processParseExceptionDebug(e);
847 {list = new VariableDeclaration[arrayList.size()];
848 arrayList.toArray(list);
849 return new FieldDeclaration(list,
851 SimpleCharStream.getPosition(),
856 * a strict variable declarator : there cannot be a suffix here.
857 * It will be used by fields and formal parameters
859 VariableDeclaration VariableDeclaratorNoSuffix() :
862 Expression initializer = null;
865 varName = <DOLLAR_ID>
866 {final int pos = SimpleCharStream.getPosition()-varName.image.length();}
870 initializer = VariableInitializer()
871 } catch (ParseException e) {
872 errorMessage = "Literal expression expected in variable initializer";
874 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
875 errorEnd = SimpleCharStream.getPosition() + 1;
876 processParseExceptionDebug(e);
880 if (initializer == null) {
881 return new VariableDeclaration(currentSegment,
882 new Variable(varName.image.substring(1),
886 SimpleCharStream.getPosition());
888 return new VariableDeclaration(currentSegment,
889 new Variable(varName.image.substring(1),
893 VariableDeclaration.EQUAL,
899 * this will be used by static statement
901 VariableDeclaration VariableDeclarator() :
903 final AbstractVariable variable;
904 Expression initializer = null;
905 final int pos = SimpleCharStream.getPosition();
908 variable = VariableDeclaratorId()
912 initializer = VariableInitializer()
913 } catch (ParseException e) {
914 errorMessage = "Literal expression expected in variable initializer";
916 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
917 errorEnd = SimpleCharStream.getPosition() + 1;
918 processParseExceptionDebug(e);
922 if (initializer == null) {
923 return new VariableDeclaration(currentSegment,
926 SimpleCharStream.getPosition());
928 return new VariableDeclaration(currentSegment,
931 VariableDeclaration.EQUAL,
938 * @return the variable name (with suffix)
940 AbstractVariable VariableDeclaratorId() :
943 AbstractVariable expression = null;
944 final int pos = SimpleCharStream.getPosition();
951 expression = VariableSuffix(var)
954 if (expression == null) {
959 } catch (ParseException e) {
960 errorMessage = "'$' expected for variable identifier";
962 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
963 errorEnd = SimpleCharStream.getPosition() + 1;
969 * Return a variablename without the $.
970 * @return a variable name
974 final StringBuffer buff;
975 Expression expression = null;
981 token = <DOLLAR_ID> {pos = SimpleCharStream.getPosition()-token.image.length();}
982 [<LBRACE> expression = Expression() <RBRACE>]
984 if (expression == null) {
985 return new Variable(token.image.substring(1),token.sourceStart,token.sourceEnd);
987 String s = expression.toStringExpression();
988 buff = new StringBuffer(token.image.length()+s.length()+2);
989 buff.append(token.image);
994 return new Variable(s,token.sourceStart,token.sourceEnd);
998 expr = VariableName()
999 {return new Variable(expr,token.sourceStart,expr.sourceEnd);}
1003 * A Variable name (without the $)
1004 * @return a variable name String
1006 Variable VariableName():
1008 final StringBuffer buff;
1011 Expression expression = null;
1013 Token token2 = null;
1018 {pos = SimpleCharStream.getPosition()-1;}
1019 expression = Expression() token2 = <RBRACE>
1020 {expr = expression.toStringExpression();
1021 buff = new StringBuffer(expr.length()+2);
1025 pos = SimpleCharStream.getPosition();
1026 expr = buff.toString();
1027 return new Variable(expr,
1033 token = <IDENTIFIER>
1034 {pos = SimpleCharStream.getPosition() - token.image.length();}
1035 [<LBRACE> expression = Expression() token2 = <RBRACE>]
1037 if (expression == null) {
1038 return new Variable(token.image,
1042 expr = expression.toStringExpression();
1043 buff = new StringBuffer(token.image.length()+expr.length()+2);
1044 buff.append(token.image);
1048 expr = buff.toString();
1049 return new Variable(expr,
1055 var = VariableName()
1057 return new Variable(var,
1064 return new Variable(token.image,
1070 Expression VariableInitializer() :
1072 final Expression expr;
1073 final Token token, token2;
1079 token2 = <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1080 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1082 token2.sourceStart);}
1084 token2 = <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1085 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1087 token2.sourceStart);}
1089 expr = ArrayDeclarator()
1092 token = <IDENTIFIER>
1093 {return new ConstantIdentifier(token);}
1096 ArrayVariableDeclaration ArrayVariable() :
1098 final Expression expr,expr2;
1103 <ARRAYASSIGN> expr2 = Expression()
1104 {return new ArrayVariableDeclaration(expr,expr2);}
1106 {return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());}
1109 ArrayVariableDeclaration[] ArrayInitializer() :
1111 ArrayVariableDeclaration expr;
1112 final ArrayList list = new ArrayList();
1117 expr = ArrayVariable()
1119 ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
1124 <COMMA> {list.add(null);}
1128 final ArrayVariableDeclaration[] vars = new ArrayVariableDeclaration[list.size()];
1134 * A Method Declaration.
1135 * <b>function</b> MetodDeclarator() Block()
1137 MethodDeclaration MethodDeclaration() :
1139 final MethodDeclaration functionDeclaration;
1141 final OutlineableWithChildren seg = currentSegment;
1146 functionDeclaration = MethodDeclarator()
1147 {outlineInfo.addVariable(new String(functionDeclaration.name));}
1148 } catch (ParseException e) {
1149 if (errorMessage != null) throw e;
1150 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1152 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1153 errorEnd = SimpleCharStream.getPosition() + 1;
1156 {currentSegment = functionDeclaration;}
1158 {functionDeclaration.statements = block.statements;
1159 currentSegment = seg;
1160 return functionDeclaration;}
1164 * A MethodDeclarator.
1165 * [&] IDENTIFIER(parameters ...).
1166 * @return a function description for the outline
1168 MethodDeclaration MethodDeclarator() :
1170 final Token identifier;
1171 Token reference = null;
1172 final Hashtable formalParameters;
1173 final int pos = SimpleCharStream.getPosition();
1174 char[] identifierChar = SYNTAX_ERROR_CHAR;
1177 [reference = <BIT_AND>]
1179 identifier = <IDENTIFIER>
1180 {identifierChar = identifier.image.toCharArray();}
1181 } catch (ParseException e) {
1182 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1184 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1185 errorEnd = SimpleCharStream.getPosition() + 1;
1186 processParseExceptionDebug(e);
1188 formalParameters = FormalParameters()
1189 {MethodDeclaration method = new MethodDeclaration(currentSegment,
1194 SimpleCharStream.getPosition());
1199 * FormalParameters follows method identifier.
1200 * (FormalParameter())
1202 Hashtable FormalParameters() :
1204 VariableDeclaration var;
1205 final Hashtable parameters = new Hashtable();
1210 } catch (ParseException e) {
1211 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected after function identifier";
1213 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1214 errorEnd = SimpleCharStream.getPosition() + 1;
1215 processParseExceptionDebug(e);
1218 var = FormalParameter()
1219 {parameters.put(new String(var.name()),var);}
1221 <COMMA> var = FormalParameter()
1222 {parameters.put(new String(var.name()),var);}
1227 } catch (ParseException e) {
1228 errorMessage = "')' expected";
1230 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1231 errorEnd = SimpleCharStream.getPosition() + 1;
1232 processParseExceptionDebug(e);
1234 {return parameters;}
1238 * A formal parameter.
1239 * $varname[=value] (,$varname[=value])
1241 VariableDeclaration FormalParameter() :
1243 final VariableDeclaration variableDeclaration;
1247 [token = <BIT_AND>] variableDeclaration = VariableDeclaratorNoSuffix()
1249 if (token != null) {
1250 variableDeclaration.setReference(true);
1252 return variableDeclaration;}
1255 ConstantIdentifier Type() :
1256 {final Token token;}
1258 token = <STRING> {return new ConstantIdentifier(token);}
1259 | token = <BOOL> {return new ConstantIdentifier(token);}
1260 | token = <BOOLEAN> {return new ConstantIdentifier(token);}
1261 | token = <REAL> {return new ConstantIdentifier(token);}
1262 | token = <DOUBLE> {return new ConstantIdentifier(token);}
1263 | token = <FLOAT> {return new ConstantIdentifier(token);}
1264 | token = <INT> {return new ConstantIdentifier(token);}
1265 | token = <INTEGER> {return new ConstantIdentifier(token);}
1266 | token = <OBJECT> {return new ConstantIdentifier(token);}
1269 Expression Expression() :
1271 final Expression expr;
1272 Expression initializer = null;
1273 final int pos = SimpleCharStream.getPosition();
1274 int assignOperator = -1;
1278 expr = ConditionalExpression()
1280 assignOperator = AssignmentOperator()
1282 initializer = Expression()
1283 } catch (ParseException e) {
1284 if (errorMessage != null) {
1287 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1289 errorEnd = SimpleCharStream.getPosition();
1294 if (assignOperator != -1) {// todo : change this, very very bad :(
1295 if (expr instanceof AbstractVariable) {
1296 return new VariableDeclaration(currentSegment,
1297 (AbstractVariable) expr,
1300 initializer.sourceEnd);
1302 String varName = expr.toStringExpression().substring(1);
1303 return new VariableDeclaration(currentSegment,
1304 new Variable(varName,
1308 initializer.sourceEnd);
1312 | expr = ExpressionWBang() {return expr;}
1315 Expression ExpressionWBang() :
1317 final Expression expr;
1318 final int pos = SimpleCharStream.getPosition();
1321 <BANG> expr = ExpressionWBang() {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,pos);}
1322 | expr = ExpressionNoBang() {return expr;}
1325 Expression ExpressionNoBang() :
1330 expr = ListExpression() {return expr;}
1332 expr = PrintExpression() {return expr;}
1336 * Any assignement operator.
1337 * @return the assignement operator id
1339 int AssignmentOperator() :
1342 <ASSIGN> {return VariableDeclaration.EQUAL;}
1343 | <STARASSIGN> {return VariableDeclaration.STAR_EQUAL;}
1344 | <SLASHASSIGN> {return VariableDeclaration.SLASH_EQUAL;}
1345 | <REMASSIGN> {return VariableDeclaration.REM_EQUAL;}
1346 | <PLUSASSIGN> {return VariableDeclaration.PLUS_EQUAL;}
1347 | <MINUSASSIGN> {return VariableDeclaration.MINUS_EQUAL;}
1348 | <LSHIFTASSIGN> {return VariableDeclaration.LSHIFT_EQUAL;}
1349 | <RSIGNEDSHIFTASSIGN> {return VariableDeclaration.RSIGNEDSHIFT_EQUAL;}
1350 | <ANDASSIGN> {return VariableDeclaration.AND_EQUAL;}
1351 | <XORASSIGN> {return VariableDeclaration.XOR_EQUAL;}
1352 | <ORASSIGN> {return VariableDeclaration.OR_EQUAL;}
1353 | <DOTASSIGN> {return VariableDeclaration.DOT_EQUAL;}
1354 | <TILDEEQUAL> {return VariableDeclaration.TILDE_EQUAL;}
1357 Expression ConditionalExpression() :
1359 final Expression expr;
1360 Expression expr2 = null;
1361 Expression expr3 = null;
1364 expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
1366 if (expr3 == null) {
1369 return new ConditionalExpression(expr,expr2,expr3);
1373 Expression ConditionalOrExpression() :
1375 Expression expr,expr2;
1379 expr = ConditionalAndExpression()
1382 <OR_OR> {operator = OperatorIds.OR_OR;}
1383 | <_ORL> {operator = OperatorIds.ORL;}
1385 expr2 = ConditionalAndExpression()
1387 expr = new BinaryExpression(expr,expr2,operator);
1393 Expression ConditionalAndExpression() :
1395 Expression expr,expr2;
1399 expr = ConcatExpression()
1401 ( <AND_AND> {operator = OperatorIds.AND_AND;}
1402 | <_ANDL> {operator = OperatorIds.ANDL;})
1403 expr2 = ConcatExpression() {expr = new BinaryExpression(expr,expr2,operator);}
1408 Expression ConcatExpression() :
1410 Expression expr,expr2;
1413 expr = InclusiveOrExpression()
1415 <DOT> expr2 = InclusiveOrExpression()
1416 {expr = new BinaryExpression(expr,expr2,OperatorIds.DOT);}
1421 Expression InclusiveOrExpression() :
1423 Expression expr,expr2;
1426 expr = ExclusiveOrExpression()
1427 (<BIT_OR> expr2 = ExclusiveOrExpression()
1428 {expr = new BinaryExpression(expr,expr2,OperatorIds.OR);}
1433 Expression ExclusiveOrExpression() :
1435 Expression expr,expr2;
1438 expr = AndExpression()
1440 <XOR> expr2 = AndExpression()
1441 {expr = new BinaryExpression(expr,expr2,OperatorIds.XOR);}
1446 Expression AndExpression() :
1448 Expression expr,expr2;
1451 expr = EqualityExpression()
1454 <BIT_AND> expr2 = EqualityExpression()
1455 {expr = new BinaryExpression(expr,expr2,OperatorIds.AND);}
1460 Expression EqualityExpression() :
1462 Expression expr,expr2;
1466 expr = RelationalExpression()
1468 ( <EQUAL_EQUAL> {operator = OperatorIds.EQUAL_EQUAL;}
1469 | <DIF> {operator = OperatorIds.DIF;}
1470 | <NOT_EQUAL> {operator = OperatorIds.DIF;}
1471 | <BANGDOUBLEEQUAL> {operator = OperatorIds.BANG_EQUAL_EQUAL;}
1472 | <TRIPLEEQUAL> {operator = OperatorIds.EQUAL_EQUAL_EQUAL;}
1475 expr2 = RelationalExpression()
1476 } catch (ParseException e) {
1477 if (errorMessage != null) {
1480 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1482 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1483 errorEnd = SimpleCharStream.getPosition() + 1;
1487 expr = new BinaryExpression(expr,expr2,operator);
1493 Expression RelationalExpression() :
1495 Expression expr,expr2;
1499 expr = ShiftExpression()
1501 ( <LT> {operator = OperatorIds.LESS;}
1502 | <GT> {operator = OperatorIds.GREATER;}
1503 | <LE> {operator = OperatorIds.LESS_EQUAL;}
1504 | <GE> {operator = OperatorIds.GREATER_EQUAL;})
1505 expr2 = ShiftExpression()
1506 {expr = new BinaryExpression(expr,expr2,operator);}
1511 Expression ShiftExpression() :
1513 Expression expr,expr2;
1517 expr = AdditiveExpression()
1519 ( <LSHIFT> {operator = OperatorIds.LEFT_SHIFT;}
1520 | <RSIGNEDSHIFT> {operator = OperatorIds.RIGHT_SHIFT;}
1521 | <RUNSIGNEDSHIFT> {operator = OperatorIds.UNSIGNED_RIGHT_SHIFT;})
1522 expr2 = AdditiveExpression()
1523 {expr = new BinaryExpression(expr,expr2,operator);}
1528 Expression AdditiveExpression() :
1530 Expression expr,expr2;
1534 expr = MultiplicativeExpression()
1537 ( <PLUS> {operator = OperatorIds.PLUS;}
1538 | <MINUS> {operator = OperatorIds.MINUS;}
1540 expr2 = MultiplicativeExpression()
1541 {expr = new BinaryExpression(expr,expr2,operator);}
1546 Expression MultiplicativeExpression() :
1548 Expression expr,expr2;
1553 expr = UnaryExpression()
1554 } catch (ParseException e) {
1555 if (errorMessage != null) throw e;
1556 errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
1558 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1559 errorEnd = SimpleCharStream.getPosition() + 1;
1563 ( <STAR> {operator = OperatorIds.MULTIPLY;}
1564 | <SLASH> {operator = OperatorIds.DIVIDE;}
1565 | <REMAINDER> {operator = OperatorIds.REMAINDER;})
1566 expr2 = UnaryExpression()
1567 {expr = new BinaryExpression(expr,expr2,operator);}
1573 * An unary expression starting with @, & or nothing
1575 Expression UnaryExpression() :
1577 final Expression expr;
1578 final int pos = SimpleCharStream.getPosition();
1581 /* <BIT_AND> expr = UnaryExpressionNoPrefix() //why did I had that ?
1582 {return new PrefixedUnaryExpression(expr,OperatorIds.AND,pos);}
1584 expr = AtNotUnaryExpression() {return expr;}
1588 * An expression prefixed (or not) by one or more @ and !.
1589 * @return the expression
1591 Expression AtNotUnaryExpression() :
1593 final Expression expr;
1594 final int pos = SimpleCharStream.getPosition();
1598 expr = AtNotUnaryExpression()
1599 {return new PrefixedUnaryExpression(expr,OperatorIds.AT,pos);}
1602 expr = AtNotUnaryExpression()
1603 {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,pos);}
1605 expr = UnaryExpressionNoPrefix()
1610 Expression UnaryExpressionNoPrefix() :
1612 final Expression expr;
1613 final int pos = SimpleCharStream.getPosition();
1616 <PLUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,OperatorIds.PLUS,pos);}
1618 <MINUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,OperatorIds.MINUS,pos);}
1620 expr = PreIncDecExpression()
1623 expr = UnaryExpressionNotPlusMinus()
1628 Expression PreIncDecExpression() :
1630 final Expression expr;
1632 final int pos = SimpleCharStream.getPosition();
1636 <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1638 <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1640 expr = PrimaryExpression()
1641 {return new PrefixedUnaryExpression(expr,operator,pos);}
1644 Expression UnaryExpressionNotPlusMinus() :
1646 final Expression expr;
1647 final int pos = SimpleCharStream.getPosition();
1650 LOOKAHEAD( <LPAREN> (Type() | <ARRAY>) <RPAREN> )
1651 expr = CastExpression() {return expr;}
1652 | expr = PostfixExpression() {return expr;}
1653 | expr = Literal() {return expr;}
1654 | <LPAREN> expr = Expression()
1657 } catch (ParseException e) {
1658 errorMessage = "')' expected";
1660 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1661 errorEnd = SimpleCharStream.getPosition() + 1;
1667 CastExpression CastExpression() :
1669 final ConstantIdentifier type;
1670 final Expression expr;
1671 final Token token,token1;
1678 token = <ARRAY> {type = new ConstantIdentifier(token);}
1680 <RPAREN> expr = UnaryExpression()
1681 {return new CastExpression(type,expr,token1.sourceStart,expr.sourceEnd);}
1684 Expression PostfixExpression() :
1686 final Expression expr;
1691 expr = PrimaryExpression()
1693 token = <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1695 token = <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1698 if (operator == -1) {
1701 return new PostfixedUnaryExpression(expr,operator,token.sourceEnd);
1705 Expression PrimaryExpression() :
1707 Expression expr = null;
1709 int assignOperator = -1;
1710 final Token identifier;
1715 token = <IDENTIFIER>
1717 expr = new ConstantIdentifier(token);
1720 <STATICCLASSACCESS> expr2 = ClassIdentifier()
1721 {expr = new ClassAccess(expr,
1723 ClassAccess.STATIC);}
1725 [ expr = Arguments(expr) ]
1728 expr = VariableDeclaratorId()
1729 [ expr = Arguments(expr) ]
1733 expr = ClassIdentifier()
1734 {expr = new PrefixedUnaryExpression(expr,
1738 [ expr = Arguments(expr) ]
1741 expr = ArrayDeclarator()
1746 * An array declarator.
1750 ArrayInitializer ArrayDeclarator() :
1752 final ArrayVariableDeclaration[] vars;
1753 final int pos = SimpleCharStream.getPosition();
1756 <ARRAY> vars = ArrayInitializer()
1757 {return new ArrayInitializer(vars,pos,SimpleCharStream.getPosition());}
1760 PrefixedUnaryExpression classInstantiation() :
1763 final StringBuffer buff;
1768 token = <NEW> expr = ClassIdentifier()
1770 {pos = expr.sourceStart;
1771 buff = new StringBuffer(expr.toStringExpression());}
1772 expr = PrimaryExpression()
1773 {buff.append(expr.toStringExpression());
1774 expr = new ConstantIdentifier(buff.toString(),
1778 {return new PrefixedUnaryExpression(expr,
1780 token.sourceStart);}
1783 Expression ClassIdentifier():
1785 final Expression expr;
1787 final ConstantIdentifier type;
1790 token = <IDENTIFIER> {return new ConstantIdentifier(token);}
1791 | expr = Type() {return expr;}
1792 | expr = VariableDeclaratorId() {return expr;}
1796 * Used by Variabledeclaratorid and primarysuffix
1798 AbstractVariable VariableSuffix(final AbstractVariable prefix) :
1800 Variable expr = null;
1801 final int pos = SimpleCharStream.getPosition();
1802 Expression expression = null;
1807 expr = VariableName()
1808 } catch (ParseException e) {
1809 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
1811 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1812 errorEnd = SimpleCharStream.getPosition() + 1;
1815 {return new ClassAccess(prefix,
1817 ClassAccess.NORMAL);}
1819 <LBRACKET> [ expression = Expression() | expression = Type() ] //Not good
1822 } catch (ParseException e) {
1823 errorMessage = "']' expected";
1825 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1826 errorEnd = SimpleCharStream.getPosition() + 1;
1829 {return new ArrayDeclarator(prefix,expression,SimpleCharStream.getPosition());}
1837 token = <INTEGER_LITERAL> {return new NumberLiteral(token);}
1838 | token = <FLOATING_POINT_LITERAL> {return new NumberLiteral(token);}
1839 | token = <STRING_LITERAL> {return new StringLiteral(token);}
1840 | token = <TRUE> {return new TrueLiteral(token);}
1841 | token = <FALSE> {return new FalseLiteral(token);}
1842 | token = <NULL> {return new NullLiteral(token);}
1845 FunctionCall Arguments(final Expression func) :
1847 Expression[] args = null;
1850 <LPAREN> [ args = ArgumentList() ]
1853 } catch (ParseException e) {
1854 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
1856 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1857 errorEnd = SimpleCharStream.getPosition() + 1;
1860 {return new FunctionCall(func,args,SimpleCharStream.getPosition());}
1864 * An argument list is a list of arguments separated by comma :
1865 * argumentDeclaration() (, argumentDeclaration)*
1866 * @return an array of arguments
1868 Expression[] ArgumentList() :
1871 final ArrayList list = new ArrayList();
1880 } catch (ParseException e) {
1881 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. An expression expected after a comma in argument list";
1883 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1884 errorEnd = SimpleCharStream.getPosition() + 1;
1889 final Expression[] arguments = new Expression[list.size()];
1890 list.toArray(arguments);
1895 * A Statement without break.
1896 * @return a statement
1898 Statement StatementNoBreak() :
1900 final Statement statement;
1905 statement = expressionStatement() {return statement;}
1907 statement = LabeledStatement() {return statement;}
1908 | statement = Block() {return statement;}
1909 | statement = EmptyStatement() {return statement;}
1910 | statement = SwitchStatement() {return statement;}
1911 | statement = IfStatement() {return statement;}
1912 | statement = WhileStatement() {return statement;}
1913 | statement = DoStatement() {return statement;}
1914 | statement = ForStatement() {return statement;}
1915 | statement = ForeachStatement() {return statement;}
1916 | statement = ContinueStatement() {return statement;}
1917 | statement = ReturnStatement() {return statement;}
1918 | statement = EchoStatement() {return statement;}
1919 | [token=<AT>] statement = IncludeStatement()
1920 {if (token != null) {
1921 ((InclusionStatement)statement).silent = true;
1924 | statement = StaticStatement() {return statement;}
1925 | statement = GlobalStatement() {return statement;}
1926 | statement = defineStatement() {currentSegment.add((Outlineable)statement);return statement;}
1930 * A statement expression.
1932 * @return an expression
1934 Statement expressionStatement() :
1936 final Statement statement;
1939 statement = Expression()
1942 } catch (ParseException e) {
1943 if (e.currentToken.next.kind != PHPParserConstants.PHPEND) {
1944 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
1946 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1947 errorEnd = SimpleCharStream.getPosition() + 1;
1954 Define defineStatement() :
1956 final int start = SimpleCharStream.getPosition();
1957 Expression defineName,defineValue;
1963 } catch (ParseException e) {
1964 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
1966 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1967 errorEnd = SimpleCharStream.getPosition() + 1;
1968 processParseExceptionDebug(e);
1971 defineName = Expression()
1972 } catch (ParseException e) {
1973 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1975 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1976 errorEnd = SimpleCharStream.getPosition() + 1;
1981 } catch (ParseException e) {
1982 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
1984 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1985 errorEnd = SimpleCharStream.getPosition() + 1;
1986 processParseExceptionDebug(e);
1989 defineValue = Expression()
1990 } catch (ParseException e) {
1991 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1993 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1994 errorEnd = SimpleCharStream.getPosition() + 1;
1999 } catch (ParseException e) {
2000 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2002 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2003 errorEnd = SimpleCharStream.getPosition() + 1;
2004 processParseExceptionDebug(e);
2006 {return new Define(currentSegment,
2010 SimpleCharStream.getPosition());}
2014 * A Normal statement.
2016 Statement Statement() :
2018 final Statement statement;
2021 statement = StatementNoBreak() {return statement;}
2022 | statement = BreakStatement() {return statement;}
2026 * An html block inside a php syntax.
2028 HTMLBlock htmlBlock() :
2030 final int startIndex = nodePtr;
2031 final AstNode[] blockNodes;
2035 <PHPEND> (phpEchoBlock())*
2037 (<PHPSTARTLONG> | <PHPSTARTSHORT>)
2038 } catch (ParseException e) {
2039 errorMessage = "unexpected end of file , '<?php' expected";
2041 errorStart = SimpleCharStream.getPosition();
2042 errorEnd = SimpleCharStream.getPosition();
2046 nbNodes = nodePtr - startIndex;
2047 blockNodes = new AstNode[nbNodes];
2048 System.arraycopy(nodes,startIndex,blockNodes,0,nbNodes);
2049 nodePtr = startIndex;
2050 return new HTMLBlock(blockNodes);}
2054 * An include statement. It's "include" an expression;
2056 InclusionStatement IncludeStatement() :
2058 final Expression expr;
2060 final int pos = SimpleCharStream.getPosition();
2061 final InclusionStatement inclusionStatement;
2064 ( <REQUIRE> {keyword = InclusionStatement.REQUIRE;}
2065 | <REQUIRE_ONCE> {keyword = InclusionStatement.REQUIRE_ONCE;}
2066 | <INCLUDE> {keyword = InclusionStatement.INCLUDE;}
2067 | <INCLUDE_ONCE> {keyword = InclusionStatement.INCLUDE_ONCE;})
2070 } catch (ParseException e) {
2071 if (errorMessage != null) {
2074 errorMessage = "unexpected token '"+ e.currentToken.next.image+"', expression expected";
2076 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2077 errorEnd = SimpleCharStream.getPosition() + 1;
2080 {inclusionStatement = new InclusionStatement(currentSegment,
2084 currentSegment.add(inclusionStatement);
2088 } catch (ParseException e) {
2089 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2091 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2092 errorEnd = SimpleCharStream.getPosition() + 1;
2095 {return inclusionStatement;}
2098 PrintExpression PrintExpression() :
2100 final Expression expr;
2101 final int pos = SimpleCharStream.getPosition();
2104 <PRINT> expr = Expression() {return new PrintExpression(expr,pos,SimpleCharStream.getPosition());}
2107 ListExpression ListExpression() :
2109 Expression expr = null;
2110 final Expression expression;
2111 final ArrayList list = new ArrayList();
2112 final int pos = SimpleCharStream.getPosition();
2118 } catch (ParseException e) {
2119 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
2121 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2122 errorEnd = SimpleCharStream.getPosition() + 1;
2126 expr = VariableDeclaratorId()
2129 {if (expr == null) list.add(null);}
2133 } catch (ParseException e) {
2134 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
2136 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2137 errorEnd = SimpleCharStream.getPosition() + 1;
2140 [expr = VariableDeclaratorId() {list.add(expr);}]
2144 } catch (ParseException e) {
2145 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2147 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2148 errorEnd = SimpleCharStream.getPosition() + 1;
2151 [ <ASSIGN> expression = Expression()
2153 final Variable[] vars = new Variable[list.size()];
2155 return new ListExpression(vars,
2158 SimpleCharStream.getPosition());}
2161 final Variable[] vars = new Variable[list.size()];
2163 return new ListExpression(vars,pos,SimpleCharStream.getPosition());}
2167 * An echo statement.
2168 * echo anyexpression (, otherexpression)*
2170 EchoStatement EchoStatement() :
2172 final ArrayList expressions = new ArrayList();
2174 final int pos = SimpleCharStream.getPosition();
2177 <ECHO> expr = Expression()
2178 {expressions.add(expr);}
2180 <COMMA> expr = Expression()
2181 {expressions.add(expr);}
2185 } catch (ParseException e) {
2186 if (e.currentToken.next.kind != 4) {
2187 errorMessage = "';' expected after 'echo' statement";
2189 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2190 errorEnd = SimpleCharStream.getPosition() + 1;
2194 {final Expression[] exprs = new Expression[expressions.size()];
2195 expressions.toArray(exprs);
2196 return new EchoStatement(exprs,pos);}
2199 GlobalStatement GlobalStatement() :
2201 final int pos = SimpleCharStream.getPosition();
2203 final ArrayList vars = new ArrayList();
2204 final GlobalStatement global;
2217 final Variable[] variables = new Variable[vars.size()];
2218 vars.toArray(variables);
2219 global = new GlobalStatement(currentSegment,
2222 SimpleCharStream.getPosition());
2223 currentSegment.add(global);
2225 } catch (ParseException e) {
2226 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2228 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2229 errorEnd = SimpleCharStream.getPosition() + 1;
2234 StaticStatement StaticStatement() :
2236 final int pos = SimpleCharStream.getPosition();
2237 final ArrayList vars = new ArrayList();
2238 VariableDeclaration expr;
2241 <STATIC> expr = VariableDeclarator() {vars.add(expr);}
2243 <COMMA> expr = VariableDeclarator() {vars.add(expr);}
2248 final VariableDeclaration[] variables = new VariableDeclaration[vars.size()];
2249 vars.toArray(variables);
2250 return new StaticStatement(variables,
2252 SimpleCharStream.getPosition());}
2253 } catch (ParseException e) {
2254 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2256 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2257 errorEnd = SimpleCharStream.getPosition() + 1;
2262 LabeledStatement LabeledStatement() :
2264 final int pos = SimpleCharStream.getPosition();
2266 final Statement statement;
2269 label = <IDENTIFIER> <COLON> statement = Statement()
2270 {return new LabeledStatement(label.image.toCharArray(),statement,pos,SimpleCharStream.getPosition());}
2282 final int pos = SimpleCharStream.getPosition();
2283 final ArrayList list = new ArrayList();
2284 Statement statement;
2289 } catch (ParseException e) {
2290 errorMessage = "'{' expected";
2292 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2293 errorEnd = SimpleCharStream.getPosition() + 1;
2296 ( statement = BlockStatement() {list.add(statement);}
2297 | statement = htmlBlock() {list.add(statement);})*
2300 } catch (ParseException e) {
2301 errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
2303 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2304 errorEnd = SimpleCharStream.getPosition() + 1;
2308 final Statement[] statements = new Statement[list.size()];
2309 list.toArray(statements);
2310 return new Block(statements,pos,SimpleCharStream.getPosition());}
2313 Statement BlockStatement() :
2315 final Statement statement;
2318 statement = Statement() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2320 | statement = ClassDeclaration() {return statement;}
2321 | statement = MethodDeclaration() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2322 currentSegment.add((MethodDeclaration) statement);
2323 ((MethodDeclaration) statement).analyzeCode();
2328 * A Block statement that will not contain any 'break'
2330 Statement BlockStatementNoBreak() :
2332 final Statement statement;
2335 statement = StatementNoBreak() {return statement;}
2336 | statement = ClassDeclaration() {return statement;}
2337 | statement = MethodDeclaration() {currentSegment.add((MethodDeclaration) statement);
2338 ((MethodDeclaration) statement).analyzeCode();
2343 * used only by ForInit()
2345 VariableDeclaration[] LocalVariableDeclaration() :
2347 final ArrayList list = new ArrayList();
2348 VariableDeclaration var;
2351 var = LocalVariableDeclarator()
2353 ( <COMMA> var = LocalVariableDeclarator() {list.add(var);})*
2355 final VariableDeclaration[] vars = new VariableDeclaration[list.size()];
2361 * used only by LocalVariableDeclaration().
2363 VariableDeclaration LocalVariableDeclarator() :
2365 final Variable varName;
2366 Expression initializer = null;
2367 final int pos = SimpleCharStream.getPosition();
2370 varName = Variable() [ <ASSIGN> initializer = Expression() ]
2372 if (initializer == null) {
2373 return new VariableDeclaration(currentSegment,
2376 SimpleCharStream.getPosition());
2378 return new VariableDeclaration(currentSegment,
2381 VariableDeclaration.EQUAL,
2386 EmptyStatement EmptyStatement() :
2392 {pos = SimpleCharStream.getPosition();
2393 return new EmptyStatement(pos-1,pos);}
2397 * used only by StatementExpressionList() which is used only by ForInit() and ForStatement()
2399 Expression StatementExpression() :
2401 final Expression expr,expr2;
2405 expr = PreIncDecExpression() {return expr;}
2407 expr = PrimaryExpression()
2408 [ <PLUS_PLUS> {return new PostfixedUnaryExpression(expr,
2409 OperatorIds.PLUS_PLUS,
2410 SimpleCharStream.getPosition());}
2411 | <MINUS_MINUS> {return new PostfixedUnaryExpression(expr,
2412 OperatorIds.MINUS_MINUS,
2413 SimpleCharStream.getPosition());}
2418 SwitchStatement SwitchStatement() :
2420 final Expression variable;
2421 final AbstractCase[] cases;
2422 final int pos = SimpleCharStream.getPosition();
2428 } catch (ParseException e) {
2429 errorMessage = "'(' expected after 'switch'";
2431 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2432 errorEnd = SimpleCharStream.getPosition() + 1;
2436 variable = Expression()
2437 } catch (ParseException e) {
2438 if (errorMessage != null) {
2441 errorMessage = "expression expected";
2443 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2444 errorEnd = SimpleCharStream.getPosition() + 1;
2449 } catch (ParseException e) {
2450 errorMessage = "')' expected";
2452 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2453 errorEnd = SimpleCharStream.getPosition() + 1;
2456 (cases = switchStatementBrace() | cases = switchStatementColon(pos, pos + 6))
2457 {return new SwitchStatement(variable,cases,pos,SimpleCharStream.getPosition());}
2460 AbstractCase[] switchStatementBrace() :
2463 final ArrayList cases = new ArrayList();
2467 ( cas = switchLabel0() {cases.add(cas);})*
2471 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2472 cases.toArray(abcase);
2474 } catch (ParseException e) {
2475 errorMessage = "'}' expected";
2477 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2478 errorEnd = SimpleCharStream.getPosition() + 1;
2483 * A Switch statement with : ... endswitch;
2484 * @param start the begin offset of the switch
2485 * @param end the end offset of the switch
2487 AbstractCase[] switchStatementColon(final int start, final int end) :
2490 final ArrayList cases = new ArrayList();
2495 setMarker(fileToParse,
2496 "Ugly syntax detected, you should switch () {...} instead of switch (): ... enswitch;",
2500 "Line " + token.beginLine);
2501 } catch (CoreException e) {
2502 PHPeclipsePlugin.log(e);
2504 ( cas = switchLabel0() {cases.add(cas);})*
2507 } catch (ParseException e) {
2508 errorMessage = "'endswitch' expected";
2510 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2511 errorEnd = SimpleCharStream.getPosition() + 1;
2517 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2518 cases.toArray(abcase);
2520 } catch (ParseException e) {
2521 errorMessage = "';' expected after 'endswitch' keyword";
2523 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2524 errorEnd = SimpleCharStream.getPosition() + 1;
2529 AbstractCase switchLabel0() :
2531 final Expression expr;
2532 Statement statement;
2533 final ArrayList stmts = new ArrayList();
2534 final int pos = SimpleCharStream.getPosition();
2537 expr = SwitchLabel()
2538 ( statement = BlockStatementNoBreak() {stmts.add(statement);}
2539 | statement = htmlBlock() {stmts.add(statement);})*
2540 [ statement = BreakStatement() {stmts.add(statement);}]
2542 final Statement[] stmtsArray = new Statement[stmts.size()];
2543 stmts.toArray(stmtsArray);
2544 if (expr == null) {//it's a default
2545 return new DefaultCase(stmtsArray,pos,SimpleCharStream.getPosition());
2547 return new Case(expr,stmtsArray,pos,SimpleCharStream.getPosition());}
2552 * case Expression() :
2554 * @return the if it was a case and null if not
2556 Expression SwitchLabel() :
2558 final Expression expr;
2564 } catch (ParseException e) {
2565 if (errorMessage != null) throw e;
2566 errorMessage = "expression expected after 'case' keyword";
2568 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2569 errorEnd = SimpleCharStream.getPosition() + 1;
2575 } catch (ParseException e) {
2576 errorMessage = "':' expected after case expression";
2578 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2579 errorEnd = SimpleCharStream.getPosition() + 1;
2587 } catch (ParseException e) {
2588 errorMessage = "':' expected after 'default' keyword";
2590 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2591 errorEnd = SimpleCharStream.getPosition() + 1;
2596 Break BreakStatement() :
2598 Expression expression = null;
2599 final int start = SimpleCharStream.getPosition();
2602 <BREAK> [ expression = Expression() ]
2605 } catch (ParseException e) {
2606 errorMessage = "';' expected after 'break' keyword";
2608 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2609 errorEnd = SimpleCharStream.getPosition() + 1;
2612 {return new Break(expression, start, SimpleCharStream.getPosition());}
2615 IfStatement IfStatement() :
2617 final int pos = SimpleCharStream.getPosition();
2618 final Expression condition;
2619 final IfStatement ifStatement;
2622 <IF> condition = Condition("if") ifStatement = IfStatement0(condition, pos,pos+2)
2623 {return ifStatement;}
2627 Expression Condition(final String keyword) :
2629 final Expression condition;
2634 } catch (ParseException e) {
2635 errorMessage = "'(' expected after " + keyword + " keyword";
2637 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length();
2638 errorEnd = errorStart +1;
2639 processParseExceptionDebug(e);
2641 condition = Expression()
2644 } catch (ParseException e) {
2645 errorMessage = "')' expected after " + keyword + " keyword";
2647 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2648 errorEnd = SimpleCharStream.getPosition() + 1;
2649 processParseExceptionDebug(e);
2654 IfStatement IfStatement0(final Expression condition, final int start,final int end) :
2656 Statement statement;
2657 final Statement stmt;
2658 final Statement[] statementsArray;
2659 ElseIf elseifStatement;
2660 Else elseStatement = null;
2661 final ArrayList stmts;
2662 final ArrayList elseIfList = new ArrayList();
2663 final ElseIf[] elseIfs;
2664 int pos = SimpleCharStream.getPosition();
2665 final int endStatements;
2669 {stmts = new ArrayList();}
2670 ( statement = Statement() {stmts.add(statement);}
2671 | statement = htmlBlock() {stmts.add(statement);})*
2672 {endStatements = SimpleCharStream.getPosition();}
2673 (elseifStatement = ElseIfStatementColon() {elseIfList.add(elseifStatement);})*
2674 [elseStatement = ElseStatementColon()]
2677 setMarker(fileToParse,
2678 "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
2682 "Line " + token.beginLine);
2683 } catch (CoreException e) {
2684 PHPeclipsePlugin.log(e);
2688 } catch (ParseException e) {
2689 errorMessage = "'endif' expected";
2691 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2692 errorEnd = SimpleCharStream.getPosition() + 1;
2697 } catch (ParseException e) {
2698 errorMessage = "';' expected after 'endif' keyword";
2700 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2701 errorEnd = SimpleCharStream.getPosition() + 1;
2705 elseIfs = new ElseIf[elseIfList.size()];
2706 elseIfList.toArray(elseIfs);
2707 if (stmts.size() == 1) {
2708 return new IfStatement(condition,
2709 (Statement) stmts.get(0),
2713 SimpleCharStream.getPosition());
2715 statementsArray = new Statement[stmts.size()];
2716 stmts.toArray(statementsArray);
2717 return new IfStatement(condition,
2718 new Block(statementsArray,pos,endStatements),
2722 SimpleCharStream.getPosition());
2727 (stmt = Statement() | stmt = htmlBlock())
2728 ( LOOKAHEAD(1) elseifStatement = ElseIfStatement() {elseIfList.add(elseifStatement);})*
2732 {pos = SimpleCharStream.getPosition();}
2733 statement = Statement()
2734 {elseStatement = new Else(statement,pos,SimpleCharStream.getPosition());}
2735 } catch (ParseException e) {
2736 if (errorMessage != null) {
2739 errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected";
2741 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2742 errorEnd = SimpleCharStream.getPosition() + 1;
2747 elseIfs = new ElseIf[elseIfList.size()];
2748 elseIfList.toArray(elseIfs);
2749 return new IfStatement(condition,
2754 SimpleCharStream.getPosition());}
2757 ElseIf ElseIfStatementColon() :
2759 final Expression condition;
2760 Statement statement;
2761 final ArrayList list = new ArrayList();
2762 final int pos = SimpleCharStream.getPosition();
2765 <ELSEIF> condition = Condition("elseif")
2766 <COLON> ( statement = Statement() {list.add(statement);}
2767 | statement = htmlBlock() {list.add(statement);})*
2769 final Statement[] stmtsArray = new Statement[list.size()];
2770 list.toArray(stmtsArray);
2771 return new ElseIf(condition,stmtsArray ,pos,SimpleCharStream.getPosition());}
2774 Else ElseStatementColon() :
2776 Statement statement;
2777 final ArrayList list = new ArrayList();
2778 final int pos = SimpleCharStream.getPosition();
2781 <ELSE> <COLON> ( statement = Statement() {list.add(statement);}
2782 | statement = htmlBlock() {list.add(statement);})*
2784 final Statement[] stmtsArray = new Statement[list.size()];
2785 list.toArray(stmtsArray);
2786 return new Else(stmtsArray,pos,SimpleCharStream.getPosition());}
2789 ElseIf ElseIfStatement() :
2791 final Expression condition;
2792 final Statement statement;
2793 final ArrayList list = new ArrayList();
2794 final int pos = SimpleCharStream.getPosition();
2797 <ELSEIF> condition = Condition("elseif") statement = Statement() {list.add(statement);/*todo:do better*/}
2799 final Statement[] stmtsArray = new Statement[list.size()];
2800 list.toArray(stmtsArray);
2801 return new ElseIf(condition,stmtsArray,pos,SimpleCharStream.getPosition());}
2804 WhileStatement WhileStatement() :
2806 final Expression condition;
2807 final Statement action;
2808 final int pos = SimpleCharStream.getPosition();
2812 condition = Condition("while")
2813 action = WhileStatement0(pos,pos + 5)
2814 {return new WhileStatement(condition,action,pos,SimpleCharStream.getPosition());}
2817 Statement WhileStatement0(final int start, final int end) :
2819 Statement statement;
2820 final ArrayList stmts = new ArrayList();
2821 final int pos = SimpleCharStream.getPosition();
2824 <COLON> (statement = Statement() {stmts.add(statement);})*
2826 setMarker(fileToParse,
2827 "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
2831 "Line " + token.beginLine);
2832 } catch (CoreException e) {
2833 PHPeclipsePlugin.log(e);
2837 } catch (ParseException e) {
2838 errorMessage = "'endwhile' expected";
2840 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2841 errorEnd = SimpleCharStream.getPosition() + 1;
2847 final Statement[] stmtsArray = new Statement[stmts.size()];
2848 stmts.toArray(stmtsArray);
2849 return new Block(stmtsArray,pos,SimpleCharStream.getPosition());}
2850 } catch (ParseException e) {
2851 errorMessage = "';' expected after 'endwhile' keyword";
2853 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2854 errorEnd = SimpleCharStream.getPosition() + 1;
2858 statement = Statement()
2862 DoStatement DoStatement() :
2864 final Statement action;
2865 final Expression condition;
2866 final int pos = SimpleCharStream.getPosition();
2869 <DO> action = Statement() <WHILE> condition = Condition("while")
2872 {return new DoStatement(condition,action,pos,SimpleCharStream.getPosition());}
2873 } catch (ParseException e) {
2874 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2876 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2877 errorEnd = SimpleCharStream.getPosition() + 1;
2882 ForeachStatement ForeachStatement() :
2884 Statement statement;
2885 Expression expression;
2886 final int pos = SimpleCharStream.getPosition();
2887 ArrayVariableDeclaration variable;
2893 } catch (ParseException e) {
2894 errorMessage = "'(' expected after 'foreach' keyword";
2896 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2897 errorEnd = SimpleCharStream.getPosition() + 1;
2901 expression = Expression()
2902 } catch (ParseException e) {
2903 errorMessage = "variable expected";
2905 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2906 errorEnd = SimpleCharStream.getPosition() + 1;
2911 } catch (ParseException e) {
2912 errorMessage = "'as' expected";
2914 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2915 errorEnd = SimpleCharStream.getPosition() + 1;
2919 variable = ArrayVariable()
2920 } catch (ParseException e) {
2921 errorMessage = "variable expected";
2923 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2924 errorEnd = SimpleCharStream.getPosition() + 1;
2929 } catch (ParseException e) {
2930 errorMessage = "')' expected after 'foreach' keyword";
2932 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2933 errorEnd = SimpleCharStream.getPosition() + 1;
2937 statement = Statement()
2938 } catch (ParseException e) {
2939 if (errorMessage != null) throw e;
2940 errorMessage = "statement expected";
2942 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2943 errorEnd = SimpleCharStream.getPosition() + 1;
2946 {return new ForeachStatement(expression,
2950 SimpleCharStream.getPosition());}
2954 ForStatement ForStatement() :
2957 final int pos = SimpleCharStream.getPosition();
2958 Expression[] initializations = null;
2959 Expression condition = null;
2960 Expression[] increments = null;
2962 final ArrayList list = new ArrayList();
2963 final int startBlock, endBlock;
2969 } catch (ParseException e) {
2970 errorMessage = "'(' expected after 'for' keyword";
2972 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2973 errorEnd = SimpleCharStream.getPosition() + 1;
2976 [ initializations = ForInit() ] <SEMICOLON>
2977 [ condition = Expression() ] <SEMICOLON>
2978 [ increments = StatementExpressionList() ] <RPAREN>
2980 action = Statement()
2981 {return new ForStatement(initializations,condition,increments,action,pos,SimpleCharStream.getPosition());}
2984 {startBlock = SimpleCharStream.getPosition();}
2985 (action = Statement() {list.add(action);})*
2988 setMarker(fileToParse,
2989 "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
2991 pos+token.image.length(),
2993 "Line " + token.beginLine);
2994 } catch (CoreException e) {
2995 PHPeclipsePlugin.log(e);
2998 {endBlock = SimpleCharStream.getPosition();}
3001 } catch (ParseException e) {
3002 errorMessage = "'endfor' expected";
3004 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3005 errorEnd = SimpleCharStream.getPosition() + 1;
3011 final Statement[] stmtsArray = new Statement[list.size()];
3012 list.toArray(stmtsArray);
3013 return new ForStatement(initializations,condition,increments,new Block(stmtsArray,startBlock,endBlock),pos,SimpleCharStream.getPosition());}
3014 } catch (ParseException e) {
3015 errorMessage = "';' expected after 'endfor' keyword";
3017 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3018 errorEnd = SimpleCharStream.getPosition() + 1;
3024 Expression[] ForInit() :
3026 final Expression[] exprs;
3029 LOOKAHEAD(LocalVariableDeclaration())
3030 exprs = LocalVariableDeclaration()
3033 exprs = StatementExpressionList()
3037 Expression[] StatementExpressionList() :
3039 final ArrayList list = new ArrayList();
3040 final Expression expr;
3043 expr = StatementExpression() {list.add(expr);}
3044 (<COMMA> StatementExpression() {list.add(expr);})*
3046 final Expression[] exprsArray = new Expression[list.size()];
3047 list.toArray(exprsArray);
3051 Continue ContinueStatement() :
3053 Expression expr = null;
3054 final int pos = SimpleCharStream.getPosition();
3057 <CONTINUE> [ expr = Expression() ]
3060 {return new Continue(expr,pos,SimpleCharStream.getPosition());}
3061 } catch (ParseException e) {
3062 errorMessage = "';' expected after 'continue' statement";
3064 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3065 errorEnd = SimpleCharStream.getPosition() + 1;
3070 ReturnStatement ReturnStatement() :
3072 Expression expr = null;
3073 final int pos = SimpleCharStream.getPosition();
3076 <RETURN> [ expr = Expression() ]
3079 {return new ReturnStatement(expr,pos,SimpleCharStream.getPosition());}
3080 } catch (ParseException e) {
3081 errorMessage = "';' expected after 'return' statement";
3083 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3084 errorEnd = SimpleCharStream.getPosition() + 1;