1 /*******************************************************************************
 
   2  * Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de All rights
 
   3  * reserved. This program and the accompanying material are made available under
 
   4  * the terms of the Common Public License v1.0 which accompanies this
 
   5  * distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html
 
   7  * Contributors: Klaus Hartlage - www.eclipseproject.de
 
   8  ******************************************************************************/
 
   9 package net.sourceforge.phpdt.internal.compiler.parser;
 
  10 import java.util.ArrayList;
 
  12 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  13 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  14 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  15 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 
  16 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
 
  17 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
 
  18 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
 
  19 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  20 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
 
  21 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  22 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
 
  23 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
 
  24 import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
 
  25 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
 
  26 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
 
  27 import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
 
  28 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
 
  29 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
 
  30 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
 
  32 import org.eclipse.core.resources.IFile;
 
  33 public class Parser //extends PHPParserSuperclass
 
  34     implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
 
  35   //internal data for the automat
 
  36   protected final static int StackIncrement = 255;
 
  37   protected int stateStackTop;
 
  38   protected int[] stack = new int[StackIncrement];
 
  39   public int firstToken; // handle for multiple parsing goals
 
  40   public int lastAct; //handle for multiple parsing goals
 
  41   protected RecoveredElement currentElement;
 
  42   public static boolean VERBOSE_RECOVERY = false;
 
  43   protected boolean diet = false; //tells the scanner to jump over some
 
  44   // parts of the code/expressions like
 
  47   public Scanner scanner;
 
  48   private ArrayList phpList;
 
  49   private int currentPHPString;
 
  50   private boolean phpEnd;
 
  51   // private static HashMap keywordMap = null;
 
  57   // row counter for syntax errors:
 
  59   // column counter for syntax errors:
 
  63   //    // current identifier
 
  67   private String stringValue;
 
  68   /** Contains the current expression. */
 
  69   // private StringBuffer expression;
 
  70   //private boolean phpMode;
 
  71   protected int modifiers;
 
  72   protected int modifiersSourceStart;
 
  73 //  protected IdentifierIndexManager indexManager;
 
  75   protected Parser(ProblemReporter problemReporter) {
 
  76     this.problemReporter = problemReporter;
 
  77     this.options = problemReporter.options;
 
  78     this.currentPHPString = 0;
 
  79     //          PHPParserSuperclass.fileToParse = fileToParse;
 
  81 //    this.indexManager = null;
 
  83     this.token = TokenNameEOF;
 
  86     //    this.columnCount = 0;
 
  89     this.initializeScanner();
 
  91   public void setFileToParse(IFile fileToParse) {
 
  92     this.currentPHPString = 0;
 
  93     //    PHPParserSuperclass.fileToParse = fileToParse;
 
  95 //    this.indexManager = null;
 
  97     this.token = TokenNameEOF;
 
  99     this.initializeScanner();
 
 102    * ClassDeclaration Constructor.
 
 106    *          Description of Parameter
 
 109   public Parser(IFile fileToParse) {
 
 110     //    if (keywordMap == null) {
 
 111     //      keywordMap = new HashMap();
 
 112     //      for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 113     //        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 116     this.currentPHPString = 0;
 
 117     //    PHPParserSuperclass.fileToParse = fileToParse;
 
 119     this.includesList = null;
 
 121     this.token = TokenNameEOF;
 
 123     //    this.rowCount = 1;
 
 124     //    this.columnCount = 0;
 
 127     this.initializeScanner();
 
 129   public void initializeScanner() {
 
 130     this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options
 
 131         .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false,
 
 132         this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */);
 
 135    * Create marker for the parse error
 
 137   //  private void setMarker(String message, int charStart, int charEnd, int
 
 139   //    setMarker(fileToParse, message, charStart, charEnd, errorLevel);
 
 142    * This method will throw the SyntaxError. It will add the good lines and
 
 143    * columns to the Error
 
 147    * @throws SyntaxError
 
 150   private void throwSyntaxError(String error) {
 
 151     int problemStartPosition = scanner.getCurrentTokenStartPosition();
 
 152     int problemEndPosition = scanner.getCurrentTokenEndPosition();
 
 153     throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
 
 156    * This method will throw the SyntaxError. It will add the good lines and
 
 157    * columns to the Error
 
 161    * @throws SyntaxError
 
 164   //  private void throwSyntaxError(String error, int startRow) {
 
 165   //    throw new SyntaxError(startRow, 0, " ", error);
 
 167   private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
 
 168     problemReporter.phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
 
 169         compilationUnit.compilationResult);
 
 170     throw new SyntaxError(1, 0, " ", error);
 
 172   private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
 
 173     problemReporter.phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
 
 174         compilationUnit.compilationResult);
 
 176   private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) {
 
 177     problemReporter.phpParsingWarning(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
 
 178         compilationUnit.compilationResult);
 
 181    * Method Declaration.
 
 185   //  private void getChar() {
 
 186   //    if (str.length() > chIndx) {
 
 187   //      ch = str.charAt(chIndx++);
 
 192   //    chIndx = str.length() + 1;
 
 194   //    // token = TokenNameEOF;
 
 198    * gets the next token from input
 
 200   private void getNextToken() {
 
 202       token = scanner.getNextToken();
 
 204         int currentEndPosition = scanner.getCurrentTokenEndPosition();
 
 205         int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
 206         System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
 
 207         System.out.println(scanner.toStringAction(token));
 
 209     } catch (InvalidInputException e) {
 
 210       token = TokenNameERROR;
 
 211       String detailedMessage = e.getMessage();
 
 213       if (detailedMessage==Scanner.UNTERMINATED_STRING) {
 
 214         throwSyntaxError("Unterminated string.");
 
 215       } else if (detailedMessage==Scanner.UNTERMINATED_COMMENT) {
 
 216         throwSyntaxError("Unterminated commment.");
 
 221   public void init(String s) {
 
 223     this.token = TokenNameEOF;
 
 225     //    this.rowCount = 1;
 
 226     //    this.columnCount = 0;
 
 228     //    this.phpMode = false;
 
 229     /* scanner initialization */
 
 230     scanner.setSource(s.toCharArray());
 
 231     scanner.setPHPMode(false);
 
 233   protected void initialize(boolean phpMode) {
 
 234     initialize(phpMode, null);
 
 236   protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) {
 
 237     compilationUnit = null;
 
 238     referenceContext = null;
 
 239     includesList = new ArrayList();
 
 240 //    this.indexManager = indexManager;
 
 242     this.token = TokenNameEOF;
 
 244     //    this.rowCount = 1;
 
 245     //    this.columnCount = 0;
 
 247     //    this.phpMode = phpMode;
 
 248     scanner.setPHPMode(phpMode);
 
 251    * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 254   public void parse(String s) {
 
 259    * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 262   protected void parse() {
 
 266         if (token != TokenNameEOF && token != TokenNameERROR) {
 
 269         if (token != TokenNameEOF) {
 
 270           if (token == TokenNameERROR) {
 
 271             throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
 
 273           if (token == TokenNameRPAREN) {
 
 274             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
 276           if (token == TokenNameRBRACE) {
 
 277             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
 279           if (token == TokenNameRBRACKET) {
 
 280             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
 282           if (token == TokenNameLPAREN) {
 
 283             throwSyntaxError("Read character '('; end-of-file not reached.");
 
 285           if (token == TokenNameLBRACE) {
 
 286             throwSyntaxError("Read character '{';  end-of-file not reached.");
 
 288           if (token == TokenNameLBRACKET) {
 
 289             throwSyntaxError("Read character '[';  end-of-file not reached.");
 
 291           throwSyntaxError("End-of-file not reached.");
 
 294       } catch (SyntaxError sytaxErr1) {
 
 295         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
 
 297         //        setMarker(sytaxErr1.getMessage(),
 
 298         // scanner.getCurrentTokenStartPosition(),
 
 299         // scanner.getCurrentTokenEndPosition(), ERROR);
 
 301           // if an error occured,
 
 302           // try to find keywords 'class' or 'function'
 
 303           // to parse the rest of the string
 
 304           while (token != TokenNameEOF && token != TokenNameERROR) {
 
 305             if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) {
 
 310           if (token == TokenNameEOF || token == TokenNameERROR) {
 
 313         } catch (SyntaxError sytaxErr2) {
 
 314           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
 
 316           //          setMarker(sytaxErr2.getMessage(),
 
 317           // scanner.getCurrentTokenStartPosition(),
 
 318           // scanner.getCurrentTokenEndPosition(), ERROR);
 
 327   protected CompilationUnitDeclaration endParse(int act) {
 
 331     if (currentElement != null) {
 
 332       currentElement.topElement().updateParseTree();
 
 333       if (VERBOSE_RECOVERY) {
 
 334         System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
 
 335         System.out.println("--------------------------"); //$NON-NLS-1$
 
 336         System.out.println(compilationUnit);
 
 337         System.out.println("----------------------------------"); //$NON-NLS-1$
 
 340       if (diet & VERBOSE_RECOVERY) {
 
 341         System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
 
 342         System.out.println("--------------------------"); //$NON-NLS-1$
 
 343         System.out.println(compilationUnit);
 
 344         System.out.println("----------------------------------"); //$NON-NLS-1$
 
 347     if (scanner.recordLineSeparator) {
 
 348       compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
 
 350     if (scanner.taskTags != null) {
 
 351       for (int i = 0; i < scanner.foundTaskCount; i++) {
 
 352         problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]),
 
 353             scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
 
 354             scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]);
 
 357     compilationUnit.imports = new ImportReference[includesList.size()];
 
 358     for (int i = 0; i < includesList.size(); i++) {
 
 359       compilationUnit.imports[i] = (ImportReference) includesList.get(i);
 
 361     return compilationUnit;
 
 363   //  public PHPOutlineInfo parseInfo(Object parent, String s) {
 
 364   //    PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
 
 365   //    // Stack stack = new Stack();
 
 366   //    // stack.push(outlineInfo.getDeclarations());
 
 368   //    this.token = TokenNameEOF;
 
 369   //    // this.chIndx = 0;
 
 370   //    // this.rowCount = 1;
 
 371   //    // this.columnCount = 0;
 
 372   //    this.phpEnd = false;
 
 373   //    this.phpMode = false;
 
 374   //    scanner.setSource(s.toCharArray());
 
 375   //    scanner.setPHPMode(false);
 
 378   //    parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
 
 380   //    return outlineInfo;
 
 382   private boolean isVariable() {
 
 383     return token == TokenNameVariable; //  || token == TokenNamethis;
 
 385   //  private void parseDeclarations(PHPOutlineInfo outlineInfo,
 
 386   //      OutlineableWithChildren current, boolean goBack) {
 
 388   //    // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
 
 389   //    PHPSegmentWithChildren temp;
 
 391   //    IPreferenceStore store =
 
 392   // PHPeclipsePlugin.getDefault().getPreferenceStore();
 
 394   //      while (token != TokenNameEOF && token != TokenNameERROR) {
 
 395   //        if (token == TokenNameVariable) {
 
 396   //          ident = scanner.getCurrentIdentifierSource();
 
 397   //          outlineInfo.addVariable(new String(ident));
 
 399   //        } else if (token == TokenNamevar) {
 
 401   //          if (token == TokenNameVariable
 
 402   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
 
 403   //            ident = scanner.getCurrentIdentifierSource();
 
 404   //            //substring(1) added because PHPVarDeclaration doesn't
 
 405   //            // need the $ anymore
 
 406   //            String variableName = new String(ident).substring(1);
 
 407   //            outlineInfo.addVariable(variableName);
 
 409   //            if (token != TokenNameSEMICOLON) {
 
 411   //              ident = scanner.getCurrentTokenSource();
 
 412   //              if (token > TokenNameKEYWORD) {
 
 413   //                current.add(new PHPVarDeclaration(current, variableName,
 
 414   //                // chIndx - ident.length,
 
 415   //                    scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 418   //                  case TokenNameVariable :
 
 419   //                  case TokenNamethis :
 
 420   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 423   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 426   //                  case TokenNameIdentifier :
 
 427   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 430   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 433   //                  case TokenNameDoubleLiteral :
 
 434   //                    current.add(new PHPVarDeclaration(current, variableName
 
 438   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 441   //                  case TokenNameIntegerLiteral :
 
 442   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 445   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 448   //                  case TokenNameStringInterpolated :
 
 449   //                  case TokenNameStringLiteral :
 
 450   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 453   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 456   //                  case TokenNameStringConstant :
 
 457   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 460   //                        scanner.getCurrentTokenStartPosition(), new String(
 
 464   //                    current.add(new PHPVarDeclaration(current, variableName,
 
 467   //                        scanner.getCurrentTokenStartPosition()));
 
 472   //              ident = scanner.getCurrentIdentifierSource();
 
 473   //              current.add(new PHPVarDeclaration(current, variableName,
 
 474   //              // chIndx - ident.length
 
 475   //                  scanner.getCurrentTokenStartPosition()));
 
 478   //        } else if (token == TokenNamefunction) {
 
 480   //          if (token == TokenNameAND) {
 
 483   //          if (token == TokenNameIdentifier
 
 484   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
 
 485   //            ident = scanner.getCurrentIdentifierSource();
 
 486   //            outlineInfo.addVariable(new String(ident));
 
 487   //            temp = new PHPFunctionDeclaration(current, new String(ident),
 
 488   //            // chIndx - ident.length
 
 489   //                scanner.getCurrentTokenStartPosition());
 
 490   //            current.add(temp);
 
 492   //            parseDeclarations(outlineInfo, temp, true);
 
 494   //        } else if (token == TokenNameclass) {
 
 496   //          if (token == TokenNameIdentifier
 
 497   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
 
 498   //            ident = scanner.getCurrentIdentifierSource();
 
 499   //            outlineInfo.addVariable(new String(ident));
 
 500   //            temp = new PHPClassDeclaration(current, new String(ident),
 
 501   //            // chIndx - ident.len
 
 502   //                scanner.getCurrentTokenStartPosition());
 
 503   //            current.add(temp);
 
 504   //            // stack.push(temp);
 
 506   //            //skip tokens for classname, extends and others until
 
 507   //            // we have the opening '{'
 
 508   //            while (token != TokenNameLBRACE && token != TokenNameEOF
 
 509   //                && token != TokenNameERROR) {
 
 512   //            parseDeclarations(outlineInfo, temp, true);
 
 515   //        } else if ((token == TokenNameLBRACE)
 
 516   //            || (token == TokenNameDOLLAR_LBRACE)) {
 
 519   //        } else if (token == TokenNameRBRACE) {
 
 522   //          if (counter == 0 && goBack) {
 
 525   //        } else if (token == TokenNamerequire || token == TokenNamerequire_once
 
 526   //            || token == TokenNameinclude || token == TokenNameinclude_once) {
 
 527   //          ident = scanner.getCurrentTokenSource();
 
 529   //          int startPosition = scanner.getCurrentTokenStartPosition();
 
 531   //          char[] expr = scanner.getCurrentTokenSource(startPosition);
 
 532   //          outlineInfo.addVariable(new String(ident));
 
 533   //          current.add(new PHPReqIncDeclaration(current, new String(ident),
 
 534   //          // chIndx - ident.length,
 
 535   //              startPosition, new String(expr)));
 
 541   //    } catch (SyntaxError sytaxErr) {
 
 543   //      // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
 
 544   //      // setMarker(sytaxErr.getMessage(),
 
 545   //      // scanner.getCurrentTokenStartPosition(),
 
 546   //      // scanner.getCurrentTokenEndPosition(), ERROR);
 
 547   //      // } catch (CoreException e) {
 
 551   private void statementList() {
 
 553       statement(TokenNameEOF);
 
 554       if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
 
 555           || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
 
 556           || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
 
 557           || (token == TokenNameEOF) || (token == TokenNameERROR)) {
 
 562   private void functionBody(MethodDeclaration methodDecl) {
 
 563     // '{' [statement-list] '}'
 
 564     if (token == TokenNameLBRACE) {
 
 567       throwSyntaxError("'{' expected in compound-statement.");
 
 569     if (token != TokenNameRBRACE) {
 
 572     if (token == TokenNameRBRACE) {
 
 573       methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
 576       throwSyntaxError("'}' expected in compound-statement.");
 
 579   private void statement(int previousToken) {
 
 580     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
 
 582     //  char[] ident = scanner.getCurrentIdentifierSource();
 
 583     //  String keyword = new String(ident);
 
 584     //    if (token == TokenNameAT) {
 
 586     //      if (token != TokenNamerequire && token != TokenNamerequire_once
 
 587     //          && token != TokenNameinclude && token != TokenNameinclude_once
 
 588     //          && token != TokenNameIdentifier && token != TokenNameVariable
 
 589     //          && token != TokenNameStringInterpolated) {
 
 590     //        throwSyntaxError("identifier expected after '@'.");
 
 593     //    if (token == TokenNameinclude || token == TokenNameinclude_once) {
 
 595     //      if (token == TokenNameLPAREN) {
 
 597     //        if (token == TokenNameSEMICOLON) {
 
 600     //          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
 
 601     //            throwSyntaxError("';' expected after 'include' or 'include_once'.");
 
 603     //          // getNextToken();
 
 606     //        concatenationExpression();
 
 609     //    } else if (token == TokenNamerequire || token ==
 
 610     // TokenNamerequire_once)
 
 614     //      if (token == TokenNameLPAREN) {
 
 616     //        if (token == TokenNameSEMICOLON) {
 
 619     //          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
 
 620     //            throwSyntaxError("';' expected after 'require' or 'require_once'.");
 
 622     //          // getNextToken();
 
 625     //        concatenationExpression();
 
 629     if (token == TokenNameif) {
 
 631       if (token == TokenNameLPAREN) {
 
 634         throwSyntaxError("'(' expected after 'if' keyword.");
 
 637       if (token == TokenNameRPAREN) {
 
 640         throwSyntaxError("')' expected after 'if' condition.");
 
 644     } else if (token == TokenNameswitch) {
 
 646       if (token == TokenNameLPAREN) {
 
 649         throwSyntaxError("'(' expected after 'switch' keyword.");
 
 652       if (token == TokenNameRPAREN) {
 
 655         throwSyntaxError("')' expected after 'switch' condition.");
 
 659     } else if (token == TokenNamefor) {
 
 661       if (token == TokenNameLPAREN) {
 
 664         throwSyntaxError("'(' expected after 'for' keyword.");
 
 666       if (token == TokenNameSEMICOLON) {
 
 670         if (token == TokenNameSEMICOLON) {
 
 673           throwSyntaxError("';' expected after 'for'.");
 
 676       if (token == TokenNameSEMICOLON) {
 
 680         if (token == TokenNameSEMICOLON) {
 
 683           throwSyntaxError("';' expected after 'for'.");
 
 686       if (token == TokenNameRPAREN) {
 
 690         if (token == TokenNameRPAREN) {
 
 693           throwSyntaxError("')' expected after 'for'.");
 
 698     } else if (token == TokenNamewhile) {
 
 700       if (token == TokenNameLPAREN) {
 
 703         throwSyntaxError("'(' expected after 'while' keyword.");
 
 706       if (token == TokenNameRPAREN) {
 
 709         throwSyntaxError("')' expected after 'while' condition.");
 
 713     } else if (token == TokenNamedo) {
 
 715       if (token == TokenNameLBRACE) {
 
 717         if (token != TokenNameRBRACE) {
 
 720         if (token == TokenNameRBRACE) {
 
 723           throwSyntaxError("'}' expected after 'do' keyword.");
 
 726         statement(TokenNameEOF);
 
 728       if (token == TokenNamewhile) {
 
 730         if (token == TokenNameLPAREN) {
 
 733           throwSyntaxError("'(' expected after 'while' keyword.");
 
 736         if (token == TokenNameRPAREN) {
 
 739           throwSyntaxError("')' expected after 'while' condition.");
 
 742         throwSyntaxError("'while' expected after 'do' keyword.");
 
 744       if (token == TokenNameSEMICOLON) {
 
 747         if (token != TokenNameINLINE_HTML) {
 
 748           throwSyntaxError("';' expected after do-while statement.");
 
 753     } else if (token == TokenNameforeach) {
 
 755       if (token == TokenNameLPAREN) {
 
 758         throwSyntaxError("'(' expected after 'foreach' keyword.");
 
 761       if (token == TokenNameas) {
 
 764         throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
 768       foreach_optional_arg();
 
 769       if (token == TokenNameEQUAL_GREATER) {
 
 773       if (token == TokenNameRPAREN) {
 
 776         throwSyntaxError("')' expected after 'foreach' expression.");
 
 780     } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
 
 782       if (token != TokenNameSEMICOLON) {
 
 785       if (token == TokenNameSEMICOLON) {
 
 788         if (token != TokenNameINLINE_HTML) {
 
 789           throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
 
 794     } else if (token == TokenNameecho) {
 
 797       if (token == TokenNameSEMICOLON) {
 
 800         if (token != TokenNameINLINE_HTML) {
 
 801           throwSyntaxError("';' expected after 'echo' statement.");
 
 806     } else if (token == TokenNameINLINE_HTML) {
 
 809       //    } else if (token == TokenNameprint) {
 
 812       //      if (token == TokenNameSEMICOLON) {
 
 815       //        if (token != TokenNameStopPHP) {
 
 816       //          throwSyntaxError("';' expected after 'print' statement.");
 
 821     } else if (token == TokenNameglobal) {
 
 824       if (token == TokenNameSEMICOLON) {
 
 827         if (token != TokenNameINLINE_HTML) {
 
 828           throwSyntaxError("';' expected after 'global' statement.");
 
 833     } else if (token == TokenNamestatic) {
 
 836       if (token == TokenNameSEMICOLON) {
 
 839         if (token != TokenNameINLINE_HTML) {
 
 840           throwSyntaxError("';' expected after 'static' statement.");
 
 845     } else if (token == TokenNameunset) {
 
 847       if (token == TokenNameLPAREN) {
 
 850         throwSyntaxError("'(' expected after 'unset' statement.");
 
 853       if (token == TokenNameRPAREN) {
 
 856         throwSyntaxError("')' expected after 'unset' statement.");
 
 858       if (token == TokenNameSEMICOLON) {
 
 861         if (token != TokenNameINLINE_HTML) {
 
 862           throwSyntaxError("';' expected after 'unset' statement.");
 
 867     } else if (token == TokenNamefunction) {
 
 868       MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
 
 869       methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
 870       methodDecl.modifiers = AccDefault;
 
 872       functionDefinition(methodDecl);
 
 874     } else if (token == TokenNametry) {
 
 876       if (token != TokenNameLBRACE) {
 
 877         throwSyntaxError("'{' expected in 'try' statement.");
 
 881       if (token != TokenNameRBRACE) {
 
 882         throwSyntaxError("'}' expected in 'try' statement.");
 
 886     } else if (token == TokenNamecatch) {
 
 888       if (token != TokenNameLPAREN) {
 
 889         throwSyntaxError("'(' expected in 'catch' statement.");
 
 892       fully_qualified_class_name();
 
 893       if (token != TokenNameVariable) {
 
 894         throwSyntaxError("Variable expected in 'catch' statement.");
 
 897       if (token != TokenNameRPAREN) {
 
 898         throwSyntaxError("')' expected in 'catch' statement.");
 
 901       if (token != TokenNameLBRACE) {
 
 902         throwSyntaxError("'{' expected in 'catch' statement.");
 
 905       if (token != TokenNameRBRACE) {
 
 907         if (token != TokenNameRBRACE) {
 
 908           throwSyntaxError("'}' expected in 'catch' statement.");
 
 912       additional_catches();
 
 914     } else if (token == TokenNamethrow) {
 
 917       if (token == TokenNameSEMICOLON) {
 
 920         throwSyntaxError("';' expected after 'throw' exxpression.");
 
 923     } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
 
 924       TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
 
 925       typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
 926       typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
 927       typeDecl.name = new char[]{' '};
 
 928       // default super class
 
 929       typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
 
 930       compilationUnit.types.add(typeDecl);
 
 932         pushOnAstStack(typeDecl);
 
 933         unticked_class_declaration_statement(typeDecl);
 
 934         //        classBody(typeDecl);
 
 941       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
 
 942     } else if (token == TokenNameLBRACE) {
 
 944       if (token != TokenNameRBRACE) {
 
 947       if (token == TokenNameRBRACE) {
 
 951         throwSyntaxError("'}' expected.");
 
 954       if (token != TokenNameSEMICOLON) {
 
 957       if (token == TokenNameSEMICOLON) {
 
 961         if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
 
 962           throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
 
 968   private void additional_catches() {
 
 969     while (token == TokenNamecatch) {
 
 971       if (token != TokenNameLPAREN) {
 
 972         throwSyntaxError("'(' expected in 'catch' statement.");
 
 975       fully_qualified_class_name();
 
 976       if (token != TokenNameVariable) {
 
 977         throwSyntaxError("Variable expected in 'catch' statement.");
 
 980       if (token != TokenNameRPAREN) {
 
 981         throwSyntaxError("')' expected in 'catch' statement.");
 
 984       if (token != TokenNameLBRACE) {
 
 985         throwSyntaxError("'{' expected in 'catch' statement.");
 
 989       if (token != TokenNameRBRACE) {
 
 990         throwSyntaxError("'}' expected in 'catch' statement.");
 
 995   private void foreach_variable() {
 
 998     if (token == TokenNameAND) {
 
1003   private void foreach_optional_arg() {
 
1005     //| T_DOUBLE_ARROW foreach_variable
 
1006     if (token == TokenNameEQUAL_GREATER) {
 
1011   private void global_var_list() {
 
1013     //  global_var_list ',' global_var
 
1017       if (token != TokenNameCOMMA) {
 
1023   private void global_var() {
 
1027     //| '$' '{' expr '}'
 
1028     if (token == TokenNameVariable) {
 
1030     } else if (token == TokenNameDOLLAR) {
 
1032       if (token == TokenNameLPAREN) {
 
1035         if (token != TokenNameLPAREN) {
 
1036           throwSyntaxError("')' expected in global variable.");
 
1044   private void static_var_list() {
 
1046     //  static_var_list ',' T_VARIABLE
 
1047     //| static_var_list ',' T_VARIABLE '=' static_scalar
 
1049     //| T_VARIABLE '=' static_scalar
 
1051       if (token == TokenNameVariable) {
 
1053         if (token == TokenNameEQUAL) {
 
1057         if (token != TokenNameCOMMA) {
 
1066   private void unset_variables() {
 
1069     //          | unset_variables ',' unset_variable
 
1074       if (token != TokenNameCOMMA) {
 
1080   private final void initializeModifiers() {
 
1082     this.modifiersSourceStart = -1;
 
1084   private final void checkAndSetModifiers(int flag) {
 
1085     this.modifiers |= flag;
 
1086     if (this.modifiersSourceStart < 0)
 
1087       this.modifiersSourceStart = this.scanner.startPosition;
 
1089   private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
 
1090     initializeModifiers();
 
1091     if (token == TokenNameinterface) {
 
1092       //      interface_entry T_STRING
 
1093       //                interface_extends_list
 
1094       //                '{' class_statement_list '}'
 
1095       checkAndSetModifiers(AccInterface);
 
1097       typeDecl.modifiers = this.modifiers;
 
1098       typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1099       typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1100       if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
1101         typeDecl.name = scanner.getCurrentIdentifierSource();
 
1102         if (token > TokenNameKEYWORD) {
 
1103           problemReporter.phpKeywordWarning(new String[]{scanner.toStringAction(token)}, scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
 
1104               referenceContext, compilationUnit.compilationResult);
 
1105 //          throwSyntaxError("Don't use a keyword for interface declaration [" + scanner.toStringAction(token) + "].",
 
1106 //              typeDecl.sourceStart, typeDecl.sourceEnd);
 
1109         interface_extends_list();
 
1111         typeDecl.name = new char[]{' '};
 
1112         throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd);
 
1116       //      class_entry_type T_STRING extends_from
 
1118       //                '{' class_statement_list'}'
 
1120       typeDecl.modifiers = this.modifiers;
 
1121       typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1122       typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1124       //identifier 'extends' identifier
 
1125       if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
1126         typeDecl.name = scanner.getCurrentIdentifierSource();
 
1127         if (token > TokenNameKEYWORD) {
 
1128           problemReporter.phpKeywordWarning(new String[]{scanner.toStringAction(token)}, scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
 
1129               referenceContext, compilationUnit.compilationResult);
 
1130 //          throwSyntaxError("Don't use a keyword for class declaration [" + scanner.toStringAction(token) + "].",
 
1131 //              typeDecl.sourceStart, typeDecl.sourceEnd);
 
1136         //      | T_EXTENDS fully_qualified_class_name
 
1137         if (token == TokenNameextends) {
 
1138           interface_extends_list();
 
1140           //          if (token != TokenNameIdentifier) {
 
1141           //            throwSyntaxError("Class name expected after keyword
 
1143           //                scanner.getCurrentTokenStartPosition(), scanner
 
1144           //                    .getCurrentTokenEndPosition());
 
1149         typeDecl.name = new char[]{' '};
 
1150         throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
 
1154     //  '{' class_statement_list '}'
 
1155     if (token == TokenNameLBRACE) {
 
1157       if (token != TokenNameRBRACE) {
 
1158         ArrayList list = new ArrayList();
 
1159         class_statement_list(list);
 
1160         typeDecl.fields = new FieldDeclaration[list.size()];
 
1161         for (int i = 0; i < list.size(); i++) {
 
1162           typeDecl.fields[i] = (FieldDeclaration) list.get(i);
 
1165       if (token == TokenNameRBRACE) {
 
1166         typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1169         throwSyntaxError("'}' expected at end of class body.");
 
1172       throwSyntaxError("'{' expected at start of class body.");
 
1175   private void class_entry_type() {
 
1177     //  | T_ABSTRACT T_CLASS
 
1178     //  | T_FINAL T_CLASS
 
1179     if (token == TokenNameclass) {
 
1181     } else if (token == TokenNameabstract) {
 
1182       checkAndSetModifiers(AccAbstract);
 
1184       if (token != TokenNameclass) {
 
1185         throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
 
1188     } else if (token == TokenNamefinal) {
 
1189       checkAndSetModifiers(AccFinal);
 
1191       if (token != TokenNameclass) {
 
1192         throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
 
1196       throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
 
1199   private void interface_extends_list() {
 
1201     //  | T_EXTENDS interface_list
 
1202     if (token == TokenNameextends) {
 
1207   private void implements_list() {
 
1209     //  | T_IMPLEMENTS interface_list
 
1210     if (token == TokenNameimplements) {
 
1215   private void interface_list() {
 
1217     //  fully_qualified_class_name
 
1218     //| interface_list ',' fully_qualified_class_name
 
1220       if (token == TokenNameIdentifier) {
 
1223         throwSyntaxError("Interface name expected after keyword 'implements'.");
 
1225       if (token != TokenNameCOMMA) {
 
1231   //  private void classBody(TypeDeclaration typeDecl) {
 
1232   //    //'{' [class-element-list] '}'
 
1233   //    if (token == TokenNameLBRACE) {
 
1235   //      if (token != TokenNameRBRACE) {
 
1236   //        class_statement_list();
 
1238   //      if (token == TokenNameRBRACE) {
 
1239   //        typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1242   //        throwSyntaxError("'}' expected at end of class body.");
 
1245   //      throwSyntaxError("'{' expected at start of class body.");
 
1248   private void class_statement_list(ArrayList list) {
 
1250       class_statement(list);
 
1251     } while (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
 
1252         || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
 
1253         || token == TokenNameconst);
 
1255   private void class_statement(ArrayList list) {
 
1257     //          variable_modifiers class_variable_declaration ';'
 
1258     //  | class_constant_declaration ';'
 
1259     //  | method_modifiers T_FUNCTION is_reference T_STRING
 
1260     //    '(' parameter_list ')' method_body
 
1261     initializeModifiers();
 
1262     int declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1264     if (token == TokenNamevar) {
 
1265       checkAndSetModifiers(AccPublic);
 
1266       problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
 
1267           referenceContext, compilationUnit.compilationResult);
 
1269       class_variable_declaration(declarationSourceStart, list);
 
1270     } else if (token == TokenNameconst) {
 
1271       checkAndSetModifiers(AccFinal|AccPublic);
 
1272       class_constant_declaration(declarationSourceStart, list);
 
1273       if (token != TokenNameSEMICOLON) {
 
1274         throwSyntaxError("';' expected after class const declaration.");
 
1278       boolean hasModifiers = member_modifiers();
 
1279       if (token == TokenNamefunction) {
 
1280         if (!hasModifiers) {
 
1281           checkAndSetModifiers(AccPublic);
 
1283         MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
 
1284         methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1285         methodDecl.modifiers = this.modifiers;
 
1287         functionDefinition(methodDecl);
 
1289         if (!hasModifiers) {
 
1290           throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
 
1292         class_variable_declaration(declarationSourceStart, list);
 
1296   private void class_constant_declaration(int declarationSourceStart, ArrayList list) {
 
1297     //  class_constant_declaration ',' T_STRING '=' static_scalar
 
1298     //  | T_CONST T_STRING '=' static_scalar
 
1299     if (token != TokenNameconst) {
 
1300       throwSyntaxError("'const' keyword expected in class declaration.");
 
1305       if (token != TokenNameIdentifier) {
 
1306         throwSyntaxError("Identifier expected in class const declaration.");
 
1308       FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
 
1309           .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
 
1310       fieldDeclaration.modifiers = this.modifiers;
 
1311       fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1312       fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1313       fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1314       //        fieldDeclaration.type
 
1315       list.add(fieldDeclaration);
 
1317       if (token != TokenNameEQUAL) {
 
1318         throwSyntaxError("'=' expected in class const declaration.");
 
1322       if (token != TokenNameCOMMA) {
 
1323         break; // while(true)-loop
 
1328   //  private void variable_modifiers() {
 
1329   //    // variable_modifiers:
 
1330   //    // non_empty_member_modifiers
 
1332   //    initializeModifiers();
 
1333   //    if (token == TokenNamevar) {
 
1334   //      checkAndSetModifiers(AccPublic);
 
1335   //      reportSyntaxError(
 
1336   //          "Keyword 'var' is deprecated. Please use 'public' 'private' or
 
1338   // modifier for field declarations.",
 
1339   //          scanner.getCurrentTokenStartPosition(), scanner
 
1340   //              .getCurrentTokenEndPosition());
 
1343   //      if (!member_modifiers()) {
 
1344   //        throwSyntaxError("'public' 'private' or 'protected' modifier expected for
 
1345   // field declarations.");
 
1349   //  private void method_modifiers() {
 
1350   //    //method_modifiers:
 
1352   //    //| non_empty_member_modifiers
 
1353   //    initializeModifiers();
 
1354   //    if (!member_modifiers()) {
 
1355   //      checkAndSetModifiers(AccPublic);
 
1358   private boolean member_modifiers() {
 
1365     boolean foundToken = false;
 
1367       if (token == TokenNamepublic) {
 
1368         checkAndSetModifiers(AccPublic);
 
1371       } else if (token == TokenNameprotected) {
 
1372         checkAndSetModifiers(AccProtected);
 
1375       } else if (token == TokenNameprivate) {
 
1376         checkAndSetModifiers(AccPrivate);
 
1379       } else if (token == TokenNamestatic) {
 
1380         checkAndSetModifiers(AccStatic);
 
1383       } else if (token == TokenNameabstract) {
 
1384         checkAndSetModifiers(AccAbstract);
 
1387       } else if (token == TokenNamefinal) {
 
1388         checkAndSetModifiers(AccFinal);
 
1397   private void class_variable_declaration(int declarationSourceStart, ArrayList list) {
 
1398     //    class_variable_declaration:
 
1399     //          class_variable_declaration ',' T_VARIABLE
 
1400     //  | class_variable_declaration ',' T_VARIABLE '=' static_scalar
 
1402     //  | T_VARIABLE '=' static_scalar
 
1403     char[] classVariable;
 
1405       if (token == TokenNameVariable) {
 
1406         classVariable = scanner.getCurrentIdentifierSource();
 
1407       //  indexManager.addIdentifierInformation('v', classVariable, buf, -1, -1);
 
1408         FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner
 
1409             .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
 
1410         fieldDeclaration.modifiers = this.modifiers;
 
1411         fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1412         fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1413         fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1414         //        fieldDeclaration.type
 
1415         list.add(fieldDeclaration);
 
1417         if (token == TokenNameEQUAL) {
 
1422         //        if (token == TokenNamethis) {
 
1423         //          throwSyntaxError("'$this' not allowed after keyword 'public'
 
1424         // 'protected' 'private' 'var'.");
 
1426         throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
 
1428       if (token != TokenNameCOMMA) {
 
1433     if (token != TokenNameSEMICOLON) {
 
1434       throwSyntaxError("';' expected after field declaration.");
 
1438   private void functionDefinition(MethodDeclaration methodDecl) {
 
1439     boolean isAbstract = false;
 
1441       compilationUnit.types.add(methodDecl);
 
1443       ASTNode node = astStack[astPtr];
 
1444       if (node instanceof TypeDeclaration) {
 
1445         TypeDeclaration typeDecl = ((TypeDeclaration) node);
 
1446         if (typeDecl.methods == null) {
 
1447           typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
 
1449           AbstractMethodDeclaration[] newMethods;
 
1450           System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1,
 
1451               typeDecl.methods.length);
 
1452           newMethods[0] = methodDecl;
 
1453           typeDecl.methods = newMethods;
 
1455         if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
 
1457         } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
 
1462     functionDeclarator(methodDecl);
 
1463     if (token == TokenNameSEMICOLON) {
 
1465         throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
 
1470     functionBody(methodDecl);
 
1472   private void functionDeclarator(MethodDeclaration methodDecl) {
 
1473     //identifier '(' [parameter-list] ')'
 
1474     if (token == TokenNameAND) {
 
1477     methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1478     methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1479     if (Scanner.isIdentifierOrKeyword(token)) {
 
1480       methodDecl.selector = scanner.getCurrentIdentifierSource();
 
1481       if (token > TokenNameKEYWORD) {
 
1482         problemReporter.phpKeywordWarning(new String[]{scanner.toStringAction(token)}, scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
 
1483             referenceContext, compilationUnit.compilationResult);
 
1484 //        reportSyntaxWarning("Don't use keyword for function declaration [" + scanner.toStringAction(token) + "].",
 
1485 //          scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
 
1488       if (token == TokenNameLPAREN) {
 
1491         throwSyntaxError("'(' expected in function declaration.");
 
1493       if (token != TokenNameRPAREN) {
 
1496       if (token != TokenNameRPAREN) {
 
1497         throwSyntaxError("')' expected in function declaration.");
 
1499         methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
 
1503       methodDecl.selector = "<undefined>".toCharArray();
 
1504       throwSyntaxError("Function name expected after keyword 'function'.");
 
1508   private void parameter_list() {
 
1509     //  non_empty_parameter_list
 
1511     non_empty_parameter_list(true);
 
1513   private void non_empty_parameter_list(boolean empty_allowed) {
 
1514     //  optional_class_type T_VARIABLE
 
1515     //  | optional_class_type '&' T_VARIABLE
 
1516     //  | optional_class_type '&' T_VARIABLE '=' static_scalar
 
1517     //  | optional_class_type T_VARIABLE '=' static_scalar
 
1518     //  | non_empty_parameter_list ',' optional_class_type T_VARIABLE
 
1519     //  | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
 
1520     //  | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
 
1522     //  | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
 
1524     if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
 
1526         if (token == TokenNameIdentifier) {
 
1529         if (token == TokenNameAND) {
 
1532         if (token == TokenNameVariable) {
 
1534           if (token == TokenNameEQUAL) {
 
1539           throwSyntaxError("Variable expected in parameter list.");
 
1541         if (token != TokenNameCOMMA) {
 
1548     if (!empty_allowed) {
 
1549       throwSyntaxError("Identifier expected in parameter list.");
 
1552   private void optional_class_type() {
 
1556   private void parameterDeclaration() {
 
1558     //variable-reference
 
1559     if (token == TokenNameAND) {
 
1564         throwSyntaxError("Variable expected after reference operator '&'.");
 
1567     //variable '=' constant
 
1568     if (token == TokenNameVariable) {
 
1570       if (token == TokenNameEQUAL) {
 
1576     //    if (token == TokenNamethis) {
 
1577     //      throwSyntaxError("Reserved word '$this' not allowed in parameter
 
1581   private void labeledStatementList() {
 
1582     if (token != TokenNamecase && token != TokenNamedefault) {
 
1583       throwSyntaxError("'case' or 'default' expected.");
 
1586       if (token == TokenNamecase) {
 
1588         expr(); //constant();
 
1589         if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
 
1591           if (token == TokenNamecase || token == TokenNamedefault) {
 
1592             // empty case statement ?
 
1597         //        else if (token == TokenNameSEMICOLON) {
 
1599         //            "':' expected after 'case' keyword (Found token: " +
 
1600         // scanner.toStringAction(token) + ")",
 
1601         //            scanner.getCurrentTokenStartPosition(),
 
1602         //            scanner.getCurrentTokenEndPosition(),
 
1605         //          if (token == TokenNamecase) { // empty case statement ?
 
1611           throwSyntaxError("':' character expected after 'case' constant (Found token: " + scanner.toStringAction(token) + ")");
 
1613       } else { // TokenNamedefault
 
1615         if (token == TokenNameCOLON) {
 
1617           if (token == TokenNameRBRACE) {
 
1618             // empty default case
 
1621           if (token != TokenNamecase) {
 
1625           throwSyntaxError("':' character expected after 'default'.");
 
1628     } while (token == TokenNamecase || token == TokenNamedefault);
 
1630   //  public void labeledStatement() {
 
1631   //    if (token == TokenNamecase) {
 
1634   //      if (token == TokenNameDDOT) {
 
1638   //        throwSyntaxError("':' character after 'case' constant expected.");
 
1641   //    } else if (token == TokenNamedefault) {
 
1643   //      if (token == TokenNameDDOT) {
 
1647   //        throwSyntaxError("':' character after 'default' expected.");
 
1652   //  public void expressionStatement() {
 
1654   //  private void inclusionStatement() {
 
1656   //  public void compoundStatement() {
 
1658   //  public void selectionStatement() {
 
1661   //  public void iterationStatement() {
 
1664   //  public void jumpStatement() {
 
1667   //  public void outputStatement() {
 
1670   //  public void scopeStatement() {
 
1673   //  public void flowStatement() {
 
1676   //  public void definitionStatement() {
 
1678   private void ifStatement() {
 
1679     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
 
1680     if (token == TokenNameCOLON) {
 
1682       if (token != TokenNameendif) {
 
1685           case TokenNameelse :
 
1687             if (token == TokenNameCOLON) {
 
1689               if (token != TokenNameendif) {
 
1693               if (token == TokenNameif) { //'else if'
 
1695                 elseifStatementList();
 
1697                 throwSyntaxError("':' expected after 'else'.");
 
1701           case TokenNameelseif :
 
1703             elseifStatementList();
 
1707       if (token != TokenNameendif) {
 
1708         throwSyntaxError("'endif' expected.");
 
1711       if (token != TokenNameSEMICOLON) {
 
1712         throwSyntaxError("';' expected after if-statement.");
 
1716       // statement [else-statement]
 
1717       statement(TokenNameEOF);
 
1718       if (token == TokenNameelseif) {
 
1720         if (token == TokenNameLPAREN) {
 
1723           throwSyntaxError("'(' expected after 'elseif' keyword.");
 
1726         if (token == TokenNameRPAREN) {
 
1729           throwSyntaxError("')' expected after 'elseif' condition.");
 
1732       } else if (token == TokenNameelse) {
 
1734         statement(TokenNameEOF);
 
1738   private void elseifStatementList() {
 
1742         case TokenNameelse :
 
1744           if (token == TokenNameCOLON) {
 
1746             if (token != TokenNameendif) {
 
1751             if (token == TokenNameif) { //'else if'
 
1754               throwSyntaxError("':' expected after 'else'.");
 
1758         case TokenNameelseif :
 
1766   private void elseifStatement() {
 
1767     if (token == TokenNameLPAREN) {
 
1770       if (token != TokenNameRPAREN) {
 
1771         throwSyntaxError("')' expected in else-if-statement.");
 
1774       if (token != TokenNameCOLON) {
 
1775         throwSyntaxError("':' expected in else-if-statement.");
 
1778       if (token != TokenNameendif) {
 
1783   private void switchStatement() {
 
1784     if (token == TokenNameCOLON) {
 
1785       // ':' [labeled-statement-list] 'endswitch' ';'
 
1787       labeledStatementList();
 
1788       if (token != TokenNameendswitch) {
 
1789         throwSyntaxError("'endswitch' expected.");
 
1792       if (token != TokenNameSEMICOLON) {
 
1793         throwSyntaxError("';' expected after switch-statement.");
 
1797       // '{' [labeled-statement-list] '}'
 
1798       if (token != TokenNameLBRACE) {
 
1799         throwSyntaxError("'{' expected in switch statement.");
 
1802       if (token != TokenNameRBRACE) {
 
1803         labeledStatementList();
 
1805       if (token != TokenNameRBRACE) {
 
1806         throwSyntaxError("'}' expected in switch statement.");
 
1811   private void forStatement() {
 
1812     if (token == TokenNameCOLON) {
 
1815       if (token != TokenNameendfor) {
 
1816         throwSyntaxError("'endfor' expected.");
 
1819       if (token != TokenNameSEMICOLON) {
 
1820         throwSyntaxError("';' expected after for-statement.");
 
1824       statement(TokenNameEOF);
 
1827   private void whileStatement() {
 
1828     // ':' statement-list 'endwhile' ';'
 
1829     if (token == TokenNameCOLON) {
 
1832       if (token != TokenNameendwhile) {
 
1833         throwSyntaxError("'endwhile' expected.");
 
1836       if (token != TokenNameSEMICOLON) {
 
1837         throwSyntaxError("';' expected after while-statement.");
 
1841       statement(TokenNameEOF);
 
1844   private void foreachStatement() {
 
1845     if (token == TokenNameCOLON) {
 
1848       if (token != TokenNameendforeach) {
 
1849         throwSyntaxError("'endforeach' expected.");
 
1852       if (token != TokenNameSEMICOLON) {
 
1853         throwSyntaxError("';' expected after foreach-statement.");
 
1857       statement(TokenNameEOF);
 
1860   //  private void exitStatus() {
 
1861   //    if (token == TokenNameLPAREN) {
 
1864   //      throwSyntaxError("'(' expected in 'exit-status'.");
 
1866   //    if (token != TokenNameRPAREN) {
 
1869   //    if (token == TokenNameRPAREN) {
 
1872   //      throwSyntaxError("')' expected after 'exit-status'.");
 
1875   private void expressionList() {
 
1878       if (token == TokenNameCOMMA) {
 
1885   private void expr() {
 
1887     //  | expr_without_variable
 
1888     //    if (token!=TokenNameEOF) {
 
1889     if (Scanner.TRACE) {
 
1890       System.out.println("TRACE: expr()");
 
1892     expr_without_variable(true);
 
1895   private void expr_without_variable(boolean only_variable) {
 
1896     //          internal_functions_in_yacc
 
1905     //  | T_INC rw_variable
 
1906     //  | T_DEC rw_variable
 
1907     //  | T_INT_CAST expr
 
1908     //  | T_DOUBLE_CAST expr
 
1909     //  | T_STRING_CAST expr
 
1910     //  | T_ARRAY_CAST expr
 
1911     //  | T_OBJECT_CAST expr
 
1912     //  | T_BOOL_CAST expr
 
1913     //  | T_UNSET_CAST expr
 
1914     //  | T_EXIT exit_expr
 
1916     //  | T_ARRAY '(' array_pair_list ')'
 
1917     //  | '`' encaps_list '`'
 
1918     //  | T_LIST '(' assignment_list ')' '=' expr
 
1919     //  | T_NEW class_name_reference ctor_arguments
 
1920     //  | variable '=' expr
 
1921     //  | variable '=' '&' variable
 
1922     //  | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
1923     //  | variable T_PLUS_EQUAL expr
 
1924     //  | variable T_MINUS_EQUAL expr
 
1925     //  | variable T_MUL_EQUAL expr
 
1926     //  | variable T_DIV_EQUAL expr
 
1927     //  | variable T_CONCAT_EQUAL expr
 
1928     //  | variable T_MOD_EQUAL expr
 
1929     //  | variable T_AND_EQUAL expr
 
1930     //  | variable T_OR_EQUAL expr
 
1931     //  | variable T_XOR_EQUAL expr
 
1932     //  | variable T_SL_EQUAL expr
 
1933     //  | variable T_SR_EQUAL expr
 
1934     //  | rw_variable T_INC
 
1935     //  | rw_variable T_DEC
 
1936     //  | expr T_BOOLEAN_OR expr
 
1937     //  | expr T_BOOLEAN_AND expr
 
1938     //  | expr T_LOGICAL_OR expr
 
1939     //  | expr T_LOGICAL_AND expr
 
1940     //  | expr T_LOGICAL_XOR expr
 
1952     //  | expr T_IS_IDENTICAL expr
 
1953     //  | expr T_IS_NOT_IDENTICAL expr
 
1954     //  | expr T_IS_EQUAL expr
 
1955     //  | expr T_IS_NOT_EQUAL expr
 
1957     //  | expr T_IS_SMALLER_OR_EQUAL expr
 
1959     //  | expr T_IS_GREATER_OR_EQUAL expr
 
1960     //  | expr T_INSTANCEOF class_name_reference
 
1961     //  | expr '?' expr ':' expr
 
1962     if (Scanner.TRACE) {
 
1963       System.out.println("TRACE: expr_without_variable() PART 1");
 
1966       case TokenNameisset :
 
1967       case TokenNameempty :
 
1968       case TokenNameeval :
 
1969       case TokenNameinclude :
 
1970       case TokenNameinclude_once :
 
1971       case TokenNamerequire :
 
1972       case TokenNamerequire_once :
 
1973         internal_functions_in_yacc();
 
1976       case TokenNameLPAREN :
 
1979         if (token == TokenNameRPAREN) {
 
1982           throwSyntaxError("')' expected in expression.");
 
1992       //    | T_INT_CAST expr
 
1993       //        | T_DOUBLE_CAST expr
 
1994       //        | T_STRING_CAST expr
 
1995       //        | T_ARRAY_CAST expr
 
1996       //        | T_OBJECT_CAST expr
 
1997       //        | T_BOOL_CAST expr
 
1998       //        | T_UNSET_CAST expr
 
1999       case TokenNameclone :
 
2000       case TokenNameprint :
 
2002       case TokenNamePLUS :
 
2003       case TokenNameMINUS :
 
2005       case TokenNameTWIDDLE :
 
2006       case TokenNameintCAST :
 
2007       case TokenNamedoubleCAST :
 
2008       case TokenNamestringCAST :
 
2009       case TokenNamearrayCAST :
 
2010       case TokenNameobjectCAST :
 
2011       case TokenNameboolCAST :
 
2012       case TokenNameunsetCAST :
 
2016       case TokenNameexit :
 
2022       //| T_STRING_VARNAME
 
2024       //| T_START_HEREDOC encaps_list T_END_HEREDOC
 
2025       //        | '`' encaps_list '`'
 
2027       //        | '`' encaps_list '`'
 
2028       case TokenNameEncapsedString0 :
 
2029         scanner.encapsedStringStack.push(new Character('`'));
 
2032           if (token == TokenNameEncapsedString0) {
 
2035             if (token != TokenNameEncapsedString0) {
 
2036               throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
 
2040           scanner.encapsedStringStack.pop();
 
2044       //      | '\'' encaps_list '\''
 
2045       case TokenNameEncapsedString1 :
 
2046         scanner.encapsedStringStack.push(new Character('\''));
 
2049           if (token == TokenNameEncapsedString1) {
 
2052             if (token != TokenNameEncapsedString1) {
 
2053               throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
 
2057           scanner.encapsedStringStack.pop();
 
2061       //| '"' encaps_list '"'
 
2062       case TokenNameEncapsedString2 :
 
2063         scanner.encapsedStringStack.push(new Character('"'));
 
2066           if (token == TokenNameEncapsedString2) {
 
2069             if (token != TokenNameEncapsedString2) {
 
2070               throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
 
2074           scanner.encapsedStringStack.pop();
 
2078       case TokenNameIntegerLiteral :
 
2079       case TokenNameDoubleLiteral :
 
2080       case TokenNameStringDoubleQuote :
 
2081       case TokenNameStringSingleQuote :
 
2082       case TokenNameStringInterpolated :
 
2083       case TokenNameFILE :
 
2084       case TokenNameLINE :
 
2085       case TokenNameCLASS_C :
 
2086       case TokenNameMETHOD_C :
 
2087       case TokenNameFUNC_C :
 
2090       case TokenNameHEREDOC :
 
2093       case TokenNamearray :
 
2094         //    T_ARRAY '(' array_pair_list ')'
 
2096         if (token == TokenNameLPAREN) {
 
2098           if (token == TokenNameRPAREN) {
 
2103           if (token != TokenNameRPAREN) {
 
2104             throwSyntaxError("')' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
 
2108           throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
 
2111       case TokenNamelist :
 
2112         //    | T_LIST '(' assignment_list ')' '=' expr
 
2114         if (token == TokenNameLPAREN) {
 
2117           if (token != TokenNameRPAREN) {
 
2118             throwSyntaxError("')' expected after 'list' keyword.");
 
2121           if (token != TokenNameEQUAL) {
 
2122             throwSyntaxError("'=' expected after 'list' keyword.");
 
2127           throwSyntaxError("'(' expected after 'list' keyword.");
 
2131         //      | T_NEW class_name_reference ctor_arguments
 
2133         class_name_reference();
 
2136       //        | T_INC rw_variable
 
2137       //        | T_DEC rw_variable
 
2138       case TokenNamePLUS_PLUS :
 
2139       case TokenNameMINUS_MINUS :
 
2143       //        | variable '=' expr
 
2144       //        | variable '=' '&' variable
 
2145       //        | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
2146       //        | variable T_PLUS_EQUAL expr
 
2147       //        | variable T_MINUS_EQUAL expr
 
2148       //        | variable T_MUL_EQUAL expr
 
2149       //        | variable T_DIV_EQUAL expr
 
2150       //        | variable T_CONCAT_EQUAL expr
 
2151       //        | variable T_MOD_EQUAL expr
 
2152       //        | variable T_AND_EQUAL expr
 
2153       //        | variable T_OR_EQUAL expr
 
2154       //        | variable T_XOR_EQUAL expr
 
2155       //        | variable T_SL_EQUAL expr
 
2156       //        | variable T_SR_EQUAL expr
 
2157       //        | rw_variable T_INC
 
2158       //        | rw_variable T_DEC
 
2159       case TokenNameIdentifier :
 
2160       case TokenNameVariable :
 
2161       case TokenNameDOLLAR :
 
2164           case TokenNameEQUAL :
 
2166             if (token == TokenNameAND) {
 
2168               if (token == TokenNamenew) {
 
2169                 // | variable '=' '&' T_NEW class_name_reference
 
2172                 class_name_reference();
 
2181           case TokenNamePLUS_EQUAL :
 
2182           case TokenNameMINUS_EQUAL :
 
2183           case TokenNameMULTIPLY_EQUAL :
 
2184           case TokenNameDIVIDE_EQUAL :
 
2185           case TokenNameDOT_EQUAL :
 
2186           case TokenNameREMAINDER_EQUAL :
 
2187           case TokenNameAND_EQUAL :
 
2188           case TokenNameOR_EQUAL :
 
2189           case TokenNameXOR_EQUAL :
 
2190           case TokenNameRIGHT_SHIFT_EQUAL :
 
2191           case TokenNameLEFT_SHIFT_EQUAL :
 
2195           case TokenNamePLUS_PLUS :
 
2196           case TokenNameMINUS_MINUS :
 
2200             if (!only_variable) {
 
2201               throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "').");
 
2206         if (token != TokenNameINLINE_HTML) {
 
2207           if (token > TokenNameKEYWORD) {
 
2211             throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
 
2216     if (Scanner.TRACE) {
 
2217       System.out.println("TRACE: expr_without_variable() PART 2");
 
2219     //  | expr T_BOOLEAN_OR expr
 
2220     //  | expr T_BOOLEAN_AND expr
 
2221     //  | expr T_LOGICAL_OR expr
 
2222     //  | expr T_LOGICAL_AND expr
 
2223     //  | expr T_LOGICAL_XOR expr
 
2235     //  | expr T_IS_IDENTICAL expr
 
2236     //  | expr T_IS_NOT_IDENTICAL expr
 
2237     //  | expr T_IS_EQUAL expr
 
2238     //  | expr T_IS_NOT_EQUAL expr
 
2240     //  | expr T_IS_SMALLER_OR_EQUAL expr
 
2242     //  | expr T_IS_GREATER_OR_EQUAL expr
 
2245         case TokenNameOR_OR :
 
2246         case TokenNameAND_AND :
 
2254         case TokenNamePLUS :
 
2255         case TokenNameMINUS :
 
2256         case TokenNameMULTIPLY :
 
2257         case TokenNameDIVIDE :
 
2258         case TokenNameREMAINDER :
 
2259         case TokenNameLEFT_SHIFT :
 
2260         case TokenNameRIGHT_SHIFT :
 
2261         case TokenNameEQUAL_EQUAL_EQUAL :
 
2262         case TokenNameNOT_EQUAL_EQUAL :
 
2263         case TokenNameEQUAL_EQUAL :
 
2264         case TokenNameNOT_EQUAL :
 
2265         case TokenNameLESS :
 
2266         case TokenNameLESS_EQUAL :
 
2267         case TokenNameGREATER :
 
2268         case TokenNameGREATER_EQUAL :
 
2272         //  | expr T_INSTANCEOF class_name_reference
 
2273         //      | expr '?' expr ':' expr
 
2274         case TokenNameinstanceof :
 
2276           class_name_reference();
 
2278         case TokenNameQUESTION :
 
2281           if (token == TokenNameCOLON) {
 
2291   private void class_name_reference() {
 
2292     //  class_name_reference:
 
2294     //| dynamic_class_name_reference
 
2295     if (Scanner.TRACE) {
 
2296       System.out.println("TRACE: class_name_reference()");
 
2298     if (token == TokenNameIdentifier) {
 
2301       dynamic_class_name_reference();
 
2304   private void dynamic_class_name_reference() {
 
2305     //dynamic_class_name_reference:
 
2306     //  base_variable T_OBJECT_OPERATOR object_property
 
2307     // dynamic_class_name_variable_properties
 
2309     if (Scanner.TRACE) {
 
2310       System.out.println("TRACE: dynamic_class_name_reference()");
 
2313     if (token == TokenNameMINUS_GREATER) {
 
2316       dynamic_class_name_variable_properties();
 
2319   private void dynamic_class_name_variable_properties() {
 
2320     //  dynamic_class_name_variable_properties:
 
2321     //                  dynamic_class_name_variable_properties
 
2322     // dynamic_class_name_variable_property
 
2324     if (Scanner.TRACE) {
 
2325       System.out.println("TRACE: dynamic_class_name_variable_properties()");
 
2327     while (token == TokenNameMINUS_GREATER) {
 
2328       dynamic_class_name_variable_property();
 
2331   private void dynamic_class_name_variable_property() {
 
2332     //  dynamic_class_name_variable_property:
 
2333     //  T_OBJECT_OPERATOR object_property
 
2334     if (Scanner.TRACE) {
 
2335       System.out.println("TRACE: dynamic_class_name_variable_property()");
 
2337     if (token == TokenNameMINUS_GREATER) {
 
2342   private void ctor_arguments() {
 
2345     //| '(' function_call_parameter_list ')'
 
2346     if (token == TokenNameLPAREN) {
 
2348       if (token == TokenNameRPAREN) {
 
2352       non_empty_function_call_parameter_list();
 
2353       if (token != TokenNameRPAREN) {
 
2354         throwSyntaxError("')' expected in ctor_arguments.");
 
2359   private void assignment_list() {
 
2361     //  assignment_list ',' assignment_list_element
 
2362     //| assignment_list_element
 
2364       assignment_list_element();
 
2365       if (token != TokenNameCOMMA) {
 
2371   private void assignment_list_element() {
 
2372     //assignment_list_element:
 
2374     //| T_LIST '(' assignment_list ')'
 
2376     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
 
2379       if (token == TokenNamelist) {
 
2381         if (token == TokenNameLPAREN) {
 
2384           if (token != TokenNameRPAREN) {
 
2385             throwSyntaxError("')' expected after 'list' keyword.");
 
2389           throwSyntaxError("'(' expected after 'list' keyword.");
 
2394   private void array_pair_list() {
 
2397     //| non_empty_array_pair_list possible_comma
 
2398     non_empty_array_pair_list();
 
2399     if (token == TokenNameCOMMA) {
 
2403   private void non_empty_array_pair_list() {
 
2404     //non_empty_array_pair_list:
 
2405     //  non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
 
2406     //| non_empty_array_pair_list ',' expr
 
2407     //| expr T_DOUBLE_ARROW expr
 
2409     //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
 
2410     //| non_empty_array_pair_list ',' '&' w_variable
 
2411     //| expr T_DOUBLE_ARROW '&' w_variable
 
2414       if (token == TokenNameAND) {
 
2419         if (token == TokenNameAND) {
 
2422         } else if (token == TokenNameEQUAL_GREATER) {
 
2424           if (token == TokenNameAND) {
 
2432       if (token != TokenNameCOMMA) {
 
2436       if (token == TokenNameRPAREN) {
 
2441   //  private void variableList() {
 
2444   //      if (token == TokenNameCOMMA) {
 
2451   private void variable_without_objects() {
 
2452     //  variable_without_objects:
 
2453     //                  reference_variable
 
2454     //          | simple_indirect_reference reference_variable
 
2455     if (Scanner.TRACE) {
 
2456       System.out.println("TRACE: variable_without_objects()");
 
2458     while (token == TokenNameDOLLAR) {
 
2461     reference_variable();
 
2463   private void function_call() {
 
2465     //  T_STRING '(' function_call_parameter_list ')'
 
2466     //| class_constant '(' function_call_parameter_list ')'
 
2467     //| static_member '(' function_call_parameter_list ')'
 
2468     //| variable_without_objects '(' function_call_parameter_list ')'
 
2469     char[] defineName = null;
 
2470     char[] ident = null;
 
2473     if (Scanner.TRACE) {
 
2474       System.out.println("TRACE: function_call()");
 
2476     if (token == TokenNameIdentifier) {
 
2477       ident = scanner.getCurrentIdentifierSource();
 
2479       startPos = scanner.getCurrentTokenStartPosition();
 
2480       endPos = scanner.getCurrentTokenEndPosition();
 
2483         case TokenNamePAAMAYIM_NEKUDOTAYIM :
 
2487           if (token == TokenNameIdentifier) {
 
2492             variable_without_objects();
 
2497       variable_without_objects();
 
2499     if (token != TokenNameLPAREN) {
 
2500       if (defineName!=null) {
 
2501         // does this identifier contain only uppercase characters?
 
2502         if (defineName.length==3) {
 
2503           if (defineName[0]=='d' &&
 
2504               defineName[1]=='i' &&
 
2505               defineName[2]=='e' ) {
 
2508         } else if (defineName.length==4) {
 
2509           if (defineName[0]=='t' &&
 
2510               defineName[1]=='r' &&
 
2511               defineName[2]=='u' &&
 
2512               defineName[3]=='e' ) {
 
2514           } else if (defineName[0]=='n' &&
 
2515               defineName[1]=='u' &&
 
2516               defineName[2]=='l' &&
 
2517               defineName[3]=='l' ) {
 
2520         } else if (defineName.length==5) {
 
2521           if (defineName[0]=='f' &&
 
2522               defineName[1]=='a' &&
 
2523               defineName[2]=='l' &&
 
2524               defineName[3]=='s' &&
 
2525               defineName[4]=='e' ) {
 
2529         if (defineName!=null) {
 
2530           for (int i=0; i<defineName.length;i++) {
 
2531             if (Character.isLowerCase(defineName[i])) {  
 
2532               problemReporter.phpUppercaseIdentifierWarning(startPos, endPos,
 
2533                 referenceContext, compilationUnit.compilationResult);
 
2539       // TODO is this ok ?
 
2541       //      throwSyntaxError("'(' expected in function call.");
 
2544     if (token == TokenNameRPAREN) {
 
2548     non_empty_function_call_parameter_list();
 
2549     if (token != TokenNameRPAREN) {
 
2550       String functionName;
 
2552         functionName = new String(" ");
 
2554         functionName = new String(ident);
 
2556       throwSyntaxError("')' expected in function call ("+functionName+").");
 
2560   //  private void function_call_parameter_list() {
 
2561   //    function_call_parameter_list:
 
2562   //            non_empty_function_call_parameter_list { $$ = $1; }
 
2565   private void non_empty_function_call_parameter_list() {
 
2566     //non_empty_function_call_parameter_list:
 
2567     //          expr_without_variable
 
2570     //  | non_empty_function_call_parameter_list ',' expr_without_variable
 
2571     //  | non_empty_function_call_parameter_list ',' variable
 
2572     //  | non_empty_function_call_parameter_list ',' '&' w_variable
 
2573     if (Scanner.TRACE) {
 
2574       System.out.println("TRACE: non_empty_function_call_parameter_list()");
 
2577       if (token == TokenNameAND) {
 
2581         //        if (token == TokenNameIdentifier || token ==
 
2582         // TokenNameVariable
 
2583         //            || token == TokenNameDOLLAR) {
 
2586         expr_without_variable(true);
 
2589       if (token != TokenNameCOMMA) {
 
2595   private void fully_qualified_class_name() {
 
2596     if (token == TokenNameIdentifier) {
 
2599       throwSyntaxError("Class name expected.");
 
2602   private void static_member() {
 
2604     //  fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
 
2605     // variable_without_objects
 
2606     if (Scanner.TRACE) {
 
2607       System.out.println("TRACE: static_member()");
 
2609     fully_qualified_class_name();
 
2610     if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
 
2611       throwSyntaxError("'::' expected after class name (static_member).");
 
2614     variable_without_objects();
 
2616   private void base_variable_with_function_calls() {
 
2617     //  base_variable_with_function_calls:
 
2620     boolean functionCall = false;
 
2621     if (Scanner.TRACE) {
 
2622       System.out.println("TRACE: base_variable_with_function_calls()");
 
2624     //    if (token == TokenNameIdentifier) {
 
2625     //      functionCall = true;
 
2626     //    } else if (token == TokenNameVariable) {
 
2627     //      int tempToken = token;
 
2628     //      int tempPosition = scanner.currentPosition;
 
2630     //      if (token == TokenNameLPAREN) {
 
2631     //        functionCall = true;
 
2633     //      token = tempToken;
 
2634     //      scanner.currentPosition = tempPosition;
 
2635     //      scanner.phpMode = true;
 
2637     //    if (functionCall) {
 
2643   private void base_variable() {
 
2645     //                  reference_variable
 
2646     //          | simple_indirect_reference reference_variable
 
2648     if (Scanner.TRACE) {
 
2649       System.out.println("TRACE: base_variable()");
 
2651     if (token == TokenNameIdentifier) {
 
2654       while (token == TokenNameDOLLAR) {
 
2657       reference_variable();
 
2660   //  private void simple_indirect_reference() {
 
2661   //    // simple_indirect_reference:
 
2663   //    //| simple_indirect_reference '$'
 
2665   private void reference_variable() {
 
2666     //  reference_variable:
 
2667     //                  reference_variable '[' dim_offset ']'
 
2668     //          | reference_variable '{' expr '}'
 
2669     //          | compound_variable
 
2670     if (Scanner.TRACE) {
 
2671       System.out.println("TRACE: reference_variable()");
 
2673     compound_variable();
 
2675       if (token == TokenNameLBRACE) {
 
2678         if (token != TokenNameRBRACE) {
 
2679           throwSyntaxError("'}' expected in reference variable.");
 
2682       } else if (token == TokenNameLBRACKET) {
 
2684         if (token != TokenNameRBRACKET) {
 
2687           if (token != TokenNameRBRACKET) {
 
2688             throwSyntaxError("']' expected in reference variable.");
 
2697   private void compound_variable() {
 
2698     //  compound_variable:
 
2700     //          | '$' '{' expr '}'
 
2701     if (Scanner.TRACE) {
 
2702       System.out.println("TRACE: compound_variable()");
 
2704     if (token == TokenNameVariable) {
 
2707       // because of simple_indirect_reference
 
2708       while (token == TokenNameDOLLAR) {
 
2711       if (token != TokenNameLBRACE) {
 
2712         throwSyntaxError("'{' expected after compound variable token '$'.");
 
2716       if (token != TokenNameRBRACE) {
 
2717         throwSyntaxError("'}' expected after compound variable token '$'.");
 
2722   //  private void dim_offset() {
 
2728   private void object_property() {
 
2731     //| variable_without_objects
 
2732     if (Scanner.TRACE) {
 
2733       System.out.println("TRACE: object_property()");
 
2735     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
 
2736       variable_without_objects();
 
2741   private void object_dim_list() {
 
2743     //  object_dim_list '[' dim_offset ']'
 
2744     //| object_dim_list '{' expr '}'
 
2746     if (Scanner.TRACE) {
 
2747       System.out.println("TRACE: object_dim_list()");
 
2751       if (token == TokenNameLBRACE) {
 
2754         if (token != TokenNameRBRACE) {
 
2755           throwSyntaxError("'}' expected in object_dim_list.");
 
2758       } else if (token == TokenNameLBRACKET) {
 
2760         if (token == TokenNameRBRACKET) {
 
2765         if (token != TokenNameRBRACKET) {
 
2766           throwSyntaxError("']' expected in object_dim_list.");
 
2774   private void variable_name() {
 
2778     if (Scanner.TRACE) {
 
2779       System.out.println("TRACE: variable_name()");
 
2781     if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
2782       if (token > TokenNameKEYWORD) {
 
2783         // TODO show a warning "Keyword used as variable" ?
 
2787       if (token != TokenNameLBRACE) {
 
2788         throwSyntaxError("'{' expected in variable name.");
 
2792       if (token != TokenNameRBRACE) {
 
2793         throwSyntaxError("'}' expected in variable name.");
 
2798   private void r_variable() {
 
2801   private void w_variable() {
 
2804   private void rw_variable() {
 
2807   private void variable() {
 
2809     //          base_variable_with_function_calls T_OBJECT_OPERATOR
 
2810     //                  object_property method_or_not variable_properties
 
2811     //  | base_variable_with_function_calls
 
2812     base_variable_with_function_calls();
 
2813     if (token == TokenNameMINUS_GREATER) {
 
2817       variable_properties();
 
2819     //    if (token == TokenNameDOLLAR_LBRACE) {
 
2823     //      if (token != TokenNameRBRACE) {
 
2824     //        throwSyntaxError("'}' expected after indirect variable token '${'.");
 
2828     //      if (token == TokenNameVariable) {
 
2830     //        if (token == TokenNameLBRACKET) {
 
2833     //          if (token != TokenNameRBRACKET) {
 
2834     //            throwSyntaxError("']' expected in variable-list.");
 
2837     //        } else if (token == TokenNameEQUAL) {
 
2842     //        throwSyntaxError("$-variable expected in variable-list.");
 
2846   private void variable_properties() {
 
2847     //  variable_properties:
 
2848     //                  variable_properties variable_property
 
2850     while (token == TokenNameMINUS_GREATER) {
 
2851       variable_property();
 
2854   private void variable_property() {
 
2855     //  variable_property:
 
2856     //                  T_OBJECT_OPERATOR object_property method_or_not
 
2857     if (Scanner.TRACE) {
 
2858       System.out.println("TRACE: variable_property()");
 
2860     if (token == TokenNameMINUS_GREATER) {
 
2865       throwSyntaxError("'->' expected in variable_property.");
 
2868   private void method_or_not() {
 
2870     //                  '(' function_call_parameter_list ')'
 
2872     if (Scanner.TRACE) {
 
2873       System.out.println("TRACE: method_or_not()");
 
2875     if (token == TokenNameLPAREN) {
 
2877       if (token == TokenNameRPAREN) {
 
2881       non_empty_function_call_parameter_list();
 
2882       if (token != TokenNameRPAREN) {
 
2883         throwSyntaxError("')' expected in method_or_not.");
 
2888   private void exit_expr() {
 
2892     if (token != TokenNameLPAREN) {
 
2896     if (token == TokenNameRPAREN) {
 
2901     if (token != TokenNameRPAREN) {
 
2902       throwSyntaxError("')' expected after keyword 'exit'");
 
2906   private void encaps_list() {
 
2907     //                  encaps_list encaps_var
 
2908     //          | encaps_list T_STRING
 
2909     //          | encaps_list T_NUM_STRING
 
2910     //          | encaps_list T_ENCAPSED_AND_WHITESPACE
 
2911     //          | encaps_list T_CHARACTER
 
2912     //          | encaps_list T_BAD_CHARACTER
 
2913     //          | encaps_list '['
 
2914     //          | encaps_list ']'
 
2915     //          | encaps_list '{'
 
2916     //          | encaps_list '}'
 
2917     //          | encaps_list T_OBJECT_OPERATOR
 
2921         case TokenNameSTRING :
 
2924         case TokenNameLBRACE :
 
2925           //          scanner.encapsedStringStack.pop();
 
2928         case TokenNameRBRACE :
 
2929           //          scanner.encapsedStringStack.pop();
 
2932         case TokenNameLBRACKET :
 
2933           //          scanner.encapsedStringStack.pop();
 
2936         case TokenNameRBRACKET :
 
2937           //          scanner.encapsedStringStack.pop();
 
2940         case TokenNameMINUS_GREATER :
 
2941           //          scanner.encapsedStringStack.pop();
 
2944         case TokenNameVariable :
 
2945         case TokenNameDOLLAR_LBRACE :
 
2946         case TokenNameLBRACE_DOLLAR :
 
2950           char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
 
2951           if (encapsedChar == '$') {
 
2952             scanner.encapsedStringStack.pop();
 
2953             encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
 
2954             switch (encapsedChar) {
 
2956                 if (token == TokenNameEncapsedString0) {
 
2959                 token = TokenNameSTRING;
 
2962                 if (token == TokenNameEncapsedString1) {
 
2965                 token = TokenNameSTRING;
 
2968                 if (token == TokenNameEncapsedString2) {
 
2971                 token = TokenNameSTRING;
 
2979   private void encaps_var() {
 
2981     //          | T_VARIABLE '[' encaps_var_offset ']'
 
2982     //          | T_VARIABLE T_OBJECT_OPERATOR T_STRING
 
2983     //          | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
 
2984     //          | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
 
2985     //          | T_CURLY_OPEN variable '}'
 
2987       case TokenNameVariable :
 
2989         if (token == TokenNameLBRACKET) {
 
2991           //          if (token == TokenNameRBRACKET) {
 
2994           expr(); //encaps_var_offset();
 
2995           if (token != TokenNameRBRACKET) {
 
2996             throwSyntaxError("']' expected after variable.");
 
2998           //          scanner.encapsedStringStack.pop();
 
3001         } else if (token == TokenNameMINUS_GREATER) {
 
3003           if (token != TokenNameIdentifier) {
 
3004             throwSyntaxError("Identifier expected after '->'.");
 
3006           //          scanner.encapsedStringStack.pop();
 
3010         //          // scanner.encapsedStringStack.pop();
 
3011         //          int tempToken = TokenNameSTRING;
 
3012         //          if (!scanner.encapsedStringStack.isEmpty()
 
3013         //              && (token == TokenNameEncapsedString0
 
3014         //                  || token == TokenNameEncapsedString1
 
3015         //                  || token == TokenNameEncapsedString2 || token ==
 
3016         // TokenNameERROR)) {
 
3017         //            char encapsedChar = ((Character)
 
3018         // scanner.encapsedStringStack.peek())
 
3021         //              case TokenNameEncapsedString0 :
 
3022         //                if (encapsedChar == '`') {
 
3023         //                  tempToken = TokenNameEncapsedString0;
 
3026         //              case TokenNameEncapsedString1 :
 
3027         //                if (encapsedChar == '\'') {
 
3028         //                  tempToken = TokenNameEncapsedString1;
 
3031         //              case TokenNameEncapsedString2 :
 
3032         //                if (encapsedChar == '"') {
 
3033         //                  tempToken = TokenNameEncapsedString2;
 
3036         //              case TokenNameERROR :
 
3037         //                if (scanner.source[scanner.currentPosition - 1] == '\\') {
 
3038         //                  scanner.currentPosition--;
 
3044         //          token = tempToken;
 
3047       case TokenNameDOLLAR_LBRACE :
 
3049         if (token == TokenNameDOLLAR_LBRACE) {
 
3051         } else if (token == TokenNameIdentifier) {
 
3053           if (token == TokenNameLBRACKET) {
 
3055             //            if (token == TokenNameRBRACKET) {
 
3059             if (token != TokenNameRBRACKET) {
 
3060               throwSyntaxError("']' expected after '${'.");
 
3068         if (token != TokenNameRBRACE) {
 
3069           throwSyntaxError("'}' expected.");
 
3073       case TokenNameLBRACE_DOLLAR :
 
3075         if (token == TokenNameLBRACE_DOLLAR) {
 
3077         } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
3079           if (token == TokenNameLBRACKET) {
 
3081             //            if (token == TokenNameRBRACKET) {
 
3085             if (token != TokenNameRBRACKET) {
 
3086               throwSyntaxError("']' expected.");
 
3090           } else if (token == TokenNameMINUS_GREATER) {
 
3092             if (token != TokenNameIdentifier &&
 
3093                 token != TokenNameVariable) {
 
3094               throwSyntaxError("String or Variable token expected.");
 
3097             if (token == TokenNameLBRACKET) {
 
3099               //            if (token == TokenNameRBRACKET) {
 
3103               if (token != TokenNameRBRACKET) {
 
3104                 throwSyntaxError("']' expected after '${'.");
 
3110           //          if (token != TokenNameRBRACE) {
 
3111           //            throwSyntaxError("'}' expected after '{$'.");
 
3113           //          // scanner.encapsedStringStack.pop();
 
3117           if (token != TokenNameRBRACE) {
 
3118             throwSyntaxError("'}' expected.");
 
3120           //          scanner.encapsedStringStack.pop();
 
3126   private void encaps_var_offset() {
 
3131       case TokenNameSTRING :
 
3134       case TokenNameIntegerLiteral :
 
3137       case TokenNameVariable :
 
3140       case TokenNameIdentifier :
 
3144         throwSyntaxError("Variable or String token expected.");
 
3148   private void internal_functions_in_yacc() {
 
3150     ImportReference impt = null;
 
3152       case TokenNameisset :
 
3153         //      T_ISSET '(' isset_variables ')'
 
3155         if (token != TokenNameLPAREN) {
 
3156           throwSyntaxError("'(' expected after keyword 'isset'");
 
3160         if (token != TokenNameRPAREN) {
 
3161           throwSyntaxError("')' expected after keyword 'isset'");
 
3165       case TokenNameempty :
 
3166         //      T_EMPTY '(' variable ')'
 
3168         if (token != TokenNameLPAREN) {
 
3169           throwSyntaxError("'(' expected after keyword 'empty'");
 
3173         if (token != TokenNameRPAREN) {
 
3174           throwSyntaxError("')' expected after keyword 'empty'");
 
3178       case TokenNameinclude :
 
3180         start = scanner.getCurrentTokenStartPosition();
 
3184         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
 
3185         impt.declarationSourceEnd = impt.sourceEnd;
 
3186         impt.declarationEnd = impt.declarationSourceEnd;
 
3187         //endPosition is just before the ;
 
3188         impt.declarationSourceStart = start;
 
3189         includesList.add(impt);
 
3191       case TokenNameinclude_once :
 
3192         //      T_INCLUDE_ONCE expr
 
3193         start = scanner.getCurrentTokenStartPosition();
 
3196         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
 
3197         impt.declarationSourceEnd = impt.sourceEnd;
 
3198         impt.declarationEnd = impt.declarationSourceEnd;
 
3199         //endPosition is just before the ;
 
3200         impt.declarationSourceStart = start;
 
3201         includesList.add(impt);
 
3203       case TokenNameeval :
 
3204         //      T_EVAL '(' expr ')'
 
3206         if (token != TokenNameLPAREN) {
 
3207           throwSyntaxError("'(' expected after keyword 'eval'");
 
3211         if (token != TokenNameRPAREN) {
 
3212           throwSyntaxError("')' expected after keyword 'eval'");
 
3216       case TokenNamerequire :
 
3218         start = scanner.getCurrentTokenStartPosition();
 
3221         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
 
3222         impt.declarationSourceEnd = impt.sourceEnd;
 
3223         impt.declarationEnd = impt.declarationSourceEnd;
 
3224         //endPosition is just before the ;
 
3225         impt.declarationSourceStart = start;
 
3226         includesList.add(impt);
 
3228       case TokenNamerequire_once :
 
3229         //      T_REQUIRE_ONCE expr
 
3230         start = scanner.getCurrentTokenStartPosition();
 
3233         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
 
3234         impt.declarationSourceEnd = impt.sourceEnd;
 
3235         impt.declarationEnd = impt.declarationSourceEnd;
 
3236         //endPosition is just before the ;
 
3237         impt.declarationSourceStart = start;
 
3238         includesList.add(impt);
 
3242   private void isset_variables() {
 
3244     //  | isset_variables ','
 
3245     if (token == TokenNameRPAREN) {
 
3246       throwSyntaxError("Variable expected after keyword 'isset'");
 
3250       if (token == TokenNameCOMMA) {
 
3257   private boolean common_scalar() {
 
3261     //  | T_CONSTANT_ENCAPSED_STRING
 
3268       case TokenNameIntegerLiteral :
 
3271       case TokenNameDoubleLiteral :
 
3274       case TokenNameStringDoubleQuote :
 
3277       case TokenNameStringSingleQuote :
 
3280       case TokenNameStringInterpolated :
 
3283       case TokenNameFILE :
 
3286       case TokenNameLINE :
 
3289       case TokenNameCLASS_C :
 
3292       case TokenNameMETHOD_C :
 
3295       case TokenNameFUNC_C :
 
3301   private void scalar() {
 
3304     //| T_STRING_VARNAME
 
3307     //| '"' encaps_list '"'
 
3308     //| '\'' encaps_list '\''
 
3309     //| T_START_HEREDOC encaps_list T_END_HEREDOC
 
3310     throwSyntaxError("Not yet implemented (scalar).");
 
3312   private void static_scalar() {
 
3313     //    static_scalar: /* compile-time evaluated scalars */
 
3316     //  | '+' static_scalar
 
3317     //  | '-' static_scalar
 
3318     //  | T_ARRAY '(' static_array_pair_list ')'
 
3319     //  | static_class_constant
 
3320     if (common_scalar()) {
 
3324       case TokenNameIdentifier :
 
3326         //        static_class_constant:
 
3327         //              T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
 
3328         if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
 
3330           if (token == TokenNameIdentifier) {
 
3333             throwSyntaxError("Identifier expected after '::' operator.");
 
3337       case TokenNameEncapsedString0 :
 
3339           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3340           while (scanner.currentCharacter != '`') {
 
3341             if (scanner.currentCharacter == '\\') {
 
3342               scanner.currentPosition++;
 
3344             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3347         } catch (IndexOutOfBoundsException e) {
 
3348           throwSyntaxError("'`' expected at end of static string.");
 
3351       case TokenNameEncapsedString1 :
 
3353           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3354           while (scanner.currentCharacter != '\'') {
 
3355             if (scanner.currentCharacter == '\\') {
 
3356               scanner.currentPosition++;
 
3358             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3361         } catch (IndexOutOfBoundsException e) {
 
3362           throwSyntaxError("'\'' expected at end of static string.");
 
3365       case TokenNameEncapsedString2 :
 
3367           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3368           while (scanner.currentCharacter != '"') {
 
3369             if (scanner.currentCharacter == '\\') {
 
3370               scanner.currentPosition++;
 
3372             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3375         } catch (IndexOutOfBoundsException e) {
 
3376           throwSyntaxError("'\"' expected at end of static string.");
 
3379       case TokenNamePLUS :
 
3383       case TokenNameMINUS :
 
3387       case TokenNamearray :
 
3389         if (token != TokenNameLPAREN) {
 
3390           throwSyntaxError("'(' expected after keyword 'array'");
 
3393         if (token == TokenNameRPAREN) {
 
3397         non_empty_static_array_pair_list();
 
3398         if (token != TokenNameRPAREN) {
 
3399           throwSyntaxError("')' expected after keyword 'array'");
 
3403       //      case TokenNamenull :
 
3406       //      case TokenNamefalse :
 
3409       //      case TokenNametrue :
 
3413         throwSyntaxError("Static scalar/constant expected.");
 
3416   private void non_empty_static_array_pair_list() {
 
3417     //  non_empty_static_array_pair_list:
 
3418     //  non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
 
3420     //| non_empty_static_array_pair_list ',' static_scalar
 
3421     //| static_scalar T_DOUBLE_ARROW static_scalar
 
3425       if (token == TokenNameEQUAL_GREATER) {
 
3429       if (token != TokenNameCOMMA) {
 
3433       if (token == TokenNameRPAREN) {
 
3438   public void reportSyntaxError() { //int act, int currentKind, int
 
3440     /* remember current scanner position */
 
3441     int startPos = scanner.startPosition;
 
3442     int currentPos = scanner.currentPosition;
 
3443     //          String[] expectings;
 
3444     //          String tokenName = name[symbol_index[currentKind]];
 
3445     //fetch all "accurate" possible terminals that could recover the error
 
3446     //          int start, end = start = asi(stack[stateStackTop]);
 
3447     //          while (asr[end] != 0)
 
3449     //          int length = end - start;
 
3450     //          expectings = new String[length];
 
3451     //          if (length != 0) {
 
3452     //                  char[] indexes = new char[length];
 
3453     //                  System.arraycopy(asr, start, indexes, 0, length);
 
3454     //                  for (int i = 0; i < length; i++) {
 
3455     //                          expectings[i] = name[symbol_index[indexes[i]]];
 
3458     //if the pb is an EOF, try to tell the user that they are some
 
3459     //          if (tokenName.equals(UNEXPECTED_EOF)) {
 
3460     //                  if (!this.checkAndReportBracketAnomalies(problemReporter())) {
 
3461     //                          char[] tokenSource;
 
3463     //                                  tokenSource = this.scanner.getCurrentTokenSource();
 
3464     //                          } catch (Exception e) {
 
3465     //                                  tokenSource = new char[] {};
 
3467     //                          problemReporter().parseError(
 
3468     //                                  this.scanner.startPosition,
 
3469     //                                  this.scanner.currentPosition - 1,
 
3474     //          } else { //the next test is HEAVILY grammar DEPENDENT.
 
3475     //                  if ((length == 14)
 
3476     //                          && (expectings[0] == "=") //$NON-NLS-1$
 
3477     //                          && (expectings[1] == "*=") //$NON-NLS-1$
 
3478     //                          && (expressionPtr > -1)) {
 
3479     //                                  switch(currentKind) {
 
3480     //                                          case TokenNameSEMICOLON:
 
3481     //                                          case TokenNamePLUS:
 
3482     //                                          case TokenNameMINUS:
 
3483     //                                          case TokenNameDIVIDE:
 
3484     //                                          case TokenNameREMAINDER:
 
3485     //                                          case TokenNameMULTIPLY:
 
3486     //                                          case TokenNameLEFT_SHIFT:
 
3487     //                                          case TokenNameRIGHT_SHIFT:
 
3488     //// case TokenNameUNSIGNED_RIGHT_SHIFT:
 
3489     //                                          case TokenNameLESS:
 
3490     //                                          case TokenNameGREATER:
 
3491     //                                          case TokenNameLESS_EQUAL:
 
3492     //                                          case TokenNameGREATER_EQUAL:
 
3493     //                                          case TokenNameEQUAL_EQUAL:
 
3494     //                                          case TokenNameNOT_EQUAL:
 
3495     //                                          case TokenNameXOR:
 
3496     //                                          case TokenNameAND:
 
3497     //                                          case TokenNameOR:
 
3498     //                                          case TokenNameOR_OR:
 
3499     //                                          case TokenNameAND_AND:
 
3500     //                                                  // the ; is not the expected token ==> it ends a statement when an
 
3501     // expression is not ended
 
3502     //                                                  problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
 
3504     //                                          case TokenNameRBRACE :
 
3505     //                                                  problemReporter().missingSemiColon(expressionStack[expressionPtr]);
 
3508     //                                                  char[] tokenSource;
 
3510     //                                                          tokenSource = this.scanner.getCurrentTokenSource();
 
3511     //                                                  } catch (Exception e) {
 
3512     //                                                          tokenSource = new char[] {};
 
3514     //                                                  problemReporter().parseError(
 
3515     //                                                          this.scanner.startPosition,
 
3516     //                                                          this.scanner.currentPosition - 1,
 
3520     //                                                  this.checkAndReportBracketAnomalies(problemReporter());
 
3525       tokenSource = this.scanner.getCurrentTokenSource();
 
3526     } catch (Exception e) {
 
3527       tokenSource = new char[]{};
 
3529     //                          problemReporter().parseError(
 
3530     //                                  this.scanner.startPosition,
 
3531     //                                  this.scanner.currentPosition - 1,
 
3535     this.checkAndReportBracketAnomalies(problemReporter());
 
3538     /* reset scanner where it was */
 
3539     scanner.startPosition = startPos;
 
3540     scanner.currentPosition = currentPos;
 
3542   public static final int RoundBracket = 0;
 
3543   public static final int SquareBracket = 1;
 
3544   public static final int CurlyBracket = 2;
 
3545   public static final int BracketKinds = 3;
 
3546   protected int[] nestedMethod; //the ptr is nestedType
 
3547   protected int nestedType, dimensions;
 
3549   final static int AstStackIncrement = 100;
 
3550   protected int astPtr;
 
3551   protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
 
3552   protected int astLengthPtr;
 
3553   protected int[] astLengthStack;
 
3554   ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
 
3555   public CompilationUnitDeclaration compilationUnit; /*
 
3556                                                       * the result from parse()
 
3558   protected ReferenceContext referenceContext;
 
3559   protected ProblemReporter problemReporter;
 
3560   protected CompilerOptions options;
 
3561   private ArrayList includesList;
 
3562   //  protected CompilationResult compilationResult;
 
3564    * Returns this parser's problem reporter initialized with its reference
 
3565    * context. Also it is assumed that a problem is going to be reported, so
 
3566    * initializes the compilation result's line positions.
 
3568   public ProblemReporter problemReporter() {
 
3569     if (scanner.recordLineSeparator) {
 
3570       compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
 
3572     problemReporter.referenceContext = referenceContext;
 
3573     return problemReporter;
 
3576    * Reconsider the entire source looking for inconsistencies in {} () []
 
3578   public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
 
3579     scanner.wasAcr = false;
 
3580     boolean anomaliesDetected = false;
 
3582       char[] source = scanner.source;
 
3583       int[] leftCount = {0, 0, 0};
 
3584       int[] rightCount = {0, 0, 0};
 
3585       int[] depths = {0, 0, 0};
 
3586       int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
 
3587       int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
 
3588       int[][] rightPositions = new int[][]{new int[10], new int[10], new int[10]};
 
3589       int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
 
3590       scanner.currentPosition = scanner.initialPosition; //starting
 
3592       // (first-zero-based
 
3594       while (scanner.currentPosition < scanner.eofPosition) { //loop for
 
3599           // ---------Consume white space and handles
 
3600           // startPosition---------
 
3601           boolean isWhiteSpace;
 
3603             scanner.startPosition = scanner.currentPosition;
 
3604             //                                          if (((scanner.currentCharacter =
 
3605             // source[scanner.currentPosition++]) == '\\') &&
 
3606             // (source[scanner.currentPosition] == 'u')) {
 
3607             //                                                  isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
 
3609             if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
 
3610               if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
3611                 // only record line positions we have not
 
3613                 scanner.pushLineSeparator();
 
3616             isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
 
3618           } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
 
3619           // -------consume token until } is found---------
 
3620           switch (scanner.currentCharacter) {
 
3622               int index = leftCount[CurlyBracket]++;
 
3623               if (index == leftPositions[CurlyBracket].length) {
 
3624                 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
3625                 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
 
3627               leftPositions[CurlyBracket][index] = scanner.startPosition;
 
3628               leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
 
3632               int index = rightCount[CurlyBracket]++;
 
3633               if (index == rightPositions[CurlyBracket].length) {
 
3634                 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
3635                 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
 
3637               rightPositions[CurlyBracket][index] = scanner.startPosition;
 
3638               rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
 
3642               int index = leftCount[RoundBracket]++;
 
3643               if (index == leftPositions[RoundBracket].length) {
 
3644                 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
 
3645                 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
 
3647               leftPositions[RoundBracket][index] = scanner.startPosition;
 
3648               leftDepths[RoundBracket][index] = depths[RoundBracket]++;
 
3652               int index = rightCount[RoundBracket]++;
 
3653               if (index == rightPositions[RoundBracket].length) {
 
3654                 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
 
3655                 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
 
3657               rightPositions[RoundBracket][index] = scanner.startPosition;
 
3658               rightDepths[RoundBracket][index] = --depths[RoundBracket];
 
3662               int index = leftCount[SquareBracket]++;
 
3663               if (index == leftPositions[SquareBracket].length) {
 
3664                 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
 
3665                 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
 
3667               leftPositions[SquareBracket][index] = scanner.startPosition;
 
3668               leftDepths[SquareBracket][index] = depths[SquareBracket]++;
 
3672               int index = rightCount[SquareBracket]++;
 
3673               if (index == rightPositions[SquareBracket].length) {
 
3674                 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
 
3675                 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
 
3677               rightPositions[SquareBracket][index] = scanner.startPosition;
 
3678               rightDepths[SquareBracket][index] = --depths[SquareBracket];
 
3682               if (scanner.getNextChar('\\')) {
 
3683                 scanner.scanEscapeCharacter();
 
3684               } else { // consume next character
 
3685                 scanner.unicodeAsBackSlash = false;
 
3686                 //                                                                      if (((scanner.currentCharacter =
 
3687                 // source[scanner.currentPosition++]) ==
 
3689                 // (source[scanner.currentPosition] ==
 
3691                 //                                                                              scanner.getNextUnicodeChar();
 
3693                 if (scanner.withoutUnicodePtr != 0) {
 
3694                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
 
3698               scanner.getNextChar('\'');
 
3702               // consume next character
 
3703               scanner.unicodeAsBackSlash = false;
 
3704               //                                                        if (((scanner.currentCharacter =
 
3705               // source[scanner.currentPosition++]) == '\\') &&
 
3706               // (source[scanner.currentPosition] == 'u')) {
 
3707               //                                                                scanner.getNextUnicodeChar();
 
3709               if (scanner.withoutUnicodePtr != 0) {
 
3710                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
 
3713               while (scanner.currentCharacter != '"') {
 
3714                 if (scanner.currentCharacter == '\r') {
 
3715                   if (source[scanner.currentPosition] == '\n')
 
3716                     scanner.currentPosition++;
 
3717                   break; // the string cannot go further that
 
3720                 if (scanner.currentCharacter == '\n') {
 
3721                   break; // the string cannot go further that
 
3724                 if (scanner.currentCharacter == '\\') {
 
3725                   scanner.scanEscapeCharacter();
 
3727                 // consume next character
 
3728                 scanner.unicodeAsBackSlash = false;
 
3729                 //                                                              if (((scanner.currentCharacter =
 
3730                 // source[scanner.currentPosition++]) == '\\')
 
3731                 // && (source[scanner.currentPosition] == 'u'))
 
3733                 //                                                                      scanner.getNextUnicodeChar();
 
3735                 if (scanner.withoutUnicodePtr != 0) {
 
3736                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
 
3743               if ((test = scanner.getNextChar('/', '*')) == 0) { //line
 
3746                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
 
3747                     && (source[scanner.currentPosition] == 'u')) {
 
3748                   //-------------unicode traitement
 
3750                   int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
3751                   scanner.currentPosition++;
 
3752                   while (source[scanner.currentPosition] == 'u') {
 
3753                     scanner.currentPosition++;
 
3755                   if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
 
3756                       || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
 
3757                       || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
 
3758                       || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
 
3762                     scanner.currentCharacter = 'A';
 
3763                   } //something different from \n and \r
 
3765                     scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
3768                 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
 
3770                   scanner.startPosition = scanner.currentPosition;
 
3771                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
 
3772                       && (source[scanner.currentPosition] == 'u')) {
 
3773                     //-------------unicode traitement
 
3775                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
3776                     scanner.currentPosition++;
 
3777                     while (source[scanner.currentPosition] == 'u') {
 
3778                       scanner.currentPosition++;
 
3780                     if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
 
3781                         || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
 
3782                         || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
 
3783                         || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
 
3787                       scanner.currentCharacter = 'A';
 
3788                     } //something different from \n
 
3791                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
3795                 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
 
3796                   if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
3797                     // only record line positions we
 
3798                     // have not recorded yet
 
3799                     scanner.pushLineSeparator();
 
3800                     if (this.scanner.taskTags != null) {
 
3801                       this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner
 
3802                           .getCurrentTokenEndPosition());
 
3808               if (test > 0) { //traditional and annotation
 
3810                 boolean star = false;
 
3811                 // consume next character
 
3812                 scanner.unicodeAsBackSlash = false;
 
3813                 //                                                                      if (((scanner.currentCharacter =
 
3814                 // source[scanner.currentPosition++]) ==
 
3816                 // (source[scanner.currentPosition] ==
 
3818                 //                                                                              scanner.getNextUnicodeChar();
 
3820                 if (scanner.withoutUnicodePtr != 0) {
 
3821                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
 
3824                 if (scanner.currentCharacter == '*') {
 
3828                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
 
3829                     && (source[scanner.currentPosition] == 'u')) {
 
3830                   //-------------unicode traitement
 
3832                   int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
3833                   scanner.currentPosition++;
 
3834                   while (source[scanner.currentPosition] == 'u') {
 
3835                     scanner.currentPosition++;
 
3837                   if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
 
3838                       || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
 
3839                       || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
 
3840                       || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
 
3844                     scanner.currentCharacter = 'A';
 
3845                   } //something different from * and /
 
3847                     scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
3850                 //loop until end of comment */
 
3851                 while ((scanner.currentCharacter != '/') || (!star)) {
 
3852                   star = scanner.currentCharacter == '*';
 
3854                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
 
3855                       && (source[scanner.currentPosition] == 'u')) {
 
3856                     //-------------unicode traitement
 
3858                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
3859                     scanner.currentPosition++;
 
3860                     while (source[scanner.currentPosition] == 'u') {
 
3861                       scanner.currentPosition++;
 
3863                     if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
 
3864                         || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
 
3865                         || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
 
3866                         || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
 
3870                       scanner.currentCharacter = 'A';
 
3871                     } //something different from * and
 
3874                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
3878                 if (this.scanner.taskTags != null) {
 
3879                   this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
 
3886               if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
 
3887                 scanner.scanIdentifierOrKeyword(false);
 
3890               if (Character.isDigit(scanner.currentCharacter)) {
 
3891                 scanner.scanNumber(false);
 
3895           //-----------------end switch while
 
3896           // try--------------------
 
3897         } catch (IndexOutOfBoundsException e) {
 
3898           break; // read until EOF
 
3899         } catch (InvalidInputException e) {
 
3900           return false; // no clue
 
3903       if (scanner.recordLineSeparator) {
 
3904         //                              compilationUnit.compilationResult.lineSeparatorPositions =
 
3905         // scanner.getLineEnds();
 
3907       // check placement anomalies against other kinds of brackets
 
3908       for (int kind = 0; kind < BracketKinds; kind++) {
 
3909         for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
 
3910           int start = leftPositions[kind][leftIndex]; // deepest
 
3912           // find matching closing bracket
 
3913           int depth = leftDepths[kind][leftIndex];
 
3915           for (int i = 0; i < rightCount[kind]; i++) {
 
3916             int pos = rightPositions[kind][i];
 
3917             // want matching bracket further in source with same
 
3919             if ((pos > start) && (depth == rightDepths[kind][i])) {
 
3924           if (end < 0) { // did not find a good closing match
 
3925             problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
 
3928           // check if even number of opening/closing other brackets
 
3929           // in between this pair of brackets
 
3931           for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
 
3932             for (int i = 0; i < leftCount[otherKind]; i++) {
 
3933               int pos = leftPositions[otherKind][i];
 
3934               if ((pos > start) && (pos < end))
 
3937             for (int i = 0; i < rightCount[otherKind]; i++) {
 
3938               int pos = rightPositions[otherKind][i];
 
3939               if ((pos > start) && (pos < end))
 
3943               problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket
 
3949         // too many opening brackets ?
 
3950         for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
 
3951           anomaliesDetected = true;
 
3952           problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext,
 
3953               compilationUnit.compilationResult);
 
3955         // too many closing brackets ?
 
3956         for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
 
3957           anomaliesDetected = true;
 
3958           problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
 
3960         if (anomaliesDetected)
 
3963       return anomaliesDetected;
 
3964     } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
 
3965       return anomaliesDetected;
 
3966     } catch (NullPointerException e) { // jdk1.2.2 jit bug
 
3967       return anomaliesDetected;
 
3970   protected void pushOnAstLengthStack(int pos) {
 
3972       astLengthStack[++astLengthPtr] = pos;
 
3973     } catch (IndexOutOfBoundsException e) {
 
3974       int oldStackLength = astLengthStack.length;
 
3975       int[] oldPos = astLengthStack;
 
3976       astLengthStack = new int[oldStackLength + StackIncrement];
 
3977       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
3978       astLengthStack[astLengthPtr] = pos;
 
3981   protected void pushOnAstStack(ASTNode node) {
 
3983      * add a new obj on top of the ast stack
 
3986       astStack[++astPtr] = node;
 
3987     } catch (IndexOutOfBoundsException e) {
 
3988       int oldStackLength = astStack.length;
 
3989       ASTNode[] oldStack = astStack;
 
3990       astStack = new ASTNode[oldStackLength + AstStackIncrement];
 
3991       System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
 
3992       astPtr = oldStackLength;
 
3993       astStack[astPtr] = node;
 
3996       astLengthStack[++astLengthPtr] = 1;
 
3997     } catch (IndexOutOfBoundsException e) {
 
3998       int oldStackLength = astLengthStack.length;
 
3999       int[] oldPos = astLengthStack;
 
4000       astLengthStack = new int[oldStackLength + AstStackIncrement];
 
4001       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
4002       astLengthStack[astLengthPtr] = 1;
 
4006   protected void resetModifiers() {
 
4007     this.modifiers = AccDefault;
 
4008     this.modifiersSourceStart = -1; // <-- see comment into
 
4009     // modifiersFlag(int)
 
4010     this.scanner.commentPtr = -1;