3   CHOICE_AMBIGUITY_CHECK = 2;
 
   4   OTHER_AMBIGUITY_CHECK = 1;
 
   7   DEBUG_LOOKAHEAD = false;
 
   8   DEBUG_TOKEN_MANAGER = false;
 
   9   OPTIMIZE_TOKEN_MANAGER = false;
 
  10   ERROR_REPORTING = true;
 
  11   JAVA_UNICODE_ESCAPE = false;
 
  12   UNICODE_INPUT = false;
 
  14   USER_TOKEN_MANAGER = false;
 
  15   USER_CHAR_STREAM = false;
 
  17   BUILD_TOKEN_MANAGER = true;
 
  19   FORCE_LA_CHECK = false;
 
  22 PARSER_BEGIN(PHPParser)
 
  25 import org.eclipse.core.resources.IFile;
 
  26 import org.eclipse.core.resources.IMarker;
 
  27 import org.eclipse.core.runtime.CoreException;
 
  28 import org.eclipse.ui.texteditor.MarkerUtilities;
 
  29 import org.eclipse.jface.preference.IPreferenceStore;
 
  31 import java.util.Hashtable;
 
  32 import java.util.Enumeration;
 
  33 import java.io.StringReader;
 
  35 import java.text.MessageFormat;
 
  37 import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
 
  38 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  39 import net.sourceforge.phpdt.internal.compiler.parser.*;
 
  43  * This php parser is inspired by the Java 1.2 grammar example
 
  44  * given with JavaCC. You can get JavaCC at http://www.webgain.com
 
  45  * You can test the parser with the PHPParserTestCase2.java
 
  46  * @author Matthieu Casanova
 
  48 public final class PHPParser extends PHPParserSuperclass {
 
  50   /** The file that is parsed. */
 
  51   private static IFile fileToParse;
 
  53   /** The current segment. */
 
  54   private static PHPSegmentWithChildren currentSegment;
 
  56   private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
 
  57   private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
 
  58   PHPOutlineInfo outlineInfo;
 
  60   private static PHPFunctionDeclaration currentFunction;
 
  61   private static boolean assigning;
 
  63   /** The error level of the current ParseException. */
 
  64   private static int errorLevel = ERROR;
 
  65   /** The message of the current ParseException. If it's null it's because the parse exception wasn't handled */
 
  66   private static String errorMessage;
 
  68   private static int errorStart = -1;
 
  69   private static int errorEnd = -1;
 
  71   public final void setFileToParse(final IFile fileToParse) {
 
  72     this.fileToParse = fileToParse;
 
  78   public PHPParser(final IFile fileToParse) {
 
  79     this(new StringReader(""));
 
  80     this.fileToParse = fileToParse;
 
  83   public static final void phpParserTester(final String strEval) throws CoreException, ParseException {
 
  84     PHPParserTokenManager.SwitchTo(PHPParserTokenManager.PHPPARSING);
 
  85     final StringReader stream = new StringReader(strEval);
 
  86     if (jj_input_stream == null) {
 
  87       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
  89     ReInit(new StringReader(strEval));
 
  93   public static final void htmlParserTester(final File fileName) throws CoreException, ParseException {
 
  95       final Reader stream = new FileReader(fileName);
 
  96       if (jj_input_stream == null) {
 
  97         jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 101     } catch (FileNotFoundException e) {
 
 102       e.printStackTrace();  //To change body of catch statement use Options | File Templates.
 
 106   public static final void htmlParserTester(final String strEval) throws CoreException, ParseException {
 
 107     final StringReader stream = new StringReader(strEval);
 
 108     if (jj_input_stream == null) {
 
 109       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 115   public final PHPOutlineInfo parseInfo(final Object parent, final String s) {
 
 116     outlineInfo = new PHPOutlineInfo(parent);
 
 117     currentSegment = outlineInfo.getDeclarations();
 
 118     final StringReader stream = new StringReader(s);
 
 119     if (jj_input_stream == null) {
 
 120       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 125     } catch (ParseException e) {
 
 126       processParseException(e);
 
 132    * This method will process the parse exception.
 
 133    * If the error message is null, the parse exception wasn't catched and a trace is written in the log
 
 134    * @param e the ParseException
 
 136   private static void processParseException(final ParseException e) {
 
 137     if (errorMessage == null) {
 
 138       PHPeclipsePlugin.log(e);
 
 139       errorMessage = "this exception wasn't handled by the parser please tell us how to reproduce it";
 
 140       errorStart = jj_input_stream.getPosition();
 
 141       errorEnd   = errorStart + 1;
 
 148    * Create marker for the parse error
 
 149    * @param e the ParseException
 
 151   private static void setMarker(final ParseException e) {
 
 153       if (errorStart == -1) {
 
 154         setMarker(fileToParse,
 
 156                   jj_input_stream.tokenBegin,
 
 157                   jj_input_stream.tokenBegin + e.currentToken.image.length(),
 
 159                   "Line " + e.currentToken.beginLine);
 
 161         setMarker(fileToParse,
 
 166                   "Line " + e.currentToken.beginLine);
 
 170     } catch (CoreException e2) {
 
 171       PHPeclipsePlugin.log(e2);
 
 176    * Create markers according to the external parser output
 
 178   private static void createMarkers(final String output, final IFile file) throws CoreException {
 
 179     // delete all markers
 
 180     file.deleteMarkers(IMarker.PROBLEM, false, 0);
 
 185     while ((brIndx = output.indexOf("<br />", indx)) != -1) {
 
 186       // newer php error output (tested with 4.2.3)
 
 187       scanLine(output, file, indx, brIndx);
 
 192       while ((brIndx = output.indexOf("<br>", indx)) != -1) {
 
 193         // older php error output (tested with 4.2.3)
 
 194         scanLine(output, file, indx, brIndx);
 
 200   private static void scanLine(final String output,
 
 203                                final int brIndx) throws CoreException {
 
 205     StringBuffer lineNumberBuffer = new StringBuffer(10);
 
 207     current = output.substring(indx, brIndx);
 
 209     if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
 
 210       int onLine = current.indexOf("on line <b>");
 
 212         lineNumberBuffer.delete(0, lineNumberBuffer.length());
 
 213         for (int i = onLine; i < current.length(); i++) {
 
 214           ch = current.charAt(i);
 
 215           if ('0' <= ch && '9' >= ch) {
 
 216             lineNumberBuffer.append(ch);
 
 220         int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
 
 222         Hashtable attributes = new Hashtable();
 
 224         current = current.replaceAll("\n", "");
 
 225         current = current.replaceAll("<b>", "");
 
 226         current = current.replaceAll("</b>", "");
 
 227         MarkerUtilities.setMessage(attributes, current);
 
 229         if (current.indexOf(PARSE_ERROR_STRING) != -1)
 
 230           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
 
 231         else if (current.indexOf(PARSE_WARNING_STRING) != -1)
 
 232           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
 
 234           attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
 
 235         MarkerUtilities.setLineNumber(attributes, lineNumber);
 
 236         MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
 
 241   public final void parse(final String s) throws CoreException {
 
 242     final StringReader stream = new StringReader(s);
 
 243     if (jj_input_stream == null) {
 
 244       jj_input_stream = new SimpleCharStream(stream, 1, 1);
 
 249     } catch (ParseException e) {
 
 250       processParseException(e);
 
 255    * Call the php parse command ( php -l -f <filename> )
 
 256    * and create markers according to the external parser output
 
 258   public static void phpExternalParse(final IFile file) {
 
 259     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
 
 260     final String filename = file.getLocation().toString();
 
 262     final String[] arguments = { filename };
 
 263     final MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
 
 264     final String command = form.format(arguments);
 
 266     final String parserResult = PHPStartApacheAction.getParserOutput(command, "External parser: ");
 
 269       // parse the buffer to find the errors and warnings
 
 270       createMarkers(parserResult, file);
 
 271     } catch (CoreException e) {
 
 272       PHPeclipsePlugin.log(e);
 
 276   public static final void parse() throws ParseException {
 
 281 PARSER_END(PHPParser)
 
 285   <PHPSTARTSHORT : "<?">   : PHPPARSING
 
 286 | <PHPSTARTLONG : "<?php"> : PHPPARSING
 
 287 | <PHPECHOSTART : "<?=">   : PHPPARSING
 
 292   <PHPEND :"?>"> : DEFAULT
 
 295 /* Skip any character if we are not in php mode */
 
 313 <PHPPARSING> SPECIAL_TOKEN :
 
 315   "//" : IN_SINGLE_LINE_COMMENT
 
 317   "#"  : IN_SINGLE_LINE_COMMENT
 
 319   <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT
 
 321   "/*" : IN_MULTI_LINE_COMMENT
 
 324 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 
 326   <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : PHPPARSING
 
 329 <IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN :
 
 331   <SINGLE_LINE_COMMENT_PHPEND : "?>" > : DEFAULT
 
 337   <FORMAL_COMMENT: "*/" > : PHPPARSING
 
 340 <IN_MULTI_LINE_COMMENT>
 
 343   <MULTI_LINE_COMMENT: "*/" > : PHPPARSING
 
 346 <IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT>
 
 356 | <FUNCTION : "function">
 
 359 | <ELSEIF   : "elseif">
 
 366 /* LANGUAGE CONSTRUCT */
 
 371 | <INCLUDE            : "include">
 
 372 | <REQUIRE            : "require">
 
 373 | <INCLUDE_ONCE       : "include_once">
 
 374 | <REQUIRE_ONCE       : "require_once">
 
 375 | <GLOBAL             : "global">
 
 376 | <STATIC             : "static">
 
 377 | <CLASSACCESS        : "->">
 
 378 | <STATICCLASSACCESS  : "::">
 
 379 | <ARRAYASSIGN        : "=>">
 
 382 /* RESERVED WORDS AND LITERALS */
 
 388 | <CONTINUE : "continue">
 
 389 | <_DEFAULT : "default">
 
 391 | <EXTENDS  : "extends">
 
 396 | <RETURN   : "return">
 
 398 | <SWITCH   : "switch">
 
 403 | <ENDWHILE : "endwhile">
 
 404 | <ENDSWITCH: "endswitch">
 
 406 | <ENDFOR   : "endfor">
 
 407 | <FOREACH  : "foreach">
 
 415 | <OBJECT  : "object">
 
 417 | <BOOLEAN : "boolean">
 
 419 | <DOUBLE  : "double">
 
 422 | <INTEGER : "integer">
 
 435         <DECIMAL_LITERAL> (["l","L"])?
 
 436       | <HEX_LITERAL> (["l","L"])?
 
 437       | <OCTAL_LITERAL> (["l","L"])?
 
 440   < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
 
 442   < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
 
 444   < #OCTAL_LITERAL: "0" (["0"-"7"])* >
 
 446   < FLOATING_POINT_LITERAL:
 
 447         (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
 
 448       | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
 
 449       | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
 
 450       | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
 
 453   < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
 
 455   < STRING_LITERAL: (<STRING_1> | <STRING_2> | <STRING_3>)>
 
 491   < IDENTIFIER: (<LETTER>|<SPECIAL>) (<LETTER>|<DIGIT>|<SPECIAL>)* >
 
 494       ["a"-"z"] | ["A"-"Z"]
 
 502     "_" | ["\u007f"-"\u00ff"]
 
 532 | <BANGDOUBLEEQUAL    : "!==">
 
 533 | <TRIPLEEQUAL        : "===">
 
 540 | <PLUSASSIGN         : "+=">
 
 541 | <MINUSASSIGN        : "-=">
 
 542 | <STARASSIGN         : "*=">
 
 543 | <SLASHASSIGN        : "/=">
 
 549 | <TILDEEQUAL         : "~=">
 
 574 | <RSIGNEDSHIFT       : ">>">
 
 575 | <RUNSIGNEDSHIFT     : ">>>">
 
 576 | <LSHIFTASSIGN       : "<<=">
 
 577 | <RSIGNEDSHIFTASSIGN : ">>=">
 
 582   < DOLLAR_ID: <DOLLAR> <IDENTIFIER>  >
 
 598   } catch (TokenMgrError e) {
 
 599     PHPeclipsePlugin.log(e);
 
 600     errorStart   = SimpleCharStream.getPosition();
 
 601     errorEnd     = errorStart + 1;
 
 602     errorMessage = e.getMessage();
 
 604     throw generateParseException();
 
 609  * A php block is a <?= expression [;]?>
 
 610  * or <?php somephpcode ?>
 
 611  * or <? somephpcode ?>
 
 615   final int start = jj_input_stream.getPosition();
 
 623       setMarker(fileToParse,
 
 624                 "You should use '<?php' instead of '<?' it will avoid some problems with XML",
 
 626                 jj_input_stream.getPosition(),
 
 628                 "Line " + token.beginLine);
 
 629     } catch (CoreException e) {
 
 630       PHPeclipsePlugin.log(e);
 
 636   } catch (ParseException e) {
 
 637     errorMessage = "'?>' expected";
 
 639     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 640     errorEnd   = jj_input_stream.getPosition() + 1;
 
 645 void phpEchoBlock() :
 
 648   <PHPECHOSTART> Expression() [ <SEMICOLON> ] <PHPEND>
 
 657 void ClassDeclaration() :
 
 659   final PHPClassDeclaration classDeclaration;
 
 660   final Token className;
 
 666     {pos = jj_input_stream.getPosition();}
 
 667     className = <IDENTIFIER>
 
 668   } catch (ParseException e) {
 
 669     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
 
 671     errorStart   = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 672     errorEnd     = jj_input_stream.getPosition() + 1;
 
 679     } catch (ParseException e) {
 
 680       errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', identifier expected";
 
 682       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 683       errorEnd   = jj_input_stream.getPosition() + 1;
 
 688     if (currentSegment != null) {
 
 689       classDeclaration = new PHPClassDeclaration(currentSegment,className.image,pos);
 
 690       currentSegment.add(classDeclaration);
 
 691       currentSegment = classDeclaration;
 
 696     if (currentSegment != null) {
 
 697       currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
 707   } catch (ParseException e) {
 
 708     errorMessage = "unexpected token : '"+ e.currentToken.next.image + "', '{' expected";
 
 710     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 711     errorEnd   = jj_input_stream.getPosition() + 1;
 
 714   ( ClassBodyDeclaration() )*
 
 717   } catch (ParseException e) {
 
 718     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', 'var', 'function' or '}' expected";
 
 720     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 721     errorEnd   = jj_input_stream.getPosition() + 1;
 
 727  * A class can contain only methods and fields.
 
 729 void ClassBodyDeclaration() :
 
 738  * A class field declaration : it's var VariableDeclarator() (, VariableDeclarator())*;.
 
 740 void FieldDeclaration() :
 
 742   PHPVarDeclaration variableDeclaration;
 
 745   <VAR> variableDeclaration = VariableDeclarator()
 
 747     if (currentSegment != null) {
 
 748       currentSegment.add(variableDeclaration);
 
 752       variableDeclaration = VariableDeclarator()
 
 754       if (currentSegment != null) {
 
 755         currentSegment.add(variableDeclaration);
 
 761   } catch (ParseException e) {
 
 762     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected after variable declaration";
 
 764     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 765     errorEnd   = jj_input_stream.getPosition() + 1;
 
 770 PHPVarDeclaration VariableDeclarator() :
 
 772   final String varName, varValue;
 
 773   final int pos = jj_input_stream.getPosition();
 
 776   varName = VariableDeclaratorId()
 
 780       varValue = VariableInitializer()
 
 781       {return new PHPVarDeclaration(currentSegment,varName,pos,varValue);}
 
 782     } catch (ParseException e) {
 
 783       errorMessage = "Literal expression expected in variable initializer";
 
 785       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 786       errorEnd   = jj_input_stream.getPosition() + 1;
 
 790   {return new PHPVarDeclaration(currentSegment,varName,pos);}
 
 793 String VariableDeclaratorId() :
 
 796   final StringBuffer buff = new StringBuffer();
 
 802     ( LOOKAHEAD(2) expr = VariableSuffix()
 
 805     {return buff.toString();}
 
 806   } catch (ParseException e) {
 
 807     errorMessage = "'$' expected for variable identifier";
 
 809     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 810     errorEnd   = jj_input_stream.getPosition() + 1;
 
 821   token = <DOLLAR_ID> [<LBRACE> expr = Expression() <RBRACE>]
 
 823     if (expr == null && !assigning) {
 
 824       if (currentFunction != null) {
 
 825         PHPVarDeclaration var = currentFunction.getParameter(token.image.substring(1));
 
 827           var.getVariable().setUsed(true);
 
 830       return token.image.substring(1);
 
 832     return token + "{" + expr + "}";
 
 835   <DOLLAR> expr = VariableName()
 
 839 String VariableName():
 
 845   <LBRACE> expr = Expression() <RBRACE>
 
 846   {return "{"+expr+"}";}
 
 848   token = <IDENTIFIER> [<LBRACE> expr = Expression() <RBRACE>]
 
 851       if (currentFunction != null) {
 
 852         PHPVarDeclaration var = currentFunction.getParameter(token.image);
 
 854           var.getVariable().setUsed(true);
 
 859     return token + "{" + expr + "}";
 
 862   <DOLLAR> expr = VariableName()
 
 864     if (currentFunction != null) {
 
 865       PHPVarDeclaration var = currentFunction.getParameter(expr);
 
 867         var.getVariable().setUsed(true);
 
 875     if (currentFunction != null) {
 
 876       PHPVarDeclaration var = currentFunction.getParameter(token.image.substring(1));
 
 878         var.getVariable().setUsed(true);
 
 881     return token.image + expr;
 
 884   token = <DOLLAR_ID> [expr = VariableName()]
 
 889   return token.image + expr;
 
 893 String VariableInitializer() :
 
 902   <MINUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 903   {return "-" + token.image;}
 
 905   <PLUS> (token = <INTEGER_LITERAL> | token = <FLOATING_POINT_LITERAL>)
 
 906   {return "+" + token.image;}
 
 908   expr = ArrayDeclarator()
 
 912   {return token.image;}
 
 915 String ArrayVariable() :
 
 918 final StringBuffer buff = new StringBuffer();
 
 923    [<ARRAYASSIGN> expr = Expression()
 
 924    {buff.append("=>").append(expr);}]
 
 925   {return buff.toString();}
 
 928 String ArrayInitializer() :
 
 931 final StringBuffer buff = new StringBuffer("(");
 
 934   <LPAREN> [ expr = ArrayVariable()
 
 936             ( LOOKAHEAD(2) <COMMA> expr = ArrayVariable()
 
 937             {buff.append(",").append(expr);}
 
 940            [<COMMA> {buff.append(",");}]
 
 944     return buff.toString();
 
 949  * A Method Declaration.
 
 950  * <b>function</b> MetodDeclarator() Block()
 
 952 void MethodDeclaration() :
 
 954   final PHPFunctionDeclaration functionDeclaration;
 
 958   functionToken = <FUNCTION>
 
 960     functionDeclaration = MethodDeclarator()
 
 961   } catch (ParseException e) {
 
 962     if (errorMessage != null) {
 
 965     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function identifier expected";
 
 967     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
 968     errorEnd   = jj_input_stream.getPosition() + 1;
 
 972     if (currentSegment != null) {
 
 973       currentSegment.add(functionDeclaration);
 
 974       currentSegment = functionDeclaration;
 
 976     currentFunction = functionDeclaration;
 
 980     Hashtable parameters = currentFunction.getParameters();
 
 981     Enumeration vars = parameters.elements();
 
 982     while (vars.hasMoreElements()) {
 
 983       PHPVarDeclaration o = (PHPVarDeclaration) vars.nextElement();
 
 984       if (!o.getVariable().isUsed()) {
 
 986           setMarker(fileToParse,
 
 987                     "Parameter "+o.getVariable().getName()+" is never used in function",
 
 988                     functionToken.beginLine,
 
 990                     "Line " + token.beginLine);
 
 991         } catch (CoreException e) {
 
 992           PHPeclipsePlugin.log(e);
 
 996     currentFunction = null;
 
 997     if (currentSegment != null) {
 
 998       currentSegment = (PHPSegmentWithChildren) currentSegment.getParent();
 
1004  * A MethodDeclarator.
 
1005  * [&] IDENTIFIER(parameters ...).
 
1006  * @return a function description for the outline
 
1008 PHPFunctionDeclaration MethodDeclarator() :
 
1010   final Token identifier;
 
1011   final StringBuffer methodDeclaration = new StringBuffer();
 
1012   final Hashtable formalParameters;
 
1013   final int pos = jj_input_stream.getPosition();
 
1016   [ <BIT_AND> {methodDeclaration.append("&");} ]
 
1017   identifier = <IDENTIFIER>
 
1018   formalParameters = FormalParameters()
 
1020     methodDeclaration.append(identifier);
 
1021     return new PHPFunctionDeclaration(currentSegment,methodDeclaration.toString(),pos,formalParameters);
 
1026  * FormalParameters follows method identifier.
 
1027  * (FormalParameter())
 
1029 Hashtable FormalParameters() :
 
1032   final StringBuffer buff = new StringBuffer("(");
 
1033   PHPVarDeclaration var;
 
1034   final Hashtable parameters = new Hashtable();
 
1039   } catch (ParseException e) {
 
1040     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected after function identifier";
 
1042     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1043     errorEnd   = jj_input_stream.getPosition() + 1;
 
1046             [ var = FormalParameter()
 
1047               {parameters.put(var.getVariable().getName(),var);}
 
1049                 <COMMA> var = FormalParameter()
 
1050                 {parameters.put(var.getVariable().getName(),var);}
 
1055   } catch (ParseException e) {
 
1056     errorMessage = "')' expected";
 
1058     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1059     errorEnd   = jj_input_stream.getPosition() + 1;
 
1062  {return parameters;}
 
1066  * A formal parameter.
 
1067  * $varname[=value] (,$varname[=value])
 
1069 PHPVarDeclaration FormalParameter() :
 
1071   final PHPVarDeclaration variableDeclaration;
 
1075   [token = <BIT_AND>] variableDeclaration = VariableDeclarator()
 
1077     if (token != null) {
 
1078       variableDeclaration.getVariable().setReference(true);
 
1080     return variableDeclaration;
 
1115 String Expression() :
 
1118   final String assignOperator;
 
1122   expr = PrintExpression()
 
1125   expr = ListExpression()
 
1128   LOOKAHEAD(varAssignation())
 
1129   expr = varAssignation()
 
1132   expr = ConditionalExpression()
 
1137  * A Variable assignation.
 
1138  * varName (an assign operator) any expression
 
1140 String varAssignation() :
 
1142   String varName,assignOperator,expr2;
 
1143   PHPVarDeclaration variable;
 
1144   final int pos = SimpleCharStream.getPosition();
 
1147   varName = VariableDeclaratorId()
 
1148   assignOperator = AssignmentOperator()
 
1150       expr2 = Expression()
 
1151     } catch (ParseException e) {
 
1152       if (errorMessage != null) {
 
1155       errorMessage = "expression expected";
 
1157       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1158       errorEnd   = jj_input_stream.getPosition() + 1;
 
1161     {return varName + assignOperator + expr2;}
 
1164 String AssignmentOperator() :
 
1181 | <RSIGNEDSHIFTASSIGN>
 
1195 String ConditionalExpression() :
 
1198   String expr2 = null;
 
1199   String expr3 = null;
 
1202   expr = ConditionalOrExpression() [ <HOOK> expr2 = Expression() <COLON> expr3 = ConditionalExpression() ]
 
1204   if (expr3 == null) {
 
1207     return expr + "?" + expr2 + ":" + expr3;
 
1212 String ConditionalOrExpression() :
 
1216   final StringBuffer buff = new StringBuffer();
 
1219   expr = ConditionalAndExpression()
 
1220   {buff.append(expr);}
 
1222     (operator = <SC_OR> | operator = <_ORL>) expr = ConditionalAndExpression()
 
1224       buff.append(operator.image);
 
1229     return buff.toString();
 
1233 String ConditionalAndExpression() :
 
1237   final StringBuffer buff = new StringBuffer();
 
1240   expr = ConcatExpression()
 
1241   {buff.append(expr);}
 
1243   (operator = <SC_AND> | operator = <_ANDL>) expr = ConcatExpression()
 
1245       buff.append(operator.image);
 
1249   {return buff.toString();}
 
1252 String ConcatExpression() :
 
1255   final StringBuffer buff = new StringBuffer();
 
1258   expr = InclusiveOrExpression()
 
1259   {buff.append(expr);}
 
1261   <DOT> expr = InclusiveOrExpression()
 
1262   {buff.append(".").append(expr);}
 
1264   {return buff.toString();}
 
1267 String InclusiveOrExpression() :
 
1270   final StringBuffer buff = new StringBuffer();
 
1273   expr = ExclusiveOrExpression()
 
1274   {buff.append(expr);}
 
1276   <BIT_OR> expr = ExclusiveOrExpression()
 
1277   {buff.append("|").append(expr);}
 
1279   {return buff.toString();}
 
1282 String ExclusiveOrExpression() :
 
1285   final StringBuffer buff = new StringBuffer();
 
1288   expr = AndExpression()
 
1293     <XOR> expr = AndExpression()
 
1300     return buff.toString();
 
1304 String AndExpression() :
 
1307   final StringBuffer buff = new StringBuffer();
 
1310   expr = EqualityExpression()
 
1315     <BIT_AND> expr = EqualityExpression()
 
1317     buff.append("&").append(expr);
 
1320   {return buff.toString();}
 
1323 String EqualityExpression() :
 
1327   final StringBuffer buff = new StringBuffer();
 
1330   expr = RelationalExpression()
 
1331   {buff.append(expr);}
 
1336     | operator = <BANGDOUBLEEQUAL>
 
1337     | operator = <TRIPLEEQUAL>
 
1340     expr = RelationalExpression()
 
1341   } catch (ParseException e) {
 
1342     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', expression expected after '"+operator.image+"'";
 
1344     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1345     errorEnd   = jj_input_stream.getPosition() + 1;
 
1349     buff.append(operator.image);
 
1353   {return buff.toString();}
 
1356 String RelationalExpression() :
 
1360   final StringBuffer buff = new StringBuffer();
 
1363   expr = ShiftExpression()
 
1364   {buff.append(expr);}
 
1366   ( operator = <LT> | operator = <GT> | operator = <LE> | operator = <GE> ) expr = ShiftExpression()
 
1367   {buff.append(operator.image).append(expr);}
 
1369   {return buff.toString();}
 
1372 String ShiftExpression() :
 
1376   final StringBuffer buff = new StringBuffer();
 
1379   expr = AdditiveExpression()
 
1380   {buff.append(expr);}
 
1382   (operator = <LSHIFT> | operator = <RSIGNEDSHIFT> | operator = <RUNSIGNEDSHIFT> ) expr = AdditiveExpression()
 
1384     buff.append(operator.image);
 
1388   {return buff.toString();}
 
1391 String AdditiveExpression() :
 
1395   final StringBuffer buff = new StringBuffer();
 
1398   expr = MultiplicativeExpression()
 
1399   {buff.append(expr);}
 
1401    ( operator = <PLUS> | operator = <MINUS> ) expr = MultiplicativeExpression()
 
1403     buff.append(operator.image);
 
1407   {return buff.toString();}
 
1410 String MultiplicativeExpression() :
 
1414   final StringBuffer buff = new StringBuffer();}
 
1417     expr = UnaryExpression()
 
1418   } catch (ParseException e) {
 
1419     errorMessage = "unexpected token '"+e.currentToken.next.image+"'";
 
1421     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1422     errorEnd   = jj_input_stream.getPosition() + 1;
 
1425   {buff.append(expr);}
 
1427     ( operator = <STAR> | operator = <SLASH> | operator = <REM> ) expr = UnaryExpression()
 
1429       buff.append(operator.image);
 
1433   {return buff.toString();}
 
1437  * An unary expression starting with @, & or nothing
 
1439 String UnaryExpression() :
 
1443   final StringBuffer buff = new StringBuffer();
 
1446   token = <BIT_AND> expr = UnaryExpressionNoPrefix()
 
1448     if (token == null) {
 
1451     return token.image + expr;
 
1454   (<AT> {buff.append("@");})* expr = UnaryExpressionNoPrefix()
 
1455   {return buff.append(expr).toString();}
 
1458 String UnaryExpressionNoPrefix() :
 
1464   ( token = <PLUS> | token = <MINUS> ) expr = UnaryExpression()
 
1466     return token.image + expr;
 
1469   expr = PreIncDecExpression()
 
1472   expr = UnaryExpressionNotPlusMinus()
 
1477 String PreIncDecExpression() :
 
1483   (token = <INCR> | token = <DECR>) expr = PrimaryExpression()
 
1484   {return token.image + expr;}
 
1487 String UnaryExpressionNotPlusMinus() :
 
1492   <BANG> expr = UnaryExpression()
 
1493   {return "!" + expr;}
 
1495   LOOKAHEAD( <LPAREN> (Type() | <ARRAY>) <RPAREN> )
 
1496   expr = CastExpression()
 
1499   expr = PostfixExpression()
 
1505   <LPAREN> expr = Expression()
 
1508   } catch (ParseException e) {
 
1509     errorMessage = "')' expected";
 
1511     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1512     errorEnd   = jj_input_stream.getPosition() + 1;
 
1515   {return "("+expr+")";}
 
1518 String CastExpression() :
 
1520 final String type, expr;
 
1523   <LPAREN> (type = Type() | <ARRAY> {type = "array";}) <RPAREN> expr = UnaryExpression()
 
1524   {return "(" + type + ")" + expr;}
 
1527 String PostfixExpression() :
 
1530   Token operator = null;
 
1533   expr = PrimaryExpression() [ operator = <INCR> | operator = <DECR> ]
 
1535     if (operator == null) {
 
1538     return expr + operator.image;
 
1542 String PrimaryExpression() :
 
1544   final Token identifier;
 
1546   final StringBuffer buff = new StringBuffer();
 
1550   identifier = <IDENTIFIER> <STATICCLASSACCESS> expr = ClassIdentifier()
 
1551   {buff.append(identifier.image).append("::").append(expr);}
 
1553   expr = PrimarySuffix()
 
1554   {buff.append(expr);}
 
1556   {return buff.toString();}
 
1558   expr = PrimaryPrefix()  {buff.append(expr);}
 
1559   ( expr = PrimarySuffix()  {buff.append(expr);} )*
 
1560   {return buff.toString();}
 
1562   expr = ArrayDeclarator()
 
1563   {return "array" + expr;}
 
1566 String ArrayDeclarator() :
 
1571   <ARRAY> expr = ArrayInitializer()
 
1572   {return "array" + expr;}
 
1575 String PrimaryPrefix() :
 
1581   token = <IDENTIFIER>
 
1582   {return token.image;}
 
1584   <NEW> expr = ClassIdentifier()
 
1586     return "new " + expr;
 
1589   expr = VariableDeclaratorId()
 
1593 String classInstantiation() :
 
1596   final StringBuffer buff = new StringBuffer("new ");
 
1599   <NEW> expr = ClassIdentifier()
 
1600   {buff.append(expr);}
 
1602     expr = PrimaryExpression()
 
1603     {buff.append(expr);}
 
1605   {return buff.toString();}
 
1608 String ClassIdentifier():
 
1614   token = <IDENTIFIER>
 
1615   {return token.image;}
 
1617   expr = VariableDeclaratorId()
 
1621 String PrimarySuffix() :
 
1629   expr = VariableSuffix()
 
1633 String VariableSuffix() :
 
1640     expr = VariableName()
 
1641   } catch (ParseException e) {
 
1642     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', function call or field access expected";
 
1644     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1645     errorEnd   = jj_input_stream.getPosition() + 1;
 
1648   {return "->" + expr;}
 
1650   <LBRACKET> [ expr = Expression() | expr = Type() ]  //Not good
 
1653   } catch (ParseException e) {
 
1654     errorMessage = "']' expected";
 
1656     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1657     errorEnd   = jj_input_stream.getPosition() + 1;
 
1664     return "[" + expr + "]";
 
1674   token = <INTEGER_LITERAL>
 
1675   {return token.image;}
 
1677   token = <FLOATING_POINT_LITERAL>
 
1678   {return token.image;}
 
1680   token = <STRING_LITERAL>
 
1681   {return token.image;}
 
1683   expr = BooleanLiteral()
 
1690 String BooleanLiteral() :
 
1700 String Arguments() :
 
1705   <LPAREN> [ expr = ArgumentList() ]
 
1708   } catch (ParseException e) {
 
1709     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected to close the argument list";
 
1711     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1712     errorEnd   = jj_input_stream.getPosition() + 1;
 
1719   return "(" + expr + ")";
 
1723 String ArgumentList() :
 
1726 final StringBuffer buff = new StringBuffer();
 
1730   {buff.append(expr);}
 
1734       } catch (ParseException e) {
 
1735         errorMessage = "expression expected after a comma in argument list";
 
1737         errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1738         errorEnd   = jj_input_stream.getPosition() + 1;
 
1742       buff.append(",").append(expr);
 
1745    {return buff.toString();}
 
1749  * A Statement without break
 
1751 void StatementNoBreak() :
 
1758   } catch (ParseException e) {
 
1759     if (e.currentToken.next.kind != 4) {
 
1760       errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
1762       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1763       errorEnd   = jj_input_stream.getPosition() + 1;
 
1775   StatementExpression()
 
1778   } catch (ParseException e) {
 
1779     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
1781     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1782     errorEnd   = jj_input_stream.getPosition() + 1;
 
1804   [<AT>] IncludeStatement()
 
1812  * A Normal statement
 
1825   <PHPEND> (phpEchoBlock())* (<PHPSTARTLONG> | <PHPSTARTSHORT>)
 
1829  * An include statement. It's "include" an expression;
 
1831 void IncludeStatement() :
 
1835   final int pos = jj_input_stream.getPosition();
 
1839    | token = <REQUIRE_ONCE>
 
1841    | token = <INCLUDE_ONCE> )
 
1844     if (currentSegment != null) {
 
1845       currentSegment.add(new PHPReqIncDeclaration(currentSegment, token.image,pos,expr));
 
1850   } catch (ParseException e) {
 
1851     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
1853     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1854     errorEnd   = jj_input_stream.getPosition() + 1;
 
1859 String PrintExpression() :
 
1861   final StringBuffer buff = new StringBuffer("print ");
 
1865   <PRINT> expr = Expression()
 
1868     return buff.toString();
 
1872 String ListExpression() :
 
1874   final StringBuffer buff = new StringBuffer("list(");
 
1881   } catch (ParseException e) {
 
1882     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', '(' expected";
 
1884     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1885     errorEnd   = jj_input_stream.getPosition() + 1;
 
1889     expr = VariableDeclaratorId()
 
1890     {buff.append(expr);}
 
1895     } catch (ParseException e) {
 
1896       errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ',' expected";
 
1898       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1899       errorEnd   = jj_input_stream.getPosition() + 1;
 
1902     expr = VariableDeclaratorId()
 
1903     {buff.append(",").append(expr);}
 
1908   } catch (ParseException e) {
 
1909     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"', ')' expected";
 
1911     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1912     errorEnd   = jj_input_stream.getPosition() + 1;
 
1915   [ <ASSIGN> expr = Expression() {buff.append("(").append(expr);}]
 
1916   {return buff.toString();}
 
1920  * An echo statement is like this : echo anyexpression (, otherexpression)*
 
1922 void EchoStatement() :
 
1925   <ECHO> Expression() (<COMMA> Expression())*
 
1928   } catch (ParseException e) {
 
1929     if (e.currentToken.next.kind != 4) {
 
1930       errorMessage = "';' expected after 'echo' statement";
 
1932       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1933       errorEnd   = jj_input_stream.getPosition() + 1;
 
1939 void GlobalStatement() :
 
1941    final int pos = jj_input_stream.getPosition();
 
1946     expr = VariableDeclaratorId()
 
1947     {if (currentSegment != null) {
 
1948       currentSegment.add(new PHPGlobalDeclaration(currentSegment, "global",pos,expr));
 
1951     expr = VariableDeclaratorId()
 
1952     {if (currentSegment != null) {
 
1953       currentSegment.add(new PHPGlobalDeclaration(currentSegment, "global",pos,expr));
 
1958   } catch (ParseException e) {
 
1959     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
1961     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1962     errorEnd   = jj_input_stream.getPosition() + 1;
 
1967 void StaticStatement() :
 
1970   <STATIC> VariableDeclarator() (<COMMA> VariableDeclarator())*
 
1973   } catch (ParseException e) {
 
1974     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
1976     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1977     errorEnd   = jj_input_stream.getPosition() + 1;
 
1982 void LabeledStatement() :
 
1985   <IDENTIFIER> <COLON> Statement()
 
1993   } catch (ParseException e) {
 
1994     errorMessage = "'{' expected";
 
1996     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
1997     errorEnd   = jj_input_stream.getPosition() + 1;
 
2000   ( BlockStatement() | htmlBlock())*
 
2003   } catch (ParseException e) {
 
2004     errorMessage = "unexpected token : '"+ e.currentToken.image +"', '}' expected";
 
2006     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2007     errorEnd   = jj_input_stream.getPosition() + 1;
 
2012 void BlockStatement() :
 
2023  * A Block statement that will not contain any 'break'
 
2025 void BlockStatementNoBreak() :
 
2035 void LocalVariableDeclaration() :
 
2038   LocalVariableDeclarator() ( <COMMA> LocalVariableDeclarator() )*
 
2041 void LocalVariableDeclarator() :
 
2044   VariableDeclaratorId() [ <ASSIGN> Expression() ]
 
2047 void EmptyStatement() :
 
2053 void StatementExpression() :
 
2056   PreIncDecExpression()
 
2064     AssignmentOperator() Expression()
 
2068 void SwitchStatement() :
 
2070   final int pos = jj_input_stream.getPosition();
 
2076   } catch (ParseException e) {
 
2077     errorMessage = "'(' expected after 'switch'";
 
2079     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2080     errorEnd   = jj_input_stream.getPosition() + 1;
 
2086   } catch (ParseException e) {
 
2087     errorMessage = "')' expected";
 
2089     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2090     errorEnd   = jj_input_stream.getPosition() + 1;
 
2093   (switchStatementBrace() | switchStatementColon(pos, pos + 6))
 
2096 void switchStatementBrace() :
 
2103   } catch (ParseException e) {
 
2104     errorMessage = "'}' expected";
 
2106     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2107     errorEnd   = jj_input_stream.getPosition() + 1;
 
2112  * A Switch statement with : ... endswitch;
 
2113  * @param start the begin offset of the switch
 
2114  * @param end the end offset of the switch
 
2116 void switchStatementColon(final int start, final int end) :
 
2121   setMarker(fileToParse,
 
2122             "Ugly syntax detected, you should switch () {...} instead of switch (): ... enswitch;",
 
2126             "Line " + token.beginLine);
 
2127   } catch (CoreException e) {
 
2128     PHPeclipsePlugin.log(e);
 
2133   } catch (ParseException e) {
 
2134     errorMessage = "'endswitch' expected";
 
2136     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2137     errorEnd   = jj_input_stream.getPosition() + 1;
 
2142   } catch (ParseException e) {
 
2143     errorMessage = "';' expected after 'endswitch' keyword";
 
2145     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2146     errorEnd   = jj_input_stream.getPosition() + 1;
 
2151 void switchLabel0() :
 
2153   Token breakToken = null;
 
2157   line = SwitchLabel()
 
2158   ( BlockStatementNoBreak() | htmlBlock() )*
 
2159   [ breakToken = BreakStatement() ]
 
2162       if (breakToken == null) {
 
2163         setMarker(fileToParse,
 
2164                   "You should use put a 'break' at the end of your statement",
 
2169     } catch (CoreException e) {
 
2170       PHPeclipsePlugin.log(e);
 
2175 Token BreakStatement() :
 
2180   token = <BREAK> [ Expression() ]
 
2183   } catch (ParseException e) {
 
2184     errorMessage = "';' expected after 'break' keyword";
 
2186     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2187     errorEnd   = jj_input_stream.getPosition() + 1;
 
2201   } catch (ParseException e) {
 
2202     if (errorMessage != null) throw e;
 
2203     errorMessage = "expression expected after 'case' keyword";
 
2205     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2206     errorEnd   = jj_input_stream.getPosition() + 1;
 
2211   } catch (ParseException e) {
 
2212     errorMessage = "':' expected after case expression";
 
2214     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2215     errorEnd   = jj_input_stream.getPosition() + 1;
 
2218   {return token.beginLine;}
 
2223   } catch (ParseException e) {
 
2224     errorMessage = "':' expected after 'default' keyword";
 
2226     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2227     errorEnd   = jj_input_stream.getPosition() + 1;
 
2230   {return token.beginLine;}
 
2233 void IfStatement() :
 
2236   final int pos = jj_input_stream.getPosition();
 
2239   token = <IF> Condition("if") IfStatement0(pos,pos+token.image.length())
 
2242 void Condition(final String keyword) :
 
2247   } catch (ParseException e) {
 
2248     errorMessage = "'(' expected after " + keyword + " keyword";
 
2250     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length();
 
2251     errorEnd   = errorStart +1;
 
2252     processParseException(e);
 
2257   } catch (ParseException e) {
 
2258     errorMessage = "')' expected after " + keyword + " keyword";
 
2260     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2261     errorEnd   = jj_input_stream.getPosition() + 1;
 
2266 void IfStatement0(final int start,final int end) :
 
2269   <COLON> (Statement() | htmlBlock())* (ElseIfStatementColon())* [ElseStatementColon()]
 
2272   setMarker(fileToParse,
 
2273             "Ugly syntax detected, you should if () {...} instead of if (): ... endif;",
 
2277             "Line " + token.beginLine);
 
2278   } catch (CoreException e) {
 
2279     PHPeclipsePlugin.log(e);
 
2283   } catch (ParseException e) {
 
2284     errorMessage = "'endif' expected";
 
2286     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2287     errorEnd   = jj_input_stream.getPosition() + 1;
 
2292   } catch (ParseException e) {
 
2293     errorMessage = "';' expected after 'endif' keyword";
 
2295     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2296     errorEnd   = jj_input_stream.getPosition() + 1;
 
2300   (Statement() |  htmlBlock())
 
2301   ( LOOKAHEAD(1) ElseIfStatement() )*
 
2306     } catch (ParseException e) {
 
2307       if (errorMessage != null) {
 
2310       errorMessage = "unexpected token '"+e.currentToken.next.image+"', a statement was expected";
 
2312       errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2313       errorEnd   = jj_input_stream.getPosition() + 1;
 
2319 void ElseIfStatementColon() :
 
2322   <ELSEIF> Condition("elseif") <COLON> (Statement() | htmlBlock())*
 
2325 void ElseStatementColon() :
 
2328   <ELSE> <COLON> (Statement() | htmlBlock())*
 
2331 void ElseIfStatement() :
 
2334   <ELSEIF> Condition("elseif") Statement()
 
2337 void WhileStatement() :
 
2340   final int pos = jj_input_stream.getPosition();
 
2343   token = <WHILE> Condition("while") WhileStatement0(pos,pos + token.image.length())
 
2346 void WhileStatement0(final int start, final int end) :
 
2349   <COLON> (Statement())*
 
2351   setMarker(fileToParse,
 
2352             "Ugly syntax detected, you should while () {...} instead of while (): ... endwhile;",
 
2356             "Line " + token.beginLine);
 
2357   } catch (CoreException e) {
 
2358     PHPeclipsePlugin.log(e);
 
2362   } catch (ParseException e) {
 
2363     errorMessage = "'endwhile' expected";
 
2365     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2366     errorEnd   = jj_input_stream.getPosition() + 1;
 
2371   } catch (ParseException e) {
 
2372     errorMessage = "';' expected after 'endwhile' keyword";
 
2374     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2375     errorEnd   = jj_input_stream.getPosition() + 1;
 
2382 void DoStatement() :
 
2385   <DO> Statement() <WHILE> Condition("while")
 
2388   } catch (ParseException e) {
 
2389     errorMessage = "unexpected token : '"+ e.currentToken.next.image +"'. A ';' was expected";
 
2391     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2392     errorEnd   = jj_input_stream.getPosition() + 1;
 
2397 void ForeachStatement() :
 
2403   } catch (ParseException e) {
 
2404     errorMessage = "'(' expected after 'foreach' keyword";
 
2406     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2407     errorEnd   = jj_input_stream.getPosition() + 1;
 
2412   } catch (ParseException e) {
 
2413     errorMessage = "variable expected";
 
2415     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2416     errorEnd   = jj_input_stream.getPosition() + 1;
 
2419   ( VariableSuffix() )*
 
2422   } catch (ParseException e) {
 
2423     errorMessage = "'as' expected";
 
2425     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2426     errorEnd   = jj_input_stream.getPosition() + 1;
 
2431   } catch (ParseException e) {
 
2432     errorMessage = "variable expected";
 
2434     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2435     errorEnd   = jj_input_stream.getPosition() + 1;
 
2438   [ <ARRAYASSIGN> Expression() ]
 
2441   } catch (ParseException e) {
 
2442     errorMessage = "')' expected after 'foreach' keyword";
 
2444     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2445     errorEnd   = jj_input_stream.getPosition() + 1;
 
2450   } catch (ParseException e) {
 
2451     if (errorMessage != null) throw e;
 
2452     errorMessage = "statement expected";
 
2454     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2455     errorEnd   = jj_input_stream.getPosition() + 1;
 
2460 void ForStatement() :
 
2463 final int pos = jj_input_stream.getPosition();
 
2469   } catch (ParseException e) {
 
2470     errorMessage = "'(' expected after 'for' keyword";
 
2472     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2473     errorEnd   = jj_input_stream.getPosition() + 1;
 
2476      [ ForInit() ] <SEMICOLON> [ Expression() ] <SEMICOLON> [ StatementExpressionList() ] <RPAREN>
 
2480       <COLON> (Statement())*
 
2483         setMarker(fileToParse,
 
2484                   "Ugly syntax detected, you should for () {...} instead of for (): ... endfor;",
 
2486                   pos+token.image.length(),
 
2488                   "Line " + token.beginLine);
 
2489         } catch (CoreException e) {
 
2490           PHPeclipsePlugin.log(e);
 
2495       } catch (ParseException e) {
 
2496         errorMessage = "'endfor' expected";
 
2498         errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2499         errorEnd   = jj_input_stream.getPosition() + 1;
 
2504       } catch (ParseException e) {
 
2505         errorMessage = "';' expected after 'endfor' keyword";
 
2507         errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2508         errorEnd   = jj_input_stream.getPosition() + 1;
 
2517   LOOKAHEAD(LocalVariableDeclaration())
 
2518   LocalVariableDeclaration()
 
2520   StatementExpressionList()
 
2523 void StatementExpressionList() :
 
2526   StatementExpression() ( <COMMA> StatementExpression() )*
 
2529 void ContinueStatement() :
 
2532   <CONTINUE> [ Expression() ]
 
2535   } catch (ParseException e) {
 
2536     errorMessage = "';' expected after 'continue' statement";
 
2538     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2539     errorEnd   = jj_input_stream.getPosition() + 1;
 
2544 void ReturnStatement() :
 
2547   <RETURN> [ Expression() ]
 
2550   } catch (ParseException e) {
 
2551     errorMessage = "';' expected after 'return' statement";
 
2553     errorStart = jj_input_stream.getPosition() - e.currentToken.next.image.length() + 1;
 
2554     errorEnd   = jj_input_stream.getPosition() + 1;