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
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) :
1045 ConstantIdentifier constant;
1048 token = <DOLLAR_ID> variable = Var(token)
1049 {final StringBuffer buff = new StringBuffer();
1050 buff.append(token.image.substring(1));
1051 buff.append(variable.toStringExpression());
1052 return new Variable(buff.toString(),dollar.sourceStart,variable.sourceEnd);
1055 token = <DOLLAR> variable = Var(token)
1056 {return new Variable(variable,dollar.sourceStart,variable.sourceEnd);}
1058 constant = VariableName()
1059 {return new Variable(constant.name,dollar.sourceStart,constant.sourceEnd);}
1063 * A Variable name (without the $)
1064 * @return a variable name String
1066 ConstantIdentifier VariableName():
1068 final StringBuffer buff;
1071 Expression expression = null;
1073 Token token2 = null;
1077 token = <LBRACE> expression = Expression() token2 = <RBRACE>
1078 {expr = expression.toStringExpression();
1079 buff = new StringBuffer(expr.length()+2);
1083 pos = SimpleCharStream.getPosition();
1084 expr = buff.toString();
1085 return new ConstantIdentifier(expr,
1091 token = <IDENTIFIER>
1092 [<LBRACE> expression = Expression() token2 = <RBRACE>]
1094 if (expression == null) {
1095 return new ConstantIdentifier(token.image,
1099 expr = expression.toStringExpression();
1100 buff = new StringBuffer(token.image.length()+expr.length()+2);
1101 buff.append(token.image);
1105 expr = buff.toString();
1106 return new ConstantIdentifier(expr,
1112 var = VariableName()
1114 return new Variable(var,
1121 return new Variable(token.image,
1127 Expression VariableInitializer() :
1129 final Expression expr;
1130 final Token token, token2;
1136 token2 = <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1137 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1139 token2.sourceStart);}
1141 token2 = <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
1142 {return new PrefixedUnaryExpression(new NumberLiteral(token),
1144 token2.sourceStart);}
1146 expr = ArrayDeclarator()
1149 token = <IDENTIFIER>
1150 {return new ConstantIdentifier(token);}
1153 ArrayVariableDeclaration ArrayVariable() :
1155 final Expression expr,expr2;
1160 <ARRAYASSIGN> expr2 = Expression()
1161 {return new ArrayVariableDeclaration(expr,expr2);}
1163 {return new ArrayVariableDeclaration(expr,SimpleCharStream.getPosition());}
1166 ArrayVariableDeclaration[] ArrayInitializer() :
1168 ArrayVariableDeclaration expr;
1169 final ArrayList list = new ArrayList();
1174 expr = ArrayVariable()
1176 ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
1181 <COMMA> {list.add(null);}
1185 final ArrayVariableDeclaration[] vars = new ArrayVariableDeclaration[list.size()];
1191 * A Method Declaration.
1192 * <b>function</b> MetodDeclarator() Block()
1194 MethodDeclaration MethodDeclaration() :
1196 final MethodDeclaration functionDeclaration;
1198 final OutlineableWithChildren seg = currentSegment;
1204 functionDeclaration = MethodDeclarator(token.sourceStart)
1205 {outlineInfo.addVariable(new String(functionDeclaration.name));}
1206 } catch (ParseException e) {
1207 if (errorMessage != null) throw e;
1208 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1210 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1211 errorEnd = SimpleCharStream.getPosition() + 1;
1214 {currentSegment = functionDeclaration;}
1216 {functionDeclaration.statements = block.statements;
1217 currentSegment = seg;
1218 return functionDeclaration;}
1222 * A MethodDeclarator.
1223 * [&] IDENTIFIER(parameters ...).
1224 * @return a function description for the outline
1226 MethodDeclaration MethodDeclarator(final int start) :
1228 Token identifier = null;
1229 Token reference = null;
1230 final Hashtable formalParameters = new Hashtable();
1231 String identifierChar = SYNTAX_ERROR_CHAR;
1235 [reference = <BIT_AND>]
1237 identifier = <IDENTIFIER>
1238 {identifierChar = identifier.image;}
1239 } catch (ParseException e) {
1240 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
1242 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1243 errorEnd = SimpleCharStream.getPosition() + 1;
1244 processParseExceptionDebug(e);
1246 end = FormalParameters(formalParameters)
1248 int nameStart, nameEnd;
1249 if (identifier == null) {
1250 if (reference == null) {
1251 nameStart = start + 9;
1252 nameEnd = start + 10;
1254 nameStart = reference.sourceEnd + 1;
1255 nameEnd = reference.sourceEnd + 2;
1258 nameStart = identifier.sourceStart;
1259 nameEnd = identifier.sourceEnd;
1261 return new MethodDeclaration(currentSegment,
1273 * FormalParameters follows method identifier.
1274 * (FormalParameter())
1276 int FormalParameters(final Hashtable parameters) :
1278 VariableDeclaration var;
1285 } catch (ParseException e) {
1286 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected after function identifier";
1288 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1289 errorEnd = SimpleCharStream.getPosition() + 1;
1290 processParseExceptionDebug(e);
1293 var = FormalParameter()
1294 {parameters.put(new String(var.name()),var);}
1296 <COMMA> var = FormalParameter()
1297 {parameters.put(new String(var.name()),var);}
1302 {end = token.sourceEnd;}
1303 } catch (ParseException e) {
1304 errorMessage = "')' expected";
1306 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1307 errorEnd = SimpleCharStream.getPosition() + 1;
1308 processParseExceptionDebug(e);
1309 end = e.currentToken.sourceStart;
1315 * A formal parameter.
1316 * $varname[=value] (,$varname[=value])
1318 VariableDeclaration FormalParameter() :
1320 final VariableDeclaration variableDeclaration;
1324 [token = <BIT_AND>] variableDeclaration = VariableDeclaratorNoSuffix()
1326 if (token != null) {
1327 variableDeclaration.setReference(true);
1329 return variableDeclaration;}
1332 ConstantIdentifier Type() :
1333 {final Token token;}
1335 token = <STRING> {return new ConstantIdentifier(token);}
1336 | token = <BOOL> {return new ConstantIdentifier(token);}
1337 | token = <BOOLEAN> {return new ConstantIdentifier(token);}
1338 | token = <REAL> {return new ConstantIdentifier(token);}
1339 | token = <DOUBLE> {return new ConstantIdentifier(token);}
1340 | token = <FLOAT> {return new ConstantIdentifier(token);}
1341 | token = <INT> {return new ConstantIdentifier(token);}
1342 | token = <INTEGER> {return new ConstantIdentifier(token);}
1343 | token = <OBJECT> {return new ConstantIdentifier(token);}
1346 Expression Expression() :
1348 final Expression expr;
1349 Expression initializer = null;
1350 int assignOperator = -1;
1354 expr = ConditionalExpression()
1356 assignOperator = AssignmentOperator()
1358 initializer = Expression()
1359 } catch (ParseException e) {
1360 if (errorMessage != null) {
1363 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1365 errorEnd = SimpleCharStream.getPosition();
1370 if (assignOperator != -1) {// todo : change this, very very bad :(
1371 if (expr instanceof AbstractVariable) {
1372 return new VariableDeclaration(currentSegment,
1373 (AbstractVariable) expr,
1376 initializer.sourceEnd);
1378 String varName = expr.toStringExpression().substring(1);
1379 return new VariableDeclaration(currentSegment,
1380 new Variable(varName,
1384 initializer.sourceEnd);
1388 | expr = ExpressionWBang() {return expr;}
1391 Expression ExpressionWBang() :
1393 final Expression expr;
1397 token = <BANG> expr = ExpressionWBang()
1398 {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,token.sourceStart);}
1399 | expr = ExpressionNoBang() {return expr;}
1402 Expression ExpressionNoBang() :
1407 expr = ListExpression() {return expr;}
1409 expr = PrintExpression() {return expr;}
1413 * Any assignement operator.
1414 * @return the assignement operator id
1416 int AssignmentOperator() :
1419 <ASSIGN> {return VariableDeclaration.EQUAL;}
1420 | <STARASSIGN> {return VariableDeclaration.STAR_EQUAL;}
1421 | <SLASHASSIGN> {return VariableDeclaration.SLASH_EQUAL;}
1422 | <REMASSIGN> {return VariableDeclaration.REM_EQUAL;}
1423 | <PLUSASSIGN> {return VariableDeclaration.PLUS_EQUAL;}
1424 | <MINUSASSIGN> {return VariableDeclaration.MINUS_EQUAL;}
1425 | <LSHIFTASSIGN> {return VariableDeclaration.LSHIFT_EQUAL;}
1426 | <RSIGNEDSHIFTASSIGN> {return VariableDeclaration.RSIGNEDSHIFT_EQUAL;}
1427 | <ANDASSIGN> {return VariableDeclaration.AND_EQUAL;}
1428 | <XORASSIGN> {return VariableDeclaration.XOR_EQUAL;}
1429 | <ORASSIGN> {return VariableDeclaration.OR_EQUAL;}
1430 | <DOTASSIGN> {return VariableDeclaration.DOT_EQUAL;}
1431 | <TILDEEQUAL> {return VariableDeclaration.TILDE_EQUAL;}
1434 Expression ConditionalExpression() :
1436 final Expression expr;
1437 Expression expr2 = null;
1438 Expression expr3 = null;
1441 expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
1443 if (expr3 == null) {
1446 return new ConditionalExpression(expr,expr2,expr3);
1450 Expression ConditionalOrExpression() :
1452 Expression expr,expr2;
1456 expr = ConditionalAndExpression()
1459 <OR_OR> {operator = OperatorIds.OR_OR;}
1460 | <_ORL> {operator = OperatorIds.ORL;}
1462 expr2 = ConditionalAndExpression()
1464 expr = new BinaryExpression(expr,expr2,operator);
1470 Expression ConditionalAndExpression() :
1472 Expression expr,expr2;
1476 expr = ConcatExpression()
1478 ( <AND_AND> {operator = OperatorIds.AND_AND;}
1479 | <_ANDL> {operator = OperatorIds.ANDL;})
1480 expr2 = ConcatExpression() {expr = new BinaryExpression(expr,expr2,operator);}
1485 Expression ConcatExpression() :
1487 Expression expr,expr2;
1490 expr = InclusiveOrExpression()
1492 <DOT> expr2 = InclusiveOrExpression()
1493 {expr = new BinaryExpression(expr,expr2,OperatorIds.DOT);}
1498 Expression InclusiveOrExpression() :
1500 Expression expr,expr2;
1503 expr = ExclusiveOrExpression()
1504 (<BIT_OR> expr2 = ExclusiveOrExpression()
1505 {expr = new BinaryExpression(expr,expr2,OperatorIds.OR);}
1510 Expression ExclusiveOrExpression() :
1512 Expression expr,expr2;
1515 expr = AndExpression()
1517 <XOR> expr2 = AndExpression()
1518 {expr = new BinaryExpression(expr,expr2,OperatorIds.XOR);}
1523 Expression AndExpression() :
1525 Expression expr,expr2;
1528 expr = EqualityExpression()
1531 <BIT_AND> expr2 = EqualityExpression()
1532 {expr = new BinaryExpression(expr,expr2,OperatorIds.AND);}
1537 Expression EqualityExpression() :
1539 Expression expr,expr2;
1543 expr = RelationalExpression()
1545 ( <EQUAL_EQUAL> {operator = OperatorIds.EQUAL_EQUAL;}
1546 | <DIF> {operator = OperatorIds.DIF;}
1547 | <NOT_EQUAL> {operator = OperatorIds.DIF;}
1548 | <BANGDOUBLEEQUAL> {operator = OperatorIds.BANG_EQUAL_EQUAL;}
1549 | <TRIPLEEQUAL> {operator = OperatorIds.EQUAL_EQUAL_EQUAL;}
1552 expr2 = RelationalExpression()
1553 } catch (ParseException e) {
1554 if (errorMessage != null) {
1557 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
1559 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1560 errorEnd = SimpleCharStream.getPosition() + 1;
1564 expr = new BinaryExpression(expr,expr2,operator);
1570 Expression RelationalExpression() :
1572 Expression expr,expr2;
1576 expr = ShiftExpression()
1578 ( <LT> {operator = OperatorIds.LESS;}
1579 | <GT> {operator = OperatorIds.GREATER;}
1580 | <LE> {operator = OperatorIds.LESS_EQUAL;}
1581 | <GE> {operator = OperatorIds.GREATER_EQUAL;})
1582 expr2 = ShiftExpression()
1583 {expr = new BinaryExpression(expr,expr2,operator);}
1588 Expression ShiftExpression() :
1590 Expression expr,expr2;
1594 expr = AdditiveExpression()
1596 ( <LSHIFT> {operator = OperatorIds.LEFT_SHIFT;}
1597 | <RSIGNEDSHIFT> {operator = OperatorIds.RIGHT_SHIFT;}
1598 | <RUNSIGNEDSHIFT> {operator = OperatorIds.UNSIGNED_RIGHT_SHIFT;})
1599 expr2 = AdditiveExpression()
1600 {expr = new BinaryExpression(expr,expr2,operator);}
1605 Expression AdditiveExpression() :
1607 Expression expr,expr2;
1611 expr = MultiplicativeExpression()
1614 ( <PLUS> {operator = OperatorIds.PLUS;}
1615 | <MINUS> {operator = OperatorIds.MINUS;}
1617 expr2 = MultiplicativeExpression()
1618 {expr = new BinaryExpression(expr,expr2,operator);}
1623 Expression MultiplicativeExpression() :
1625 Expression expr,expr2;
1630 expr = UnaryExpression()
1631 } catch (ParseException e) {
1632 if (errorMessage != null) throw e;
1633 errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
1635 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1636 errorEnd = SimpleCharStream.getPosition() + 1;
1640 ( <STAR> {operator = OperatorIds.MULTIPLY;}
1641 | <SLASH> {operator = OperatorIds.DIVIDE;}
1642 | <REMAINDER> {operator = OperatorIds.REMAINDER;})
1643 expr2 = UnaryExpression()
1644 {expr = new BinaryExpression(expr,expr2,operator);}
1650 * An unary expression starting with @, & or nothing
1652 Expression UnaryExpression() :
1654 final Expression expr;
1657 /* <BIT_AND> expr = UnaryExpressionNoPrefix() //why did I had that ?
1658 {return new PrefixedUnaryExpression(expr,OperatorIds.AND,pos);}
1660 expr = AtNotUnaryExpression() {return expr;}
1664 * An expression prefixed (or not) by one or more @ and !.
1665 * @return the expression
1667 Expression AtNotUnaryExpression() :
1669 final Expression expr;
1674 expr = AtNotUnaryExpression()
1675 {return new PrefixedUnaryExpression(expr,OperatorIds.AT,token.sourceStart);}
1678 expr = AtNotUnaryExpression()
1679 {return new PrefixedUnaryExpression(expr,OperatorIds.NOT,token.sourceStart);}
1681 expr = UnaryExpressionNoPrefix()
1686 Expression UnaryExpressionNoPrefix() :
1688 final Expression expr;
1692 token = <PLUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,
1694 token.sourceStart);}
1696 token = <MINUS> expr = AtNotUnaryExpression() {return new PrefixedUnaryExpression(expr,
1698 token.sourceStart);}
1700 expr = PreIncDecExpression()
1703 expr = UnaryExpressionNotPlusMinus()
1708 Expression PreIncDecExpression() :
1710 final Expression expr;
1716 token = <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1718 token = <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1720 expr = PrimaryExpression()
1721 {return new PrefixedUnaryExpression(expr,operator,token.sourceStart);}
1724 Expression UnaryExpressionNotPlusMinus() :
1726 final Expression expr;
1729 LOOKAHEAD( <LPAREN> (Type() | <ARRAY>) <RPAREN> )
1730 expr = CastExpression() {return expr;}
1731 | expr = PostfixExpression() {return expr;}
1732 | expr = Literal() {return expr;}
1733 | <LPAREN> expr = Expression()
1736 } catch (ParseException e) {
1737 errorMessage = "')' expected";
1739 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1740 errorEnd = SimpleCharStream.getPosition() + 1;
1746 CastExpression CastExpression() :
1748 final ConstantIdentifier type;
1749 final Expression expr;
1750 final Token token,token1;
1757 token = <ARRAY> {type = new ConstantIdentifier(token);}
1759 <RPAREN> expr = UnaryExpression()
1760 {return new CastExpression(type,expr,token1.sourceStart,expr.sourceEnd);}
1763 Expression PostfixExpression() :
1765 final Expression expr;
1770 expr = PrimaryExpression()
1772 token = <PLUS_PLUS> {operator = OperatorIds.PLUS_PLUS;}
1774 token = <MINUS_MINUS> {operator = OperatorIds.MINUS_MINUS;}
1777 if (operator == -1) {
1780 return new PostfixedUnaryExpression(expr,operator,token.sourceEnd);
1784 Expression PrimaryExpression() :
1786 Expression expr = null;
1790 [token = <BIT_AND>] expr = refPrimaryExpression(token)
1793 expr = ArrayDeclarator()
1797 Expression refPrimaryExpression(final Token reference) :
1799 Expression expr = null;
1800 Expression expr2 = null;
1801 int assignOperator = -1;
1802 final Token identifier;
1806 identifier = <IDENTIFIER>
1808 expr = new ConstantIdentifier(identifier);
1811 <STATICCLASSACCESS> expr2 = ClassIdentifier()
1812 {expr = new ClassAccess(expr,
1814 ClassAccess.STATIC);}
1816 [ expr2 = Arguments(expr) ]
1818 if (expr2 == null) {
1819 if (reference != null) {
1820 ParseException e = generateParseException();
1821 errorMessage = "you cannot use a constant by reference";
1823 errorStart = reference.sourceStart;
1824 errorEnd = reference.sourceEnd;
1825 processParseExceptionDebug(e);
1832 expr = VariableDeclaratorId() //todo use the reference parameter ...
1833 [ expr = Arguments(expr) ]
1837 expr = ClassIdentifier()
1840 if (reference == null) {
1841 start = token.sourceStart;
1843 start = reference.sourceStart;
1845 expr = new ClassInstantiation(expr,
1849 [ expr = Arguments(expr) ]
1854 * An array declarator.
1858 ArrayInitializer ArrayDeclarator() :
1860 final ArrayVariableDeclaration[] vars;
1864 token = <ARRAY> vars = ArrayInitializer()
1865 {return new ArrayInitializer(vars,token.sourceStart,SimpleCharStream.getPosition());}
1868 Expression ClassIdentifier():
1870 final Expression expr;
1872 final ConstantIdentifier type;
1875 token = <IDENTIFIER> {return new ConstantIdentifier(token);}
1876 | expr = Type() {return expr;}
1877 | expr = VariableDeclaratorId() {return expr;}
1881 * Used by Variabledeclaratorid and primarysuffix
1883 AbstractVariable VariableSuffix(final AbstractVariable prefix) :
1885 Variable expr = null;
1886 final int pos = SimpleCharStream.getPosition();
1887 Expression expression = null;
1892 expression = VariableName()
1893 } catch (ParseException e) {
1894 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
1896 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1897 errorEnd = SimpleCharStream.getPosition() + 1;
1900 {return new ClassAccess(prefix,
1902 ClassAccess.NORMAL);}
1904 <LBRACKET> [ expression = Expression() | expression = Type() ] //Not good
1907 } catch (ParseException e) {
1908 errorMessage = "']' expected";
1910 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1911 errorEnd = SimpleCharStream.getPosition() + 1;
1914 {return new ArrayDeclarator(prefix,expression,SimpleCharStream.getPosition());}
1922 token = <INTEGER_LITERAL> {return new NumberLiteral(token);}
1923 | token = <FLOATING_POINT_LITERAL> {return new NumberLiteral(token);}
1924 | token = <STRING_LITERAL> {return new StringLiteral(token);}
1925 | token = <TRUE> {return new TrueLiteral(token);}
1926 | token = <FALSE> {return new FalseLiteral(token);}
1927 | token = <NULL> {return new NullLiteral(token);}
1930 FunctionCall Arguments(final Expression func) :
1932 Expression[] args = null;
1936 <LPAREN> [ args = ArgumentList() ]
1939 } catch (ParseException e) {
1940 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
1942 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1943 errorEnd = SimpleCharStream.getPosition() + 1;
1946 {return new FunctionCall(func,args,token.sourceEnd);}
1950 * An argument list is a list of arguments separated by comma :
1951 * argumentDeclaration() (, argumentDeclaration)*
1952 * @return an array of arguments
1954 Expression[] ArgumentList() :
1957 final ArrayList list = new ArrayList();
1966 } catch (ParseException e) {
1967 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. An expression expected after a comma in argument list";
1969 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
1970 errorEnd = SimpleCharStream.getPosition() + 1;
1975 final Expression[] arguments = new Expression[list.size()];
1976 list.toArray(arguments);
1981 * A Statement without break.
1982 * @return a statement
1984 Statement StatementNoBreak() :
1986 final Statement statement;
1991 statement = expressionStatement() {return statement;}
1993 statement = LabeledStatement() {return statement;}
1994 | statement = Block() {return statement;}
1995 | statement = EmptyStatement() {return statement;}
1996 | statement = SwitchStatement() {return statement;}
1997 | statement = IfStatement() {return statement;}
1998 | statement = WhileStatement() {return statement;}
1999 | statement = DoStatement() {return statement;}
2000 | statement = ForStatement() {return statement;}
2001 | statement = ForeachStatement() {return statement;}
2002 | statement = ContinueStatement() {return statement;}
2003 | statement = ReturnStatement() {return statement;}
2004 | statement = EchoStatement() {return statement;}
2005 | [token=<AT>] statement = IncludeStatement()
2006 {if (token != null) {
2007 ((InclusionStatement)statement).silent = true;
2008 statement.sourceStart = token.sourceStart;
2011 | statement = StaticStatement() {return statement;}
2012 | statement = GlobalStatement() {return statement;}
2013 | statement = defineStatement() {currentSegment.add((Outlineable)statement);return statement;}
2017 * A statement expression.
2019 * @return an expression
2021 Statement expressionStatement() :
2023 final Statement statement;
2027 statement = Expression()
2030 {statement.sourceEnd = token.sourceEnd;}
2031 } catch (ParseException e) {
2032 if (e.currentToken.next.kind != PHPParserConstants.PHPEND) {
2033 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2035 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2036 errorEnd = SimpleCharStream.getPosition() + 1;
2043 Define defineStatement() :
2045 final int start = SimpleCharStream.getPosition();
2046 Expression defineName,defineValue;
2052 } catch (ParseException e) {
2053 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
2055 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2056 errorEnd = SimpleCharStream.getPosition() + 1;
2057 processParseExceptionDebug(e);
2060 defineName = Expression()
2061 } catch (ParseException e) {
2062 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
2064 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2065 errorEnd = SimpleCharStream.getPosition() + 1;
2070 } catch (ParseException e) {
2071 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
2073 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2074 errorEnd = SimpleCharStream.getPosition() + 1;
2075 processParseExceptionDebug(e);
2078 defineValue = Expression()
2079 } catch (ParseException e) {
2080 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected";
2082 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2083 errorEnd = SimpleCharStream.getPosition() + 1;
2088 } catch (ParseException e) {
2089 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2091 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2092 errorEnd = SimpleCharStream.getPosition() + 1;
2093 processParseExceptionDebug(e);
2095 {return new Define(currentSegment,
2099 SimpleCharStream.getPosition());}
2103 * A Normal statement.
2105 Statement Statement() :
2107 final Statement statement;
2110 statement = StatementNoBreak() {return statement;}
2111 | statement = BreakStatement() {return statement;}
2115 * An html block inside a php syntax.
2117 HTMLBlock htmlBlock() :
2119 final int startIndex = nodePtr;
2120 final AstNode[] blockNodes;
2124 <PHPEND> (phpEchoBlock())*
2126 (<PHPSTARTLONG> | <PHPSTARTSHORT>)
2127 } catch (ParseException e) {
2128 errorMessage = "unexpected end of file , '<?php' expected";
2130 errorStart = SimpleCharStream.getPosition();
2131 errorEnd = SimpleCharStream.getPosition();
2135 nbNodes = nodePtr - startIndex;
2136 blockNodes = new AstNode[nbNodes];
2137 System.arraycopy(nodes,startIndex,blockNodes,0,nbNodes);
2138 nodePtr = startIndex;
2139 return new HTMLBlock(blockNodes);}
2143 * An include statement. It's "include" an expression;
2145 InclusionStatement IncludeStatement() :
2147 final Expression expr;
2149 final InclusionStatement inclusionStatement;
2150 final Token token, token2;
2153 ( token = <REQUIRE> {keyword = InclusionStatement.REQUIRE;}
2154 | token = <REQUIRE_ONCE> {keyword = InclusionStatement.REQUIRE_ONCE;}
2155 | token = <INCLUDE> {keyword = InclusionStatement.INCLUDE;}
2156 | token = <INCLUDE_ONCE> {keyword = InclusionStatement.INCLUDE_ONCE;})
2159 } catch (ParseException e) {
2160 if (errorMessage != null) {
2163 errorMessage = "unexpected token '"+ e.currentToken.next.image+"', expression expected";
2165 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2166 errorEnd = SimpleCharStream.getPosition() + 1;
2169 {inclusionStatement = new InclusionStatement(currentSegment,
2173 currentSegment.add(inclusionStatement);
2176 token2 = <SEMICOLON>
2177 } catch (ParseException e) {
2178 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2180 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2181 errorEnd = SimpleCharStream.getPosition() + 1;
2184 {inclusionStatement.sourceEnd = token2.sourceEnd;
2185 return inclusionStatement;}
2188 PrintExpression PrintExpression() :
2190 final Expression expr;
2191 final int pos = SimpleCharStream.getPosition();
2194 <PRINT> expr = Expression() {return new PrintExpression(expr,pos,SimpleCharStream.getPosition());}
2197 ListExpression ListExpression() :
2199 Expression expr = null;
2200 final Expression expression;
2201 final ArrayList list = new ArrayList();
2202 final int pos = SimpleCharStream.getPosition();
2208 } catch (ParseException e) {
2209 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
2211 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2212 errorEnd = SimpleCharStream.getPosition() + 1;
2216 expr = VariableDeclaratorId()
2219 {if (expr == null) list.add(null);}
2223 } catch (ParseException e) {
2224 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
2226 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2227 errorEnd = SimpleCharStream.getPosition() + 1;
2230 [expr = VariableDeclaratorId() {list.add(expr);}]
2234 } catch (ParseException e) {
2235 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
2237 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2238 errorEnd = SimpleCharStream.getPosition() + 1;
2241 [ <ASSIGN> expression = Expression()
2243 final Variable[] vars = new Variable[list.size()];
2245 return new ListExpression(vars,
2248 SimpleCharStream.getPosition());}
2251 final Variable[] vars = new Variable[list.size()];
2253 return new ListExpression(vars,pos,SimpleCharStream.getPosition());}
2257 * An echo statement.
2258 * echo anyexpression (, otherexpression)*
2260 EchoStatement EchoStatement() :
2262 final ArrayList expressions = new ArrayList();
2265 Token token2 = null;
2268 token = <ECHO> expr = Expression()
2269 {expressions.add(expr);}
2271 <COMMA> expr = Expression()
2272 {expressions.add(expr);}
2275 token2 = <SEMICOLON>
2276 } catch (ParseException e) {
2277 if (e.currentToken.next.kind != 4) {
2278 errorMessage = "';' expected after 'echo' statement";
2280 errorStart = e.currentToken.sourceEnd;
2281 errorEnd = e.currentToken.sourceEnd;
2282 processParseExceptionDebug(e);
2286 final Expression[] exprs = new Expression[expressions.size()];
2287 expressions.toArray(exprs);
2288 if (token2 == null) {
2289 return new EchoStatement(exprs,token.sourceStart, exprs[exprs.length-1].sourceEnd);
2291 return new EchoStatement(exprs,token.sourceStart, token2.sourceEnd);
2295 GlobalStatement GlobalStatement() :
2298 final ArrayList vars = new ArrayList();
2299 final GlobalStatement global;
2300 final Token token, token2;
2311 token2 = <SEMICOLON>
2313 final Variable[] variables = new Variable[vars.size()];
2314 vars.toArray(variables);
2315 global = new GlobalStatement(currentSegment,
2319 currentSegment.add(global);
2321 } catch (ParseException e) {
2322 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2324 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2325 errorEnd = SimpleCharStream.getPosition() + 1;
2330 StaticStatement StaticStatement() :
2332 final ArrayList vars = new ArrayList();
2333 VariableDeclaration expr;
2334 final Token token, token2;
2337 token = <STATIC> expr = VariableDeclarator() {vars.add(expr);}
2339 <COMMA> expr = VariableDeclarator() {vars.add(expr);}
2342 token2 = <SEMICOLON>
2344 final VariableDeclaration[] variables = new VariableDeclaration[vars.size()];
2345 vars.toArray(variables);
2346 return new StaticStatement(variables,
2349 } catch (ParseException e) {
2350 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. a ';' was expected";
2352 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2353 errorEnd = SimpleCharStream.getPosition() + 1;
2358 LabeledStatement LabeledStatement() :
2361 final Statement statement;
2364 label = <IDENTIFIER> <COLON> statement = Statement()
2365 {return new LabeledStatement(label.image,statement,label.sourceStart,statement.sourceEnd);}
2377 final ArrayList list = new ArrayList();
2378 Statement statement;
2379 final Token token, token2;
2384 } catch (ParseException e) {
2385 errorMessage = "'{' expected";
2387 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2388 errorEnd = SimpleCharStream.getPosition() + 1;
2391 ( statement = BlockStatement() {list.add(statement);}
2392 | statement = htmlBlock() {list.add(statement);})*
2395 } catch (ParseException e) {
2396 errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
2398 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2399 errorEnd = SimpleCharStream.getPosition() + 1;
2403 final Statement[] statements = new Statement[list.size()];
2404 list.toArray(statements);
2405 return new Block(statements,token.sourceStart,token2.sourceEnd);}
2408 Statement BlockStatement() :
2410 final Statement statement;
2414 statement = Statement() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2416 } catch (ParseException e) {
2417 errorMessage = "unexpected token : '"+ e.currentToken.image +"', a statement was expected";
2419 errorStart = e.currentToken.sourceStart;
2420 errorEnd = e.currentToken.sourceEnd;
2423 | statement = ClassDeclaration() {return statement;}
2424 | statement = MethodDeclaration() {if (phpDocument == currentSegment) pushOnAstNodes(statement);
2425 currentSegment.add((MethodDeclaration) statement);
2426 ((MethodDeclaration) statement).analyzeCode();
2431 * A Block statement that will not contain any 'break'
2433 Statement BlockStatementNoBreak() :
2435 final Statement statement;
2438 statement = StatementNoBreak() {return statement;}
2439 | statement = ClassDeclaration() {return statement;}
2440 | statement = MethodDeclaration() {currentSegment.add((MethodDeclaration) statement);
2441 ((MethodDeclaration) statement).analyzeCode();
2446 * used only by ForInit()
2448 VariableDeclaration[] LocalVariableDeclaration() :
2450 final ArrayList list = new ArrayList();
2451 VariableDeclaration var;
2454 var = LocalVariableDeclarator()
2456 ( <COMMA> var = LocalVariableDeclarator() {list.add(var);})*
2458 final VariableDeclaration[] vars = new VariableDeclaration[list.size()];
2464 * used only by LocalVariableDeclaration().
2466 VariableDeclaration LocalVariableDeclarator() :
2468 final Variable varName;
2469 Expression initializer = null;
2472 varName = Variable() [ <ASSIGN> initializer = Expression() ]
2474 if (initializer == null) {
2475 return new VariableDeclaration(currentSegment,
2477 varName.sourceStart,
2480 return new VariableDeclaration(currentSegment,
2483 VariableDeclaration.EQUAL,
2484 varName.sourceStart);
2488 EmptyStatement EmptyStatement() :
2494 {return new EmptyStatement(token.sourceStart,token.sourceEnd);}
2498 * used only by StatementExpressionList() which is used only by ForInit() and ForStatement()
2500 Expression StatementExpression() :
2502 final Expression expr,expr2;
2506 expr = PreIncDecExpression() {return expr;}
2508 expr = PrimaryExpression()
2509 [ <PLUS_PLUS> {return new PostfixedUnaryExpression(expr,
2510 OperatorIds.PLUS_PLUS,
2511 SimpleCharStream.getPosition());}
2512 | <MINUS_MINUS> {return new PostfixedUnaryExpression(expr,
2513 OperatorIds.MINUS_MINUS,
2514 SimpleCharStream.getPosition());}
2519 SwitchStatement SwitchStatement() :
2521 final Expression variable;
2522 final AbstractCase[] cases;
2523 final int pos = SimpleCharStream.getPosition();
2529 } catch (ParseException e) {
2530 errorMessage = "'(' expected after 'switch'";
2532 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2533 errorEnd = SimpleCharStream.getPosition() + 1;
2537 variable = Expression()
2538 } catch (ParseException e) {
2539 if (errorMessage != null) {
2542 errorMessage = "expression expected";
2544 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2545 errorEnd = SimpleCharStream.getPosition() + 1;
2550 } catch (ParseException e) {
2551 errorMessage = "')' expected";
2553 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2554 errorEnd = SimpleCharStream.getPosition() + 1;
2557 (cases = switchStatementBrace() | cases = switchStatementColon(pos, pos + 6))
2558 {return new SwitchStatement(variable,cases,pos,SimpleCharStream.getPosition());}
2561 AbstractCase[] switchStatementBrace() :
2564 final ArrayList cases = new ArrayList();
2568 ( cas = switchLabel0() {cases.add(cas);})*
2572 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2573 cases.toArray(abcase);
2575 } catch (ParseException e) {
2576 errorMessage = "'}' expected";
2578 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2579 errorEnd = SimpleCharStream.getPosition() + 1;
2584 * A Switch statement with : ... endswitch;
2585 * @param start the begin offset of the switch
2586 * @param end the end offset of the switch
2588 AbstractCase[] switchStatementColon(final int start, final int end) :
2591 final ArrayList cases = new ArrayList();
2596 setMarker(fileToParse,
2597 "Ugly syntax detected, you should switch () {...} instead of switch (): ... enswitch;",
2601 "Line " + token.beginLine);
2602 } catch (CoreException e) {
2603 PHPeclipsePlugin.log(e);
2605 ( cas = switchLabel0() {cases.add(cas);})*
2608 } catch (ParseException e) {
2609 errorMessage = "'endswitch' expected";
2611 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2612 errorEnd = SimpleCharStream.getPosition() + 1;
2618 final AbstractCase[] abcase = new AbstractCase[cases.size()];
2619 cases.toArray(abcase);
2621 } catch (ParseException e) {
2622 errorMessage = "';' expected after 'endswitch' keyword";
2624 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2625 errorEnd = SimpleCharStream.getPosition() + 1;
2630 AbstractCase switchLabel0() :
2632 final Expression expr;
2633 Statement statement;
2634 final ArrayList stmts = new ArrayList();
2635 final int pos = SimpleCharStream.getPosition();
2638 expr = SwitchLabel()
2639 ( statement = BlockStatementNoBreak() {stmts.add(statement);}
2640 | statement = htmlBlock() {stmts.add(statement);})*
2641 [ statement = BreakStatement() {stmts.add(statement);}]
2643 final Statement[] stmtsArray = new Statement[stmts.size()];
2644 stmts.toArray(stmtsArray);
2645 if (expr == null) {//it's a default
2646 return new DefaultCase(stmtsArray,pos,SimpleCharStream.getPosition());
2648 return new Case(expr,stmtsArray,pos,SimpleCharStream.getPosition());}
2653 * case Expression() :
2655 * @return the if it was a case and null if not
2657 Expression SwitchLabel() :
2659 final Expression expr;
2665 } catch (ParseException e) {
2666 if (errorMessage != null) throw e;
2667 errorMessage = "expression expected after 'case' keyword";
2669 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2670 errorEnd = SimpleCharStream.getPosition() + 1;
2676 } catch (ParseException e) {
2677 errorMessage = "':' expected after case expression";
2679 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2680 errorEnd = SimpleCharStream.getPosition() + 1;
2688 } catch (ParseException e) {
2689 errorMessage = "':' expected after 'default' keyword";
2691 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2692 errorEnd = SimpleCharStream.getPosition() + 1;
2697 Break BreakStatement() :
2699 Expression expression = null;
2700 final Token token, token2;
2703 token = <BREAK> [ expression = Expression() ]
2705 token2 = <SEMICOLON>
2706 } catch (ParseException e) {
2707 errorMessage = "';' expected after 'break' keyword";
2709 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2710 errorEnd = SimpleCharStream.getPosition() + 1;
2713 {return new Break(expression, token.sourceStart, token2.sourceEnd);}
2716 IfStatement IfStatement() :
2718 final int pos = SimpleCharStream.getPosition();
2719 final Expression condition;
2720 final IfStatement ifStatement;
2724 token = <IF> condition = Condition("if") ifStatement = IfStatement0(condition,
2725 token.sourceStart,token.sourceStart+2)
2726 {return ifStatement;}
2730 Expression Condition(final String keyword) :
2732 final Expression condition;
2737 } catch (ParseException e) {
2738 errorMessage = "'(' expected after " + keyword + " keyword";
2740 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length();
2741 errorEnd = errorStart +1;
2742 processParseExceptionDebug(e);
2744 condition = Expression()
2747 } catch (ParseException e) {
2748 errorMessage = "')' expected after " + keyword + " keyword";
2750 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2751 errorEnd = SimpleCharStream.getPosition() + 1;
2752 processParseExceptionDebug(e);
2757 IfStatement IfStatement0(final Expression condition, final int start,final int end) :
2759 Statement statement;
2760 final Statement stmt;
2761 final Statement[] statementsArray;
2762 ElseIf elseifStatement;
2763 Else elseStatement = null;
2764 final ArrayList stmts;
2765 final ArrayList elseIfList = new ArrayList();
2766 final ElseIf[] elseIfs;
2767 int pos = SimpleCharStream.getPosition();
2768 final int endStatements;
2772 {stmts = new ArrayList();}
2773 ( statement = Statement() {stmts.add(statement);}
2774 | statement = htmlBlock() {stmts.add(statement);})*
2775 {endStatements = SimpleCharStream.getPosition();}
2776 (elseifStatement = ElseIfStatementColon() {elseIfList.add(elseifStatement);})*
2777 [elseStatement = ElseStatementColon()]
2780 setMarker(fileToParse,
2781 "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
2785 "Line " + token.beginLine);
2786 } catch (CoreException e) {
2787 PHPeclipsePlugin.log(e);
2791 } catch (ParseException e) {
2792 errorMessage = "'endif' expected";
2794 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2795 errorEnd = SimpleCharStream.getPosition() + 1;
2800 } catch (ParseException e) {
2801 errorMessage = "';' expected after 'endif' keyword";
2803 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2804 errorEnd = SimpleCharStream.getPosition() + 1;
2808 elseIfs = new ElseIf[elseIfList.size()];
2809 elseIfList.toArray(elseIfs);
2810 if (stmts.size() == 1) {
2811 return new IfStatement(condition,
2812 (Statement) stmts.get(0),
2816 SimpleCharStream.getPosition());
2818 statementsArray = new Statement[stmts.size()];
2819 stmts.toArray(statementsArray);
2820 return new IfStatement(condition,
2821 new Block(statementsArray,pos,endStatements),
2825 SimpleCharStream.getPosition());
2830 (stmt = Statement() | stmt = htmlBlock())
2831 ( LOOKAHEAD(1) elseifStatement = ElseIfStatement() {elseIfList.add(elseifStatement);})*
2835 {pos = SimpleCharStream.getPosition();}
2836 statement = Statement()
2837 {elseStatement = new Else(statement,pos,SimpleCharStream.getPosition());}
2838 } catch (ParseException e) {
2839 if (errorMessage != null) {
2842 errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected";
2844 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2845 errorEnd = SimpleCharStream.getPosition() + 1;
2850 elseIfs = new ElseIf[elseIfList.size()];
2851 elseIfList.toArray(elseIfs);
2852 return new IfStatement(condition,
2857 SimpleCharStream.getPosition());}
2860 ElseIf ElseIfStatementColon() :
2862 final Expression condition;
2863 Statement statement;
2864 final ArrayList list = new ArrayList();
2865 final int pos = SimpleCharStream.getPosition();
2868 <ELSEIF> condition = Condition("elseif")
2869 <COLON> ( statement = Statement() {list.add(statement);}
2870 | statement = htmlBlock() {list.add(statement);})*
2872 final Statement[] stmtsArray = new Statement[list.size()];
2873 list.toArray(stmtsArray);
2874 return new ElseIf(condition,stmtsArray ,pos,SimpleCharStream.getPosition());}
2877 Else ElseStatementColon() :
2879 Statement statement;
2880 final ArrayList list = new ArrayList();
2881 final int pos = SimpleCharStream.getPosition();
2884 <ELSE> <COLON> ( statement = Statement() {list.add(statement);}
2885 | statement = htmlBlock() {list.add(statement);})*
2887 final Statement[] stmtsArray = new Statement[list.size()];
2888 list.toArray(stmtsArray);
2889 return new Else(stmtsArray,pos,SimpleCharStream.getPosition());}
2892 ElseIf ElseIfStatement() :
2894 final Expression condition;
2895 final Statement statement;
2896 final ArrayList list = new ArrayList();
2897 final int pos = SimpleCharStream.getPosition();
2900 <ELSEIF> condition = Condition("elseif") statement = Statement() {list.add(statement);/*todo:do better*/}
2902 final Statement[] stmtsArray = new Statement[list.size()];
2903 list.toArray(stmtsArray);
2904 return new ElseIf(condition,stmtsArray,pos,SimpleCharStream.getPosition());}
2907 WhileStatement WhileStatement() :
2909 final Expression condition;
2910 final Statement action;
2911 final int pos = SimpleCharStream.getPosition();
2915 condition = Condition("while")
2916 action = WhileStatement0(pos,pos + 5)
2917 {return new WhileStatement(condition,action,pos,SimpleCharStream.getPosition());}
2920 Statement WhileStatement0(final int start, final int end) :
2922 Statement statement;
2923 final ArrayList stmts = new ArrayList();
2924 final int pos = SimpleCharStream.getPosition();
2927 <COLON> (statement = Statement() {stmts.add(statement);})*
2929 setMarker(fileToParse,
2930 "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
2934 "Line " + token.beginLine);
2935 } catch (CoreException e) {
2936 PHPeclipsePlugin.log(e);
2940 } catch (ParseException e) {
2941 errorMessage = "'endwhile' expected";
2943 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2944 errorEnd = SimpleCharStream.getPosition() + 1;
2950 final Statement[] stmtsArray = new Statement[stmts.size()];
2951 stmts.toArray(stmtsArray);
2952 return new Block(stmtsArray,pos,SimpleCharStream.getPosition());}
2953 } catch (ParseException e) {
2954 errorMessage = "';' expected after 'endwhile' keyword";
2956 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2957 errorEnd = SimpleCharStream.getPosition() + 1;
2961 statement = Statement()
2965 DoStatement DoStatement() :
2967 final Statement action;
2968 final Expression condition;
2969 final Token token, token2;
2972 token = <DO> action = Statement() <WHILE> condition = Condition("while")
2974 token2 = <SEMICOLON>
2975 {return new DoStatement(condition,action,token.sourceStart,token2.sourceEnd);}
2976 } catch (ParseException e) {
2977 errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
2979 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
2980 errorEnd = SimpleCharStream.getPosition() + 1;
2985 ForeachStatement ForeachStatement() :
2987 Statement statement;
2988 Expression expression;
2989 ArrayVariableDeclaration variable;
2996 } catch (ParseException e) {
2997 errorMessage = "'(' expected after 'foreach' keyword";
2999 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3000 errorEnd = SimpleCharStream.getPosition() + 1;
3004 expression = Expression()
3005 } catch (ParseException e) {
3006 errorMessage = "variable expected";
3008 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3009 errorEnd = SimpleCharStream.getPosition() + 1;
3014 } catch (ParseException e) {
3015 errorMessage = "'as' expected";
3017 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3018 errorEnd = SimpleCharStream.getPosition() + 1;
3022 variable = ArrayVariable()
3023 } catch (ParseException e) {
3024 errorMessage = "variable expected";
3026 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3027 errorEnd = SimpleCharStream.getPosition() + 1;
3032 } catch (ParseException e) {
3033 errorMessage = "')' expected after 'foreach' keyword";
3035 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3036 errorEnd = SimpleCharStream.getPosition() + 1;
3040 statement = Statement()
3041 } catch (ParseException e) {
3042 if (errorMessage != null) throw e;
3043 errorMessage = "statement expected";
3045 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3046 errorEnd = SimpleCharStream.getPosition() + 1;
3049 {return new ForeachStatement(expression,
3053 statement.sourceEnd);}
3057 ForStatement ForStatement() :
3059 final Token token,token2;
3060 final int pos = SimpleCharStream.getPosition();
3061 Expression[] initializations = null;
3062 Expression condition = null;
3063 Expression[] increments = null;
3065 final ArrayList list = new ArrayList();
3066 final int startBlock, endBlock;
3072 } catch (ParseException e) {
3073 errorMessage = "'(' expected after 'for' keyword";
3075 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3076 errorEnd = SimpleCharStream.getPosition() + 1;
3079 [ initializations = ForInit() ] <SEMICOLON>
3080 [ condition = Expression() ] <SEMICOLON>
3081 [ increments = StatementExpressionList() ] <RPAREN>
3083 action = Statement()
3084 {return new ForStatement(initializations,
3092 {startBlock = SimpleCharStream.getPosition();}
3093 (action = Statement() {list.add(action);})*
3096 setMarker(fileToParse,
3097 "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
3099 pos+token.image.length(),
3101 "Line " + token.beginLine);
3102 } catch (CoreException e) {
3103 PHPeclipsePlugin.log(e);
3106 {endBlock = SimpleCharStream.getPosition();}
3109 } catch (ParseException e) {
3110 errorMessage = "'endfor' expected";
3112 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3113 errorEnd = SimpleCharStream.getPosition() + 1;
3117 token2 = <SEMICOLON>
3119 final Statement[] stmtsArray = new Statement[list.size()];
3120 list.toArray(stmtsArray);
3121 return new ForStatement(initializations,
3124 new Block(stmtsArray,
3125 stmtsArray[0].sourceStart,
3126 stmtsArray[stmtsArray.length-1].sourceEnd),
3129 } catch (ParseException e) {
3130 errorMessage = "';' expected after 'endfor' keyword";
3132 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3133 errorEnd = SimpleCharStream.getPosition() + 1;
3139 Expression[] ForInit() :
3141 final Expression[] exprs;
3144 LOOKAHEAD(LocalVariableDeclaration())
3145 exprs = LocalVariableDeclaration()
3148 exprs = StatementExpressionList()
3152 Expression[] StatementExpressionList() :
3154 final ArrayList list = new ArrayList();
3155 final Expression expr;
3158 expr = StatementExpression() {list.add(expr);}
3159 (<COMMA> StatementExpression() {list.add(expr);})*
3161 final Expression[] exprsArray = new Expression[list.size()];
3162 list.toArray(exprsArray);
3167 Continue ContinueStatement() :
3169 Expression expr = null;
3170 final Token token,token2;
3173 token = <CONTINUE> [ expr = Expression() ]
3175 token2 = <SEMICOLON>
3176 {return new Continue(expr,token.sourceStart,token2.sourceEnd);}
3177 } catch (ParseException e) {
3178 errorMessage = "';' expected after 'continue' statement";
3180 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3181 errorEnd = SimpleCharStream.getPosition() + 1;
3186 ReturnStatement ReturnStatement() :
3188 Expression expr = null;
3189 final Token token,token2;
3192 token = <RETURN> [ expr = Expression() ]
3194 token2 = <SEMICOLON>
3195 {return new ReturnStatement(expr,token.sourceStart,token2.sourceEnd);}
3196 } catch (ParseException e) {
3197 errorMessage = "';' expected after 'return' statement";
3199 errorStart = SimpleCharStream.getPosition() - e.currentToken.next.image.length() + 1;
3200 errorEnd = SimpleCharStream.getPosition() + 1;