264b0ade2b69364b7db62e9ea251c512577c854a
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
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
6  * 
7  * Contributors: Klaus Hartlage - www.eclipseproject.de
8  ******************************************************************************/
9 package net.sourceforge.phpdt.internal.compiler.parser;
10 import java.util.ArrayList;
11
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;
31
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
45   // method bodies
46   //scanner token
47   public Scanner scanner;
48   private ArrayList phpList;
49   private int currentPHPString;
50   private boolean phpEnd;
51   // private static HashMap keywordMap = null;
52   private String str;
53   // current character
54   //  char ch;
55   // current token
56   int token;
57   // row counter for syntax errors:
58   //int rowCount;
59   // column counter for syntax errors:
60   //int columnCount;
61   //int chIndx;
62   //
63   //    // current identifier
64   //    String identifier;
65   Long longNumber;
66   Double doubleNumber;
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;
74   
75   protected Parser(ProblemReporter problemReporter) {
76     this.problemReporter = problemReporter;
77     this.options = problemReporter.options;
78     this.currentPHPString = 0;
79     //          PHPParserSuperclass.fileToParse = fileToParse;
80     this.phpList = null;
81 //    this.indexManager = null;
82     this.str = "";
83     this.token = TokenNameEOF;
84     //    this.chIndx = 0;
85     //    this.rowCount = 1;
86     //    this.columnCount = 0;
87     this.phpEnd = false;
88     //   getNextToken();
89     this.initializeScanner();
90   }
91   public void setFileToParse(IFile fileToParse) {
92     this.currentPHPString = 0;
93     //    PHPParserSuperclass.fileToParse = fileToParse;
94     this.phpList = null;
95 //    this.indexManager = null;
96     this.str = "";
97     this.token = TokenNameEOF;
98     this.phpEnd = false;
99     this.initializeScanner();
100   }
101   /**
102    * ClassDeclaration Constructor.
103    * 
104    * @param s
105    * @param sess
106    *          Description of Parameter
107    * @see
108    */
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]));
114     //      }
115     //    }
116     this.currentPHPString = 0;
117     //    PHPParserSuperclass.fileToParse = fileToParse;
118     this.phpList = null;
119     this.includesList = null;
120     this.str = "";
121     this.token = TokenNameEOF;
122     //    this.chIndx = 0;
123     //    this.rowCount = 1;
124     //    this.columnCount = 0;
125     this.phpEnd = false;
126     //   getNextToken();
127     this.initializeScanner();
128   }
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 */);
133   }
134   /**
135    * Create marker for the parse error
136    */
137   //  private void setMarker(String message, int charStart, int charEnd, int
138   // errorLevel) {
139   //    setMarker(fileToParse, message, charStart, charEnd, errorLevel);
140   //  }
141   /**
142    * This method will throw the SyntaxError. It will add the good lines and
143    * columns to the Error
144    * 
145    * @param error
146    *          the error message
147    * @throws SyntaxError
148    *           the error raised
149    */
150   private void throwSyntaxError(String error) {
151     int problemStartPosition = scanner.getCurrentTokenStartPosition();
152     int problemEndPosition = scanner.getCurrentTokenEndPosition();
153     throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
154   }
155   /**
156    * This method will throw the SyntaxError. It will add the good lines and
157    * columns to the Error
158    * 
159    * @param error
160    *          the error message
161    * @throws SyntaxError
162    *           the error raised
163    */
164   //  private void throwSyntaxError(String error, int startRow) {
165   //    throw new SyntaxError(startRow, 0, " ", error);
166   //  }
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);
171   }
172   private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
173     problemReporter.phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
174         compilationUnit.compilationResult);
175   }
176   private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) {
177     problemReporter.phpParsingWarning(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
178         compilationUnit.compilationResult);
179   }
180   /**
181    * Method Declaration.
182    * 
183    * @see
184    */
185   //  private void getChar() {
186   //    if (str.length() > chIndx) {
187   //      ch = str.charAt(chIndx++);
188   //
189   //      return;
190   //    }
191   //
192   //    chIndx = str.length() + 1;
193   //    ch = ' ';
194   //    // token = TokenNameEOF;
195   //    phpEnd = true;
196   //  }
197   /**
198    * gets the next token from input
199    */
200   private void getNextToken() {
201     try {
202       token = scanner.getNextToken();
203       if (Scanner.DEBUG) {
204         int currentEndPosition = scanner.getCurrentTokenEndPosition();
205         int currentStartPosition = scanner.getCurrentTokenStartPosition();
206         System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
207         System.out.println(scanner.toStringAction(token));
208       }
209     } catch (InvalidInputException e) {
210       token = TokenNameERROR;
211     }
212     return;
213   }
214   public void init(String s) {
215     this.str = s;
216     this.token = TokenNameEOF;
217     //    this.chIndx = 0;
218     //    this.rowCount = 1;
219     //    this.columnCount = 0;
220     this.phpEnd = false;
221     //    this.phpMode = false;
222     /* scanner initialization */
223     scanner.setSource(s.toCharArray());
224     scanner.setPHPMode(false);
225   }
226   protected void initialize(boolean phpMode) {
227     initialize(phpMode, null);
228   }
229   protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) {
230     compilationUnit = null;
231     referenceContext = null;
232     includesList = new ArrayList();
233 //    this.indexManager = indexManager;
234     this.str = "";
235     this.token = TokenNameEOF;
236     //    this.chIndx = 0;
237     //    this.rowCount = 1;
238     //    this.columnCount = 0;
239     this.phpEnd = false;
240     //    this.phpMode = phpMode;
241     scanner.setPHPMode(phpMode);
242   }
243   /**
244    * Parses a string with php tags i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt;
245    * &lt;/body&gt;'
246    */
247   public void parse(String s) {
248     init(s);
249     parse();
250   }
251   /**
252    * Parses a string with php tags i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt;
253    * &lt;/body&gt;'
254    */
255   protected void parse() {
256     getNextToken();
257     do {
258       try {
259         if (token != TokenNameEOF && token != TokenNameERROR) {
260           statementList();
261         }
262         if (token != TokenNameEOF) {
263           if (token == TokenNameERROR) {
264             throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
265           }
266           if (token == TokenNameRPAREN) {
267             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
268           }
269           if (token == TokenNameRBRACE) {
270             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
271           }
272           if (token == TokenNameRBRACKET) {
273             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
274           }
275           if (token == TokenNameLPAREN) {
276             throwSyntaxError("Read character '('; end-of-file not reached.");
277           }
278           if (token == TokenNameLBRACE) {
279             throwSyntaxError("Read character '{';  end-of-file not reached.");
280           }
281           if (token == TokenNameLBRACKET) {
282             throwSyntaxError("Read character '[';  end-of-file not reached.");
283           }
284           throwSyntaxError("End-of-file not reached.");
285         }
286         break;
287       } catch (SyntaxError sytaxErr1) {
288         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
289         // ERROR);
290         //        setMarker(sytaxErr1.getMessage(),
291         // scanner.getCurrentTokenStartPosition(),
292         // scanner.getCurrentTokenEndPosition(), ERROR);
293         try {
294           // if an error occured,
295           // try to find keywords 'class' or 'function'
296           // to parse the rest of the string
297           while (token != TokenNameEOF && token != TokenNameERROR) {
298             if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) {
299               break;
300             }
301             getNextToken();
302           }
303           if (token == TokenNameEOF || token == TokenNameERROR) {
304             break;
305           }
306         } catch (SyntaxError sytaxErr2) {
307           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
308           // ERROR);
309           //          setMarker(sytaxErr2.getMessage(),
310           // scanner.getCurrentTokenStartPosition(),
311           // scanner.getCurrentTokenEndPosition(), ERROR);
312           break;
313         }
314       }
315     } while (true);
316
317     endParse(0);
318   }
319
320   protected CompilationUnitDeclaration endParse(int act) {
321
322     this.lastAct = act;
323
324     if (currentElement != null) {
325       currentElement.topElement().updateParseTree();
326       if (VERBOSE_RECOVERY) {
327         System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
328         System.out.println("--------------------------"); //$NON-NLS-1$
329         System.out.println(compilationUnit);
330         System.out.println("----------------------------------"); //$NON-NLS-1$
331       }
332     } else {
333       if (diet & VERBOSE_RECOVERY) {
334         System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
335         System.out.println("--------------------------"); //$NON-NLS-1$
336         System.out.println(compilationUnit);
337         System.out.println("----------------------------------"); //$NON-NLS-1$
338       }
339     }
340     if (scanner.recordLineSeparator) {
341       compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
342     }
343     if (scanner.taskTags != null) {
344       for (int i = 0; i < scanner.foundTaskCount; i++) {
345         problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]),
346             scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
347             scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]);
348       }
349     }
350     compilationUnit.imports = new ImportReference[includesList.size()];
351     for (int i = 0; i < includesList.size(); i++) {
352       compilationUnit.imports[i] = (ImportReference) includesList.get(i);
353     }
354     return compilationUnit;
355   }
356   //  public PHPOutlineInfo parseInfo(Object parent, String s) {
357   //    PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
358   //    // Stack stack = new Stack();
359   //    // stack.push(outlineInfo.getDeclarations());
360   //    this.str = s;
361   //    this.token = TokenNameEOF;
362   //    // this.chIndx = 0;
363   //    // this.rowCount = 1;
364   //    // this.columnCount = 0;
365   //    this.phpEnd = false;
366   //    this.phpMode = false;
367   //    scanner.setSource(s.toCharArray());
368   //    scanner.setPHPMode(false);
369   //    
370   //    getNextToken();
371   //    parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
372   //    
373   //    return outlineInfo;
374   //  }
375   private boolean isVariable() {
376     return token == TokenNameVariable; //  || token == TokenNamethis;
377   }
378   //  private void parseDeclarations(PHPOutlineInfo outlineInfo,
379   //      OutlineableWithChildren current, boolean goBack) {
380   //    char[] ident;
381   //    // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
382   //    PHPSegmentWithChildren temp;
383   //    int counter = 0;
384   //    IPreferenceStore store =
385   // PHPeclipsePlugin.getDefault().getPreferenceStore();
386   //    try {
387   //      while (token != TokenNameEOF && token != TokenNameERROR) {
388   //        if (token == TokenNameVariable) {
389   //          ident = scanner.getCurrentIdentifierSource();
390   //          outlineInfo.addVariable(new String(ident));
391   //          getNextToken();
392   //        } else if (token == TokenNamevar) {
393   //          getNextToken();
394   //          if (token == TokenNameVariable
395   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
396   //            ident = scanner.getCurrentIdentifierSource();
397   //            //substring(1) added because PHPVarDeclaration doesn't
398   //            // need the $ anymore
399   //            String variableName = new String(ident).substring(1);
400   //            outlineInfo.addVariable(variableName);
401   //            getNextToken();
402   //            if (token != TokenNameSEMICOLON) {
403   //              getNextToken();
404   //              ident = scanner.getCurrentTokenSource();
405   //              if (token > TokenNameKEYWORD) {
406   //                current.add(new PHPVarDeclaration(current, variableName,
407   //                // chIndx - ident.length,
408   //                    scanner.getCurrentTokenStartPosition(), new String(ident)));
409   //              } else {
410   //                switch (token) {
411   //                  case TokenNameVariable :
412   //                  case TokenNamethis :
413   //                    current.add(new PHPVarDeclaration(current, variableName,
414   //                    // chIndx -
415   //                        // ident.length,
416   //                        scanner.getCurrentTokenStartPosition(), new String(
417   //                            ident)));
418   //                    break;
419   //                  case TokenNameIdentifier :
420   //                    current.add(new PHPVarDeclaration(current, variableName,
421   //                    // chIndx -
422   //                        // ident.length,
423   //                        scanner.getCurrentTokenStartPosition(), new String(
424   //                            ident)));
425   //                    break;
426   //                  case TokenNameDoubleLiteral :
427   //                    current.add(new PHPVarDeclaration(current, variableName
428   //                        + doubleNumber,
429   //                    // chIndx -
430   //                        // ident.length,
431   //                        scanner.getCurrentTokenStartPosition(), new String(
432   //                            ident)));
433   //                    break;
434   //                  case TokenNameIntegerLiteral :
435   //                    current.add(new PHPVarDeclaration(current, variableName,
436   //                    // chIndx -
437   //                        // ident.length,
438   //                        scanner.getCurrentTokenStartPosition(), new String(
439   //                            ident)));
440   //                    break;
441   //                  case TokenNameStringInterpolated :
442   //                  case TokenNameStringLiteral :
443   //                    current.add(new PHPVarDeclaration(current, variableName,
444   //                    // chIndx -
445   //                        // ident.length,
446   //                        scanner.getCurrentTokenStartPosition(), new String(
447   //                            ident)));
448   //                    break;
449   //                  case TokenNameStringConstant :
450   //                    current.add(new PHPVarDeclaration(current, variableName,
451   //                    // chIndx -
452   //                        // ident.length,
453   //                        scanner.getCurrentTokenStartPosition(), new String(
454   //                            ident)));
455   //                    break;
456   //                  default :
457   //                    current.add(new PHPVarDeclaration(current, variableName,
458   //                    // chIndx -
459   //                        // ident.length
460   //                        scanner.getCurrentTokenStartPosition()));
461   //                    break;
462   //                }
463   //              }
464   //            } else {
465   //              ident = scanner.getCurrentIdentifierSource();
466   //              current.add(new PHPVarDeclaration(current, variableName,
467   //              // chIndx - ident.length
468   //                  scanner.getCurrentTokenStartPosition()));
469   //            }
470   //          }
471   //        } else if (token == TokenNamefunction) {
472   //          getNextToken();
473   //          if (token == TokenNameAND) {
474   //            getNextToken();
475   //          }
476   //          if (token == TokenNameIdentifier
477   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
478   //            ident = scanner.getCurrentIdentifierSource();
479   //            outlineInfo.addVariable(new String(ident));
480   //            temp = new PHPFunctionDeclaration(current, new String(ident),
481   //            // chIndx - ident.length
482   //                scanner.getCurrentTokenStartPosition());
483   //            current.add(temp);
484   //            getNextToken();
485   //            parseDeclarations(outlineInfo, temp, true);
486   //          }
487   //        } else if (token == TokenNameclass) {
488   //          getNextToken();
489   //          if (token == TokenNameIdentifier
490   //              && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
491   //            ident = scanner.getCurrentIdentifierSource();
492   //            outlineInfo.addVariable(new String(ident));
493   //            temp = new PHPClassDeclaration(current, new String(ident),
494   //            // chIndx - ident.len
495   //                scanner.getCurrentTokenStartPosition());
496   //            current.add(temp);
497   //            // stack.push(temp);
498   //            getNextToken();
499   //            //skip tokens for classname, extends and others until
500   //            // we have the opening '{'
501   //            while (token != TokenNameLBRACE && token != TokenNameEOF
502   //                && token != TokenNameERROR) {
503   //              getNextToken();
504   //            }
505   //            parseDeclarations(outlineInfo, temp, true);
506   //            // stack.pop();
507   //          }
508   //        } else if ((token == TokenNameLBRACE)
509   //            || (token == TokenNameDOLLAR_LBRACE)) {
510   //          getNextToken();
511   //          counter++;
512   //        } else if (token == TokenNameRBRACE) {
513   //          getNextToken();
514   //          --counter;
515   //          if (counter == 0 && goBack) {
516   //            return;
517   //          }
518   //        } else if (token == TokenNamerequire || token == TokenNamerequire_once
519   //            || token == TokenNameinclude || token == TokenNameinclude_once) {
520   //          ident = scanner.getCurrentTokenSource();
521   //          getNextToken();
522   //          int startPosition = scanner.getCurrentTokenStartPosition();
523   //          expr();
524   //          char[] expr = scanner.getCurrentTokenSource(startPosition);
525   //          outlineInfo.addVariable(new String(ident));
526   //          current.add(new PHPReqIncDeclaration(current, new String(ident),
527   //          // chIndx - ident.length,
528   //              startPosition, new String(expr)));
529   //          getNextToken();
530   //        } else {
531   //          getNextToken();
532   //        }
533   //      }
534   //    } catch (SyntaxError sytaxErr) {
535   //      // try {
536   //      // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
537   //      // setMarker(sytaxErr.getMessage(),
538   //      // scanner.getCurrentTokenStartPosition(),
539   //      // scanner.getCurrentTokenEndPosition(), ERROR);
540   //      // } catch (CoreException e) {
541   //      // }
542   //    }
543   //  }
544   private void statementList() {
545     do {
546       statement(TokenNameEOF);
547       if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
548           || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
549           || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
550           || (token == TokenNameEOF) || (token == TokenNameERROR)) {
551         return;
552       }
553     } while (true);
554   }
555   private void functionBody(MethodDeclaration methodDecl) {
556     // '{' [statement-list] '}'
557     if (token == TokenNameLBRACE) {
558       getNextToken();
559     } else {
560       throwSyntaxError("'{' expected in compound-statement.");
561     }
562     if (token != TokenNameRBRACE) {
563       statementList();
564     }
565     if (token == TokenNameRBRACE) {
566       methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
567       getNextToken();
568     } else {
569       throwSyntaxError("'}' expected in compound-statement.");
570     }
571   }
572   private void statement(int previousToken) {
573     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
574     // TokenNamenew) {
575     //  char[] ident = scanner.getCurrentIdentifierSource();
576     //  String keyword = new String(ident);
577     //    if (token == TokenNameAT) {
578     //      getNextToken();
579     //      if (token != TokenNamerequire && token != TokenNamerequire_once
580     //          && token != TokenNameinclude && token != TokenNameinclude_once
581     //          && token != TokenNameIdentifier && token != TokenNameVariable
582     //          && token != TokenNameStringInterpolated) {
583     //        throwSyntaxError("identifier expected after '@'.");
584     //      }
585     //    }
586     //    if (token == TokenNameinclude || token == TokenNameinclude_once) {
587     //      getNextToken();
588     //      if (token == TokenNameLPAREN) {
589     //        expr();
590     //        if (token == TokenNameSEMICOLON) {
591     //          getNextToken();
592     //        } else {
593     //          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
594     //            throwSyntaxError("';' expected after 'include' or 'include_once'.");
595     //          }
596     //          // getNextToken();
597     //        }
598     //      } else {
599     //        concatenationExpression();
600     //      }
601     //      return;
602     //    } else if (token == TokenNamerequire || token ==
603     // TokenNamerequire_once)
604     // {
605     //      getNextToken();
606     //      //constant();
607     //      if (token == TokenNameLPAREN) {
608     //        expr();
609     //        if (token == TokenNameSEMICOLON) {
610     //          getNextToken();
611     //        } else {
612     //          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
613     //            throwSyntaxError("';' expected after 'require' or 'require_once'.");
614     //          }
615     //          // getNextToken();
616     //        }
617     //      } else {
618     //        concatenationExpression();
619     //      }
620     //      return;
621     //    } else
622     if (token == TokenNameif) {
623       getNextToken();
624       if (token == TokenNameLPAREN) {
625         getNextToken();
626       } else {
627         throwSyntaxError("'(' expected after 'if' keyword.");
628       }
629       expr();
630       if (token == TokenNameRPAREN) {
631         getNextToken();
632       } else {
633         throwSyntaxError("')' expected after 'if' condition.");
634       }
635       ifStatement();
636       return;
637     } else if (token == TokenNameswitch) {
638       getNextToken();
639       if (token == TokenNameLPAREN) {
640         getNextToken();
641       } else {
642         throwSyntaxError("'(' expected after 'switch' keyword.");
643       }
644       expr();
645       if (token == TokenNameRPAREN) {
646         getNextToken();
647       } else {
648         throwSyntaxError("')' expected after 'switch' condition.");
649       }
650       switchStatement();
651       return;
652     } else if (token == TokenNamefor) {
653       getNextToken();
654       if (token == TokenNameLPAREN) {
655         getNextToken();
656       } else {
657         throwSyntaxError("'(' expected after 'for' keyword.");
658       }
659       if (token == TokenNameSEMICOLON) {
660         getNextToken();
661       } else {
662         expressionList();
663         if (token == TokenNameSEMICOLON) {
664           getNextToken();
665         } else {
666           throwSyntaxError("';' expected after 'for'.");
667         }
668       }
669       if (token == TokenNameSEMICOLON) {
670         getNextToken();
671       } else {
672         expressionList();
673         if (token == TokenNameSEMICOLON) {
674           getNextToken();
675         } else {
676           throwSyntaxError("';' expected after 'for'.");
677         }
678       }
679       if (token == TokenNameRPAREN) {
680         getNextToken();
681       } else {
682         expressionList();
683         if (token == TokenNameRPAREN) {
684           getNextToken();
685         } else {
686           throwSyntaxError("')' expected after 'for'.");
687         }
688       }
689       forStatement();
690       return;
691     } else if (token == TokenNamewhile) {
692       getNextToken();
693       if (token == TokenNameLPAREN) {
694         getNextToken();
695       } else {
696         throwSyntaxError("'(' expected after 'while' keyword.");
697       }
698       expr();
699       if (token == TokenNameRPAREN) {
700         getNextToken();
701       } else {
702         throwSyntaxError("')' expected after 'while' condition.");
703       }
704       whileStatement();
705       return;
706     } else if (token == TokenNamedo) {
707       getNextToken();
708       if (token == TokenNameLBRACE) {
709         getNextToken();
710         if (token != TokenNameRBRACE) {
711           statementList();
712         }
713         if (token == TokenNameRBRACE) {
714           getNextToken();
715         } else {
716           throwSyntaxError("'}' expected after 'do' keyword.");
717         }
718       } else {
719         statement(TokenNameEOF);
720       }
721       if (token == TokenNamewhile) {
722         getNextToken();
723         if (token == TokenNameLPAREN) {
724           getNextToken();
725         } else {
726           throwSyntaxError("'(' expected after 'while' keyword.");
727         }
728         expr();
729         if (token == TokenNameRPAREN) {
730           getNextToken();
731         } else {
732           throwSyntaxError("')' expected after 'while' condition.");
733         }
734       } else {
735         throwSyntaxError("'while' expected after 'do' keyword.");
736       }
737       if (token == TokenNameSEMICOLON) {
738         getNextToken();
739       } else {
740         if (token != TokenNameINLINE_HTML) {
741           throwSyntaxError("';' expected after do-while statement.");
742         }
743         getNextToken();
744       }
745       return;
746     } else if (token == TokenNameforeach) {
747       getNextToken();
748       if (token == TokenNameLPAREN) {
749         getNextToken();
750       } else {
751         throwSyntaxError("'(' expected after 'foreach' keyword.");
752       }
753       expr();
754       if (token == TokenNameas) {
755         getNextToken();
756       } else {
757         throwSyntaxError("'as' expected after 'foreach' exxpression.");
758       }
759       //      variable();
760       foreach_variable();
761       foreach_optional_arg();
762       if (token == TokenNameEQUAL_GREATER) {
763         getNextToken();
764         variable();
765       }
766       if (token == TokenNameRPAREN) {
767         getNextToken();
768       } else {
769         throwSyntaxError("')' expected after 'foreach' expression.");
770       }
771       foreachStatement();
772       return;
773     } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
774       getNextToken();
775       if (token != TokenNameSEMICOLON) {
776         expr();
777       }
778       if (token == TokenNameSEMICOLON) {
779         getNextToken();
780       } else {
781         if (token != TokenNameINLINE_HTML) {
782           throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
783         }
784         getNextToken();
785       }
786       return;
787     } else if (token == TokenNameecho) {
788       getNextToken();
789       expressionList();
790       if (token == TokenNameSEMICOLON) {
791         getNextToken();
792       } else {
793         if (token != TokenNameINLINE_HTML) {
794           throwSyntaxError("';' expected after 'echo' statement.");
795         }
796         getNextToken();
797       }
798       return;
799     } else if (token == TokenNameINLINE_HTML) {
800       getNextToken();
801       return;
802       //    } else if (token == TokenNameprint) {
803       //      getNextToken();
804       //      expression();
805       //      if (token == TokenNameSEMICOLON) {
806       //        getNextToken();
807       //      } else {
808       //        if (token != TokenNameStopPHP) {
809       //          throwSyntaxError("';' expected after 'print' statement.");
810       //        }
811       //        getNextToken();
812       //      }
813       //      return;
814     } else if (token == TokenNameglobal) {
815       getNextToken();
816       global_var_list();
817       if (token == TokenNameSEMICOLON) {
818         getNextToken();
819       } else {
820         if (token != TokenNameINLINE_HTML) {
821           throwSyntaxError("';' expected after 'global' statement.");
822         }
823         getNextToken();
824       }
825       return;
826     } else if (token == TokenNamestatic) {
827       getNextToken();
828       static_var_list();
829       if (token == TokenNameSEMICOLON) {
830         getNextToken();
831       } else {
832         if (token != TokenNameINLINE_HTML) {
833           throwSyntaxError("';' expected after 'static' statement.");
834         }
835         getNextToken();
836       }
837       return;
838     } else if (token == TokenNameunset) {
839       getNextToken();
840       if (token == TokenNameLPAREN) {
841         getNextToken();
842       } else {
843         throwSyntaxError("'(' expected after 'unset' statement.");
844       }
845       unset_variables();
846       if (token == TokenNameRPAREN) {
847         getNextToken();
848       } else {
849         throwSyntaxError("')' expected after 'unset' statement.");
850       }
851       if (token == TokenNameSEMICOLON) {
852         getNextToken();
853       } else {
854         if (token != TokenNameINLINE_HTML) {
855           throwSyntaxError("';' expected after 'unset' statement.");
856         }
857         getNextToken();
858       }
859       return;
860     } else if (token == TokenNamefunction) {
861       MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
862       methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
863       methodDecl.modifiers = AccDefault;
864       getNextToken();
865       functionDefinition(methodDecl);
866       return;
867     } else if (token == TokenNametry) {
868       getNextToken();
869       if (token != TokenNameLBRACE) {
870         throwSyntaxError("'{' expected in 'try' statement.");
871       }
872       getNextToken();
873       statementList();
874       if (token != TokenNameRBRACE) {
875         throwSyntaxError("'}' expected in 'try' statement.");
876       }
877       getNextToken();
878       return;
879     } else if (token == TokenNamecatch) {
880       getNextToken();
881       if (token != TokenNameLPAREN) {
882         throwSyntaxError("'(' expected in 'catch' statement.");
883       }
884       getNextToken();
885       fully_qualified_class_name();
886       if (token != TokenNameVariable) {
887         throwSyntaxError("Variable expected in 'catch' statement.");
888       }
889       getNextToken();
890       if (token != TokenNameRPAREN) {
891         throwSyntaxError("')' expected in 'catch' statement.");
892       }
893       getNextToken();
894       if (token != TokenNameLBRACE) {
895         throwSyntaxError("'{' expected in 'catch' statement.");
896       }
897       getNextToken();
898       if (token != TokenNameRBRACE) {
899         statementList();
900         if (token != TokenNameRBRACE) {
901           throwSyntaxError("'}' expected in 'catch' statement.");
902         }
903       }
904       getNextToken();
905       additional_catches();
906       return;
907     } else if (token == TokenNamethrow) {
908       getNextToken();
909       expr();
910       if (token == TokenNameSEMICOLON) {
911         getNextToken();
912       } else {
913         throwSyntaxError("';' expected after 'throw' exxpression.");
914       }
915       return;
916     } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
917       TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
918       typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
919       // default super class
920       typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
921       compilationUnit.types.add(typeDecl);
922       try {
923         pushOnAstStack(typeDecl);
924         unticked_class_declaration_statement(typeDecl);
925         //        classBody(typeDecl);
926       } finally {
927         astPtr--;
928         astLengthPtr--;
929       }
930       return;
931       //      } else {
932       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
933     } else if (token == TokenNameLBRACE) {
934       getNextToken();
935       if (token != TokenNameRBRACE) {
936         statementList();
937       }
938       if (token == TokenNameRBRACE) {
939         getNextToken();
940         return;
941       } else {
942         throwSyntaxError("'}' expected.");
943       }
944     } else {
945       if (token != TokenNameSEMICOLON) {
946         expr();
947       }
948       if (token == TokenNameSEMICOLON) {
949         getNextToken();
950         return;
951       } else {
952         if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
953           throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
954         }
955         getNextToken();
956       }
957     }
958   }
959   private void additional_catches() {
960     while (token == TokenNamecatch) {
961       getNextToken();
962       if (token != TokenNameLPAREN) {
963         throwSyntaxError("'(' expected in 'catch' statement.");
964       }
965       getNextToken();
966       fully_qualified_class_name();
967       if (token != TokenNameVariable) {
968         throwSyntaxError("Variable expected in 'catch' statement.");
969       }
970       getNextToken();
971       if (token != TokenNameRPAREN) {
972         throwSyntaxError("')' expected in 'catch' statement.");
973       }
974       getNextToken();
975       if (token != TokenNameLBRACE) {
976         throwSyntaxError("'{' expected in 'catch' statement.");
977       }
978       getNextToken();
979       statementList();
980       if (token != TokenNameRBRACE) {
981         throwSyntaxError("'}' expected in 'catch' statement.");
982       }
983       getNextToken();
984     }
985   }
986   private void foreach_variable() {
987     //  w_variable
988     //| '&' w_variable
989     if (token == TokenNameAND) {
990       getNextToken();
991     }
992     w_variable();
993   }
994   private void foreach_optional_arg() {
995     //  /* empty */
996     //| T_DOUBLE_ARROW foreach_variable
997     if (token == TokenNameEQUAL_GREATER) {
998       getNextToken();
999       foreach_variable();
1000     }
1001   }
1002   private void global_var_list() {
1003     //  global_var_list:
1004     //  global_var_list ',' global_var
1005     //| global_var
1006     while (true) {
1007       global_var();
1008       if (token != TokenNameCOMMA) {
1009         break;
1010       }
1011       getNextToken();
1012     }
1013   }
1014   private void global_var() {
1015     //global_var:
1016     //  T_VARIABLE
1017     //| '$' r_variable
1018     //| '$' '{' expr '}'
1019     if (token == TokenNameVariable) {
1020       getNextToken();
1021     } else if (token == TokenNameDOLLAR) {
1022       getNextToken();
1023       if (token == TokenNameLPAREN) {
1024         getNextToken();
1025         expr();
1026         if (token != TokenNameLPAREN) {
1027           throwSyntaxError("')' expected in global variable.");
1028         }
1029         getNextToken();
1030       } else {
1031         r_variable();
1032       }
1033     }
1034   }
1035   private void static_var_list() {
1036     //static_var_list:
1037     //  static_var_list ',' T_VARIABLE
1038     //| static_var_list ',' T_VARIABLE '=' static_scalar
1039     //| T_VARIABLE
1040     //| T_VARIABLE '=' static_scalar
1041     while (true) {
1042       if (token == TokenNameVariable) {
1043         getNextToken();
1044         if (token == TokenNameEQUAL) {
1045           getNextToken();
1046           static_scalar();
1047         }
1048         if (token != TokenNameCOMMA) {
1049           break;
1050         }
1051         getNextToken();
1052       } else {
1053         break;
1054       }
1055     }
1056   }
1057   private void unset_variables() {
1058     //    unset_variables:
1059     //                  unset_variable
1060     //          | unset_variables ',' unset_variable
1061     //    unset_variable:
1062     //                  variable
1063     while (true) {
1064       variable();
1065       if (token != TokenNameCOMMA) {
1066         break;
1067       }
1068       getNextToken();
1069     }
1070   }
1071   private final void initializeModifiers() {
1072     this.modifiers = 0;
1073     this.modifiersSourceStart = -1;
1074   }
1075   private final void checkAndSetModifiers(int flag) {
1076     this.modifiers |= flag;
1077     if (this.modifiersSourceStart < 0)
1078       this.modifiersSourceStart = this.scanner.startPosition;
1079   }
1080   private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1081     initializeModifiers();
1082     if (token == TokenNameinterface) {
1083       //      interface_entry T_STRING
1084       //                interface_extends_list
1085       //                '{' class_statement_list '}'
1086       checkAndSetModifiers(AccInterface);
1087       getNextToken();
1088       typeDecl.modifiers = this.modifiers;
1089       if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1090         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1091         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1092         typeDecl.name = scanner.getCurrentIdentifierSource();
1093         if (token > TokenNameKEYWORD) {
1094           throwSyntaxError("Don't use a keyword for interface declaration [" + scanner.toStringAction(token) + "].",
1095               typeDecl.sourceStart, typeDecl.sourceEnd);
1096         }
1097         getNextToken();
1098         interface_extends_list();
1099       } else {
1100         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1101         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1102         typeDecl.name = new char[]{' '};
1103         throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1104         return;
1105       }
1106     } else {
1107       //      class_entry_type T_STRING extends_from
1108       //                implements_list
1109       //                '{' class_statement_list'}'
1110       class_entry_type();
1111       typeDecl.modifiers = this.modifiers;
1112       //identifier
1113       //identifier 'extends' identifier
1114       if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1115         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1116         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1117         typeDecl.name = scanner.getCurrentIdentifierSource();
1118         if (token > TokenNameKEYWORD) {
1119           throwSyntaxError("Don't use a keyword for class declaration [" + scanner.toStringAction(token) + "].",
1120               typeDecl.sourceStart, typeDecl.sourceEnd);
1121         }
1122         getNextToken();
1123         //    extends_from:
1124         //              /* empty */
1125         //      | T_EXTENDS fully_qualified_class_name
1126         if (token == TokenNameextends) {
1127           interface_extends_list();
1128           //          getNextToken();
1129           //          if (token != TokenNameIdentifier) {
1130           //            throwSyntaxError("Class name expected after keyword
1131           // 'extends'.",
1132           //                scanner.getCurrentTokenStartPosition(), scanner
1133           //                    .getCurrentTokenEndPosition());
1134           //          }
1135         }
1136         implements_list();
1137       } else {
1138         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1139         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1140         typeDecl.name = new char[]{' '};
1141         throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1142         return;
1143       }
1144     }
1145     //  '{' class_statement_list '}'
1146     if (token == TokenNameLBRACE) {
1147       getNextToken();
1148       if (token != TokenNameRBRACE) {
1149         ArrayList list = new ArrayList();
1150         class_statement_list(list);
1151         typeDecl.fields = new FieldDeclaration[list.size()];
1152         for (int i = 0; i < list.size(); i++) {
1153           typeDecl.fields[i] = (FieldDeclaration) list.get(i);
1154         }
1155       }
1156       if (token == TokenNameRBRACE) {
1157         typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1158         getNextToken();
1159       } else {
1160         throwSyntaxError("'}' expected at end of class body.");
1161       }
1162     } else {
1163       throwSyntaxError("'{' expected at start of class body.");
1164     }
1165   }
1166   private void class_entry_type() {
1167     //  T_CLASS
1168     //  | T_ABSTRACT T_CLASS
1169     //  | T_FINAL T_CLASS
1170     if (token == TokenNameclass) {
1171       getNextToken();
1172     } else if (token == TokenNameabstract) {
1173       checkAndSetModifiers(AccAbstract);
1174       getNextToken();
1175       if (token != TokenNameclass) {
1176         throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1177       }
1178       getNextToken();
1179     } else if (token == TokenNamefinal) {
1180       checkAndSetModifiers(AccFinal);
1181       getNextToken();
1182       if (token != TokenNameclass) {
1183         throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1184       }
1185       getNextToken();
1186     } else {
1187       throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1188     }
1189   }
1190   private void interface_extends_list() {
1191     //  /* empty */
1192     //  | T_EXTENDS interface_list
1193     if (token == TokenNameextends) {
1194       getNextToken();
1195       interface_list();
1196     }
1197   }
1198   private void implements_list() {
1199     //  /* empty */
1200     //  | T_IMPLEMENTS interface_list
1201     if (token == TokenNameimplements) {
1202       getNextToken();
1203       interface_list();
1204     }
1205   }
1206   private void interface_list() {
1207     //  interface_list:
1208     //  fully_qualified_class_name
1209     //| interface_list ',' fully_qualified_class_name
1210     do {
1211       if (token == TokenNameIdentifier) {
1212         getNextToken();
1213       } else {
1214         throwSyntaxError("Interface name expected after keyword 'implements'.");
1215       }
1216       if (token != TokenNameCOMMA) {
1217         return;
1218       }
1219       getNextToken();
1220     } while (true);
1221   }
1222   //  private void classBody(TypeDeclaration typeDecl) {
1223   //    //'{' [class-element-list] '}'
1224   //    if (token == TokenNameLBRACE) {
1225   //      getNextToken();
1226   //      if (token != TokenNameRBRACE) {
1227   //        class_statement_list();
1228   //      }
1229   //      if (token == TokenNameRBRACE) {
1230   //        typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1231   //        getNextToken();
1232   //      } else {
1233   //        throwSyntaxError("'}' expected at end of class body.");
1234   //      }
1235   //    } else {
1236   //      throwSyntaxError("'{' expected at start of class body.");
1237   //    }
1238   //  }
1239   private void class_statement_list(ArrayList list) {
1240     do {
1241       class_statement(list);
1242     } while (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
1243         || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
1244         || token == TokenNameconst);
1245   }
1246   private void class_statement(ArrayList list) {
1247     //    class_statement:
1248     //          variable_modifiers class_variable_declaration ';'
1249     //  | class_constant_declaration ';'
1250     //  | method_modifiers T_FUNCTION is_reference T_STRING
1251     //    '(' parameter_list ')' method_body
1252     initializeModifiers();
1253     int declarationSourceStart = scanner.getCurrentTokenStartPosition();
1254     ;
1255     if (token == TokenNamevar) {
1256       checkAndSetModifiers(AccPublic);
1257       problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
1258           referenceContext, compilationUnit.compilationResult);
1259       getNextToken();
1260       class_variable_declaration(declarationSourceStart, list);
1261     } else if (token == TokenNameconst) {
1262       checkAndSetModifiers(AccFinal|AccPublic);
1263       class_constant_declaration(declarationSourceStart, list);
1264       if (token != TokenNameSEMICOLON) {
1265         throwSyntaxError("';' expected after class const declaration.");
1266       }
1267       getNextToken();
1268     } else {
1269       boolean hasModifiers = member_modifiers();
1270       if (token == TokenNamefunction) {
1271         if (!hasModifiers) {
1272           checkAndSetModifiers(AccPublic);
1273         }
1274         MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
1275         methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
1276         methodDecl.modifiers = this.modifiers;
1277         getNextToken();
1278         functionDefinition(methodDecl);
1279       } else {
1280         if (!hasModifiers) {
1281           throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1282         }
1283         class_variable_declaration(declarationSourceStart, list);
1284       }
1285     }
1286   }
1287   private void class_constant_declaration(int declarationSourceStart, ArrayList list) {
1288     //  class_constant_declaration ',' T_STRING '=' static_scalar
1289     //  | T_CONST T_STRING '=' static_scalar
1290     if (token != TokenNameconst) {
1291       throwSyntaxError("'const' keyword expected in class declaration.");
1292     } else {
1293       getNextToken();
1294     }
1295     while (true) {
1296       if (token != TokenNameIdentifier) {
1297         throwSyntaxError("Identifier expected in class const declaration.");
1298       }
1299       FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
1300           .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1301       fieldDeclaration.modifiers = this.modifiers;
1302       fieldDeclaration.declarationSourceStart = declarationSourceStart;
1303       fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1304       fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1305       //        fieldDeclaration.type
1306       list.add(fieldDeclaration);
1307       getNextToken();
1308       if (token != TokenNameEQUAL) {
1309         throwSyntaxError("'=' expected in class const declaration.");
1310       }
1311       getNextToken();
1312       static_scalar();
1313       if (token != TokenNameCOMMA) {
1314         break; // while(true)-loop
1315       }
1316       getNextToken();
1317     }
1318   }
1319   //  private void variable_modifiers() {
1320   //    // variable_modifiers:
1321   //    // non_empty_member_modifiers
1322   //    //| T_VAR
1323   //    initializeModifiers();
1324   //    if (token == TokenNamevar) {
1325   //      checkAndSetModifiers(AccPublic);
1326   //      reportSyntaxError(
1327   //          "Keyword 'var' is deprecated. Please use 'public' 'private' or
1328   // 'protected'
1329   // modifier for field declarations.",
1330   //          scanner.getCurrentTokenStartPosition(), scanner
1331   //              .getCurrentTokenEndPosition());
1332   //      getNextToken();
1333   //    } else {
1334   //      if (!member_modifiers()) {
1335   //        throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1336   // field declarations.");
1337   //      }
1338   //    }
1339   //  }
1340   //  private void method_modifiers() {
1341   //    //method_modifiers:
1342   //    // /* empty */
1343   //    //| non_empty_member_modifiers
1344   //    initializeModifiers();
1345   //    if (!member_modifiers()) {
1346   //      checkAndSetModifiers(AccPublic);
1347   //    }
1348   //  }
1349   private boolean member_modifiers() {
1350     //  T_PUBLIC
1351     //| T_PROTECTED
1352     //| T_PRIVATE
1353     //| T_STATIC
1354     //| T_ABSTRACT
1355     //| T_FINAL
1356     boolean foundToken = false;
1357     while (true) {
1358       if (token == TokenNamepublic) {
1359         checkAndSetModifiers(AccPublic);
1360         getNextToken();
1361         foundToken = true;
1362       } else if (token == TokenNameprotected) {
1363         checkAndSetModifiers(AccProtected);
1364         getNextToken();
1365         foundToken = true;
1366       } else if (token == TokenNameprivate) {
1367         checkAndSetModifiers(AccPrivate);
1368         getNextToken();
1369         foundToken = true;
1370       } else if (token == TokenNamestatic) {
1371         checkAndSetModifiers(AccStatic);
1372         getNextToken();
1373         foundToken = true;
1374       } else if (token == TokenNameabstract) {
1375         checkAndSetModifiers(AccAbstract);
1376         getNextToken();
1377         foundToken = true;
1378       } else if (token == TokenNamefinal) {
1379         checkAndSetModifiers(AccFinal);
1380         getNextToken();
1381         foundToken = true;
1382       } else {
1383         break;
1384       }
1385     }
1386     return foundToken;
1387   }
1388   private void class_variable_declaration(int declarationSourceStart, ArrayList list) {
1389     //    class_variable_declaration:
1390     //          class_variable_declaration ',' T_VARIABLE
1391     //  | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1392     //  | T_VARIABLE
1393     //  | T_VARIABLE '=' static_scalar
1394     char[] classVariable;
1395     do {
1396       if (token == TokenNameVariable) {
1397         classVariable = scanner.getCurrentIdentifierSource();
1398       //  indexManager.addIdentifierInformation('v', classVariable, buf, -1, -1);
1399         FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner
1400             .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1401         fieldDeclaration.modifiers = this.modifiers;
1402         fieldDeclaration.declarationSourceStart = declarationSourceStart;
1403         fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1404         fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1405         //        fieldDeclaration.type
1406         list.add(fieldDeclaration);
1407         getNextToken();
1408         if (token == TokenNameEQUAL) {
1409           getNextToken();
1410           static_scalar();
1411         }
1412       } else {
1413         //        if (token == TokenNamethis) {
1414         //          throwSyntaxError("'$this' not allowed after keyword 'public'
1415         // 'protected' 'private' 'var'.");
1416         //        }
1417         throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1418       }
1419       if (token != TokenNameCOMMA) {
1420         break;
1421       }
1422       getNextToken();
1423     } while (true);
1424     if (token != TokenNameSEMICOLON) {
1425       throwSyntaxError("';' expected after field declaration.");
1426     }
1427     getNextToken();
1428   }
1429   private void functionDefinition(MethodDeclaration methodDecl) {
1430     boolean isAbstract = false;
1431     if (astPtr == 0) {
1432       compilationUnit.types.add(methodDecl);
1433     } else {
1434       AstNode node = astStack[astPtr];
1435       if (node instanceof TypeDeclaration) {
1436         TypeDeclaration typeDecl = ((TypeDeclaration) node);
1437         if (typeDecl.methods == null) {
1438           typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1439         } else {
1440           AbstractMethodDeclaration[] newMethods;
1441           System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1,
1442               typeDecl.methods.length);
1443           newMethods[0] = methodDecl;
1444           typeDecl.methods = newMethods;
1445         }
1446         if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1447           isAbstract = true;
1448         } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1449           isAbstract = true;
1450         }
1451       }
1452     }
1453     functionDeclarator(methodDecl);
1454     if (token == TokenNameSEMICOLON) {
1455       if (!isAbstract) {
1456         throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
1457       }
1458       getNextToken();
1459       return;
1460     }
1461     functionBody(methodDecl);
1462   }
1463   private void functionDeclarator(MethodDeclaration methodDecl) {
1464     //identifier '(' [parameter-list] ')'
1465     if (token == TokenNameAND) {
1466       getNextToken();
1467     }
1468     methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1469     methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1470     if (Scanner.isIdentifierOrKeyword(token)) {
1471       methodDecl.selector = scanner.getCurrentIdentifierSource();
1472       if (token > TokenNameKEYWORD) {
1473         reportSyntaxWarning("Don't use keyword for function declaration [" + scanner.toStringAction(token) + "].",
1474           scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1475 //        throwSyntaxError("Don't use keyword for function declaration [" + scanner.toStringAction(token) + "].");
1476       }
1477       getNextToken();
1478       if (token == TokenNameLPAREN) {
1479         getNextToken();
1480       } else {
1481         throwSyntaxError("'(' expected in function declaration.");
1482       }
1483       if (token != TokenNameRPAREN) {
1484         parameter_list();
1485       }
1486       if (token != TokenNameRPAREN) {
1487         throwSyntaxError("')' expected in function declaration.");
1488       } else {
1489         methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1490         getNextToken();
1491       }
1492     } else {
1493       methodDecl.selector = "<undefined>".toCharArray();
1494       throwSyntaxError("Function name expected after keyword 'function'.");
1495     }
1496   }
1497   //
1498   private void parameter_list() {
1499     //  non_empty_parameter_list
1500     //  | /* empty */
1501     non_empty_parameter_list(true);
1502   }
1503   private void non_empty_parameter_list(boolean empty_allowed) {
1504     //  optional_class_type T_VARIABLE
1505     //  | optional_class_type '&' T_VARIABLE
1506     //  | optional_class_type '&' T_VARIABLE '=' static_scalar
1507     //  | optional_class_type T_VARIABLE '=' static_scalar
1508     //  | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1509     //  | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1510     //  | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1511     // static_scalar
1512     //  | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1513     // static_scalar
1514     if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
1515       while (true) {
1516         if (token == TokenNameIdentifier) {
1517           getNextToken();
1518         }
1519         if (token == TokenNameAND) {
1520           getNextToken();
1521         }
1522         if (token == TokenNameVariable) {
1523           getNextToken();
1524           if (token == TokenNameEQUAL) {
1525             getNextToken();
1526             static_scalar();
1527           }
1528         } else {
1529           throwSyntaxError("Variable expected in parameter list.");
1530         }
1531         if (token != TokenNameCOMMA) {
1532           break;
1533         }
1534         getNextToken();
1535       }
1536       return;
1537     }
1538     if (!empty_allowed) {
1539       throwSyntaxError("Identifier expected in parameter list.");
1540     }
1541   }
1542   private void optional_class_type() {
1543     //  /* empty */
1544     //| T_STRING
1545   }
1546   private void parameterDeclaration() {
1547     //variable
1548     //variable-reference
1549     if (token == TokenNameAND) {
1550       getNextToken();
1551       if (isVariable()) {
1552         getNextToken();
1553       } else {
1554         throwSyntaxError("Variable expected after reference operator '&'.");
1555       }
1556     }
1557     //variable '=' constant
1558     if (token == TokenNameVariable) {
1559       getNextToken();
1560       if (token == TokenNameEQUAL) {
1561         getNextToken();
1562         static_scalar();
1563       }
1564       return;
1565     }
1566     //    if (token == TokenNamethis) {
1567     //      throwSyntaxError("Reserved word '$this' not allowed in parameter
1568     // declaration.");
1569     //    }
1570   }
1571   private void labeledStatementList() {
1572     if (token != TokenNamecase && token != TokenNamedefault) {
1573       throwSyntaxError("'case' or 'default' expected.");
1574     }
1575     do {
1576       if (token == TokenNamecase) {
1577         getNextToken();
1578         expr(); //constant();
1579         if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1580           getNextToken();
1581           if (token == TokenNamecase || token == TokenNamedefault) {
1582             // empty case statement ?
1583             continue;
1584           }
1585           statementList();
1586         }
1587         //        else if (token == TokenNameSEMICOLON) {
1588         //          setMarker(
1589         //            "':' expected after 'case' keyword (Found token: " +
1590         // scanner.toStringAction(token) + ")",
1591         //            scanner.getCurrentTokenStartPosition(),
1592         //            scanner.getCurrentTokenEndPosition(),
1593         //            INFO);
1594         //          getNextToken();
1595         //          if (token == TokenNamecase) { // empty case statement ?
1596         //            continue;
1597         //          }
1598         //          statementList();
1599         //        }
1600         else {
1601           throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")");
1602         }
1603       } else { // TokenNamedefault
1604         getNextToken();
1605         if (token == TokenNameCOLON) {
1606           getNextToken();
1607           if (token == TokenNameRBRACE) {
1608             // empty default case
1609             break;
1610           }
1611           statementList();
1612         } else {
1613           throwSyntaxError("':' character after 'default' expected.");
1614         }
1615       }
1616     } while (token == TokenNamecase || token == TokenNamedefault);
1617   }
1618   //  public void labeledStatement() {
1619   //    if (token == TokenNamecase) {
1620   //      getNextToken();
1621   //      constant();
1622   //      if (token == TokenNameDDOT) {
1623   //        getNextToken();
1624   //        statement();
1625   //      } else {
1626   //        throwSyntaxError("':' character after 'case' constant expected.");
1627   //      }
1628   //      return;
1629   //    } else if (token == TokenNamedefault) {
1630   //      getNextToken();
1631   //      if (token == TokenNameDDOT) {
1632   //        getNextToken();
1633   //        statement();
1634   //      } else {
1635   //        throwSyntaxError("':' character after 'default' expected.");
1636   //      }
1637   //      return;
1638   //    }
1639   //  }
1640   //  public void expressionStatement() {
1641   //  }
1642   //  private void inclusionStatement() {
1643   //  }
1644   //  public void compoundStatement() {
1645   //  }
1646   //  public void selectionStatement() {
1647   //  }
1648   //
1649   //  public void iterationStatement() {
1650   //  }
1651   //
1652   //  public void jumpStatement() {
1653   //  }
1654   //
1655   //  public void outputStatement() {
1656   //  }
1657   //
1658   //  public void scopeStatement() {
1659   //  }
1660   //
1661   //  public void flowStatement() {
1662   //  }
1663   //
1664   //  public void definitionStatement() {
1665   //  }
1666   private void ifStatement() {
1667     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1668     if (token == TokenNameCOLON) {
1669       getNextToken();
1670       if (token != TokenNameendif) {
1671         statementList();
1672         switch (token) {
1673           case TokenNameelse :
1674             getNextToken();
1675             if (token == TokenNameCOLON) {
1676               getNextToken();
1677               if (token != TokenNameendif) {
1678                 statementList();
1679               }
1680             } else {
1681               if (token == TokenNameif) { //'else if'
1682                 getNextToken();
1683                 elseifStatementList();
1684               } else {
1685                 throwSyntaxError("':' expected after 'else'.");
1686               }
1687             }
1688             break;
1689           case TokenNameelseif :
1690             getNextToken();
1691             elseifStatementList();
1692             break;
1693         }
1694       }
1695       if (token != TokenNameendif) {
1696         throwSyntaxError("'endif' expected.");
1697       }
1698       getNextToken();
1699       if (token != TokenNameSEMICOLON) {
1700         throwSyntaxError("';' expected after if-statement.");
1701       }
1702       getNextToken();
1703     } else {
1704       // statement [else-statement]
1705       statement(TokenNameEOF);
1706       if (token == TokenNameelseif) {
1707         getNextToken();
1708         if (token == TokenNameLPAREN) {
1709           getNextToken();
1710         } else {
1711           throwSyntaxError("'(' expected after 'elseif' keyword.");
1712         }
1713         expr();
1714         if (token == TokenNameRPAREN) {
1715           getNextToken();
1716         } else {
1717           throwSyntaxError("')' expected after 'elseif' condition.");
1718         }
1719         ifStatement();
1720       } else if (token == TokenNameelse) {
1721         getNextToken();
1722         statement(TokenNameEOF);
1723       }
1724     }
1725   }
1726   private void elseifStatementList() {
1727     do {
1728       elseifStatement();
1729       switch (token) {
1730         case TokenNameelse :
1731           getNextToken();
1732           if (token == TokenNameCOLON) {
1733             getNextToken();
1734             if (token != TokenNameendif) {
1735               statementList();
1736             }
1737             return;
1738           } else {
1739             if (token == TokenNameif) { //'else if'
1740               getNextToken();
1741             } else {
1742               throwSyntaxError("':' expected after 'else'.");
1743             }
1744           }
1745           break;
1746         case TokenNameelseif :
1747           getNextToken();
1748           break;
1749         default :
1750           return;
1751       }
1752     } while (true);
1753   }
1754   private void elseifStatement() {
1755     if (token == TokenNameLPAREN) {
1756       getNextToken();
1757       expr();
1758       if (token != TokenNameRPAREN) {
1759         throwSyntaxError("')' expected in else-if-statement.");
1760       }
1761       getNextToken();
1762       if (token != TokenNameCOLON) {
1763         throwSyntaxError("':' expected in else-if-statement.");
1764       }
1765       getNextToken();
1766       if (token != TokenNameendif) {
1767         statementList();
1768       }
1769     }
1770   }
1771   private void switchStatement() {
1772     if (token == TokenNameCOLON) {
1773       // ':' [labeled-statement-list] 'endswitch' ';'
1774       getNextToken();
1775       labeledStatementList();
1776       if (token != TokenNameendswitch) {
1777         throwSyntaxError("'endswitch' expected.");
1778       }
1779       getNextToken();
1780       if (token != TokenNameSEMICOLON) {
1781         throwSyntaxError("';' expected after switch-statement.");
1782       }
1783       getNextToken();
1784     } else {
1785       // '{' [labeled-statement-list] '}'
1786       if (token != TokenNameLBRACE) {
1787         throwSyntaxError("'{' expected in switch statement.");
1788       }
1789       getNextToken();
1790       if (token != TokenNameRBRACE) {
1791         labeledStatementList();
1792       }
1793       if (token != TokenNameRBRACE) {
1794         throwSyntaxError("'}' expected in switch statement.");
1795       }
1796       getNextToken();
1797     }
1798   }
1799   private void forStatement() {
1800     if (token == TokenNameCOLON) {
1801       getNextToken();
1802       statementList();
1803       if (token != TokenNameendfor) {
1804         throwSyntaxError("'endfor' expected.");
1805       }
1806       getNextToken();
1807       if (token != TokenNameSEMICOLON) {
1808         throwSyntaxError("';' expected after for-statement.");
1809       }
1810       getNextToken();
1811     } else {
1812       statement(TokenNameEOF);
1813     }
1814   }
1815   private void whileStatement() {
1816     // ':' statement-list 'endwhile' ';'
1817     if (token == TokenNameCOLON) {
1818       getNextToken();
1819       statementList();
1820       if (token != TokenNameendwhile) {
1821         throwSyntaxError("'endwhile' expected.");
1822       }
1823       getNextToken();
1824       if (token != TokenNameSEMICOLON) {
1825         throwSyntaxError("';' expected after while-statement.");
1826       }
1827       getNextToken();
1828     } else {
1829       statement(TokenNameEOF);
1830     }
1831   }
1832   private void foreachStatement() {
1833     if (token == TokenNameCOLON) {
1834       getNextToken();
1835       statementList();
1836       if (token != TokenNameendforeach) {
1837         throwSyntaxError("'endforeach' expected.");
1838       }
1839       getNextToken();
1840       if (token != TokenNameSEMICOLON) {
1841         throwSyntaxError("';' expected after foreach-statement.");
1842       }
1843       getNextToken();
1844     } else {
1845       statement(TokenNameEOF);
1846     }
1847   }
1848   //  private void exitStatus() {
1849   //    if (token == TokenNameLPAREN) {
1850   //      getNextToken();
1851   //    } else {
1852   //      throwSyntaxError("'(' expected in 'exit-status'.");
1853   //    }
1854   //    if (token != TokenNameRPAREN) {
1855   //      expression();
1856   //    }
1857   //    if (token == TokenNameRPAREN) {
1858   //      getNextToken();
1859   //    } else {
1860   //      throwSyntaxError("')' expected after 'exit-status'.");
1861   //    }
1862   //  }
1863   private void expressionList() {
1864     do {
1865       expr();
1866       if (token == TokenNameCOMMA) {
1867         getNextToken();
1868       } else {
1869         break;
1870       }
1871     } while (true);
1872   }
1873   private void expr() {
1874     //  r_variable
1875     //  | expr_without_variable
1876     //    if (token!=TokenNameEOF) {
1877     if (Scanner.TRACE) {
1878       System.out.println("TRACE: expr()");
1879     }
1880     expr_without_variable(true);
1881     //    }
1882   }
1883   private void expr_without_variable(boolean only_variable) {
1884     //          internal_functions_in_yacc
1885     //  | T_CLONE expr
1886     //  | T_PRINT expr
1887     //  | '(' expr ')'
1888     //  | '@' expr
1889     //  | '+' expr
1890     //  | '-' expr
1891     //  | '!' expr
1892     //  | '~' expr
1893     //  | T_INC rw_variable
1894     //  | T_DEC rw_variable
1895     //  | T_INT_CAST expr
1896     //  | T_DOUBLE_CAST expr
1897     //  | T_STRING_CAST expr
1898     //  | T_ARRAY_CAST expr
1899     //  | T_OBJECT_CAST expr
1900     //  | T_BOOL_CAST expr
1901     //  | T_UNSET_CAST expr
1902     //  | T_EXIT exit_expr
1903     //  | scalar
1904     //  | T_ARRAY '(' array_pair_list ')'
1905     //  | '`' encaps_list '`'
1906     //  | T_LIST '(' assignment_list ')' '=' expr
1907     //  | T_NEW class_name_reference ctor_arguments
1908     //  | variable '=' expr
1909     //  | variable '=' '&' variable
1910     //  | variable '=' '&' T_NEW class_name_reference ctor_arguments
1911     //  | variable T_PLUS_EQUAL expr
1912     //  | variable T_MINUS_EQUAL expr
1913     //  | variable T_MUL_EQUAL expr
1914     //  | variable T_DIV_EQUAL expr
1915     //  | variable T_CONCAT_EQUAL expr
1916     //  | variable T_MOD_EQUAL expr
1917     //  | variable T_AND_EQUAL expr
1918     //  | variable T_OR_EQUAL expr
1919     //  | variable T_XOR_EQUAL expr
1920     //  | variable T_SL_EQUAL expr
1921     //  | variable T_SR_EQUAL expr
1922     //  | rw_variable T_INC
1923     //  | rw_variable T_DEC
1924     //  | expr T_BOOLEAN_OR expr
1925     //  | expr T_BOOLEAN_AND expr
1926     //  | expr T_LOGICAL_OR expr
1927     //  | expr T_LOGICAL_AND expr
1928     //  | expr T_LOGICAL_XOR expr
1929     //  | expr '|' expr
1930     //  | expr '&' expr
1931     //  | expr '^' expr
1932     //  | expr '.' expr
1933     //  | expr '+' expr
1934     //  | expr '-' expr
1935     //  | expr '*' expr
1936     //  | expr '/' expr
1937     //  | expr '%' expr
1938     //  | expr T_SL expr
1939     //  | expr T_SR expr
1940     //  | expr T_IS_IDENTICAL expr
1941     //  | expr T_IS_NOT_IDENTICAL expr
1942     //  | expr T_IS_EQUAL expr
1943     //  | expr T_IS_NOT_EQUAL expr
1944     //  | expr '<' expr
1945     //  | expr T_IS_SMALLER_OR_EQUAL expr
1946     //  | expr '>' expr
1947     //  | expr T_IS_GREATER_OR_EQUAL expr
1948     //  | expr T_INSTANCEOF class_name_reference
1949     //  | expr '?' expr ':' expr
1950     if (Scanner.TRACE) {
1951       System.out.println("TRACE: expr_without_variable() PART 1");
1952     }
1953     switch (token) {
1954       case TokenNameisset :
1955       case TokenNameempty :
1956       case TokenNameeval :
1957       case TokenNameinclude :
1958       case TokenNameinclude_once :
1959       case TokenNamerequire :
1960       case TokenNamerequire_once :
1961         internal_functions_in_yacc();
1962         break;
1963       //        | '(' expr ')'
1964       case TokenNameLPAREN :
1965         getNextToken();
1966         expr();
1967         if (token == TokenNameRPAREN) {
1968           getNextToken();
1969         } else {
1970           throwSyntaxError("')' expected in expression.");
1971         }
1972         break;
1973       //    | T_CLONE expr
1974       //    | T_PRINT expr
1975       //    | '@' expr
1976       //    | '+' expr
1977       //    | '-' expr
1978       //    | '!' expr
1979       //    | '~' expr
1980       //    | T_INT_CAST expr
1981       //        | T_DOUBLE_CAST expr
1982       //        | T_STRING_CAST expr
1983       //        | T_ARRAY_CAST expr
1984       //        | T_OBJECT_CAST expr
1985       //        | T_BOOL_CAST expr
1986       //        | T_UNSET_CAST expr
1987       case TokenNameclone :
1988       case TokenNameprint :
1989       case TokenNameAT :
1990       case TokenNamePLUS :
1991       case TokenNameMINUS :
1992       case TokenNameNOT :
1993       case TokenNameTWIDDLE :
1994       case TokenNameintCAST :
1995       case TokenNamedoubleCAST :
1996       case TokenNamestringCAST :
1997       case TokenNamearrayCAST :
1998       case TokenNameobjectCAST :
1999       case TokenNameboolCAST :
2000       case TokenNameunsetCAST :
2001         getNextToken();
2002         expr();
2003         break;
2004       case TokenNameexit :
2005         getNextToken();
2006         exit_expr();
2007         break;
2008       //  scalar:
2009       //        T_STRING
2010       //| T_STRING_VARNAME
2011       //| class_constant
2012       //| T_START_HEREDOC encaps_list T_END_HEREDOC
2013       //        | '`' encaps_list '`'
2014       //  | common_scalar
2015       //        | '`' encaps_list '`'
2016       case TokenNameEncapsedString0 :
2017         scanner.encapsedStringStack.push(new Character('`'));
2018         getNextToken();
2019         try {
2020           if (token == TokenNameEncapsedString0) {
2021           } else {
2022             encaps_list();
2023             if (token != TokenNameEncapsedString0) {
2024               throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2025             }
2026           }
2027         } finally {
2028           scanner.encapsedStringStack.pop();
2029           getNextToken();
2030         }
2031         break;
2032       //      | '\'' encaps_list '\''
2033       case TokenNameEncapsedString1 :
2034         scanner.encapsedStringStack.push(new Character('\''));
2035         getNextToken();
2036         try {
2037           if (token == TokenNameEncapsedString1) {
2038           } else {
2039             encaps_list();
2040             if (token != TokenNameEncapsedString1) {
2041               throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2042             }
2043           }
2044         } finally {
2045           scanner.encapsedStringStack.pop();
2046           getNextToken();
2047         }
2048         break;
2049       //| '"' encaps_list '"'
2050       case TokenNameEncapsedString2 :
2051         scanner.encapsedStringStack.push(new Character('"'));
2052         getNextToken();
2053         try {
2054           if (token == TokenNameEncapsedString2) {
2055           } else {
2056             encaps_list();
2057             if (token != TokenNameEncapsedString2) {
2058               throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2059             }
2060           }
2061         } finally {
2062           scanner.encapsedStringStack.pop();
2063           getNextToken();
2064         }
2065         break;
2066       case TokenNameIntegerLiteral :
2067       case TokenNameDoubleLiteral :
2068       case TokenNameStringDoubleQuote :
2069       case TokenNameStringSingleQuote :
2070       case TokenNameStringInterpolated :
2071       case TokenNameFILE :
2072       case TokenNameLINE :
2073       case TokenNameCLASS_C :
2074       case TokenNameMETHOD_C :
2075       case TokenNameFUNC_C :
2076         common_scalar();
2077         break;
2078       case TokenNameHEREDOC :
2079         getNextToken();
2080         break;
2081       case TokenNamearray :
2082         //    T_ARRAY '(' array_pair_list ')'
2083         getNextToken();
2084         if (token == TokenNameLPAREN) {
2085           getNextToken();
2086           if (token == TokenNameRPAREN) {
2087             getNextToken();
2088             break;
2089           }
2090           array_pair_list();
2091           if (token != TokenNameRPAREN) {
2092             throwSyntaxError("')' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2093           }
2094           getNextToken();
2095         } else {
2096           throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2097         }
2098         break;
2099       case TokenNamelist :
2100         //    | T_LIST '(' assignment_list ')' '=' expr
2101         getNextToken();
2102         if (token == TokenNameLPAREN) {
2103           getNextToken();
2104           assignment_list();
2105           if (token != TokenNameRPAREN) {
2106             throwSyntaxError("')' expected after 'list' keyword.");
2107           }
2108           getNextToken();
2109           if (token != TokenNameEQUAL) {
2110             throwSyntaxError("'=' expected after 'list' keyword.");
2111           }
2112           getNextToken();
2113           expr();
2114         } else {
2115           throwSyntaxError("'(' expected after 'list' keyword.");
2116         }
2117         break;
2118       case TokenNamenew :
2119         //      | T_NEW class_name_reference ctor_arguments
2120         getNextToken();
2121         class_name_reference();
2122         ctor_arguments();
2123         break;
2124       //        | T_INC rw_variable
2125       //        | T_DEC rw_variable
2126       case TokenNamePLUS_PLUS :
2127       case TokenNameMINUS_MINUS :
2128         getNextToken();
2129         rw_variable();
2130         break;
2131       //        | variable '=' expr
2132       //        | variable '=' '&' variable
2133       //        | variable '=' '&' T_NEW class_name_reference ctor_arguments
2134       //        | variable T_PLUS_EQUAL expr
2135       //        | variable T_MINUS_EQUAL expr
2136       //        | variable T_MUL_EQUAL expr
2137       //        | variable T_DIV_EQUAL expr
2138       //        | variable T_CONCAT_EQUAL expr
2139       //        | variable T_MOD_EQUAL expr
2140       //        | variable T_AND_EQUAL expr
2141       //        | variable T_OR_EQUAL expr
2142       //        | variable T_XOR_EQUAL expr
2143       //        | variable T_SL_EQUAL expr
2144       //        | variable T_SR_EQUAL expr
2145       //        | rw_variable T_INC
2146       //        | rw_variable T_DEC
2147       case TokenNameIdentifier :
2148       case TokenNameVariable :
2149       case TokenNameDOLLAR :
2150         variable();
2151         switch (token) {
2152           case TokenNameEQUAL :
2153             getNextToken();
2154             if (token == TokenNameAND) {
2155               getNextToken();
2156               if (token == TokenNamenew) {
2157                 // | variable '=' '&' T_NEW class_name_reference
2158                 // ctor_arguments
2159                 getNextToken();
2160                 class_name_reference();
2161                 ctor_arguments();
2162               } else {
2163                 variable();
2164               }
2165             } else {
2166               expr();
2167             }
2168             break;
2169           case TokenNamePLUS_EQUAL :
2170           case TokenNameMINUS_EQUAL :
2171           case TokenNameMULTIPLY_EQUAL :
2172           case TokenNameDIVIDE_EQUAL :
2173           case TokenNameDOT_EQUAL :
2174           case TokenNameREMAINDER_EQUAL :
2175           case TokenNameAND_EQUAL :
2176           case TokenNameOR_EQUAL :
2177           case TokenNameXOR_EQUAL :
2178           case TokenNameRIGHT_SHIFT_EQUAL :
2179           case TokenNameLEFT_SHIFT_EQUAL :
2180             getNextToken();
2181             expr();
2182             break;
2183           case TokenNamePLUS_PLUS :
2184           case TokenNameMINUS_MINUS :
2185             getNextToken();
2186             break;
2187           default :
2188             if (!only_variable) {
2189               throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "').");
2190             }
2191         }
2192         break;
2193       default :
2194         if (token != TokenNameINLINE_HTML) {
2195           if (token > TokenNameKEYWORD) {
2196             getNextToken();
2197             break;
2198           } else {
2199             throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
2200           }
2201         }
2202         return;
2203     }
2204     if (Scanner.TRACE) {
2205       System.out.println("TRACE: expr_without_variable() PART 2");
2206     }
2207     //  | expr T_BOOLEAN_OR expr
2208     //  | expr T_BOOLEAN_AND expr
2209     //  | expr T_LOGICAL_OR expr
2210     //  | expr T_LOGICAL_AND expr
2211     //  | expr T_LOGICAL_XOR expr
2212     //  | expr '|' expr
2213     //  | expr '&' expr
2214     //  | expr '^' expr
2215     //  | expr '.' expr
2216     //  | expr '+' expr
2217     //  | expr '-' expr
2218     //  | expr '*' expr
2219     //  | expr '/' expr
2220     //  | expr '%' expr
2221     //  | expr T_SL expr
2222     //  | expr T_SR expr
2223     //  | expr T_IS_IDENTICAL expr
2224     //  | expr T_IS_NOT_IDENTICAL expr
2225     //  | expr T_IS_EQUAL expr
2226     //  | expr T_IS_NOT_EQUAL expr
2227     //  | expr '<' expr
2228     //  | expr T_IS_SMALLER_OR_EQUAL expr
2229     //  | expr '>' expr
2230     //  | expr T_IS_GREATER_OR_EQUAL expr
2231     while (true) {
2232       switch (token) {
2233         case TokenNameOR_OR :
2234         case TokenNameAND_AND :
2235         case TokenNameand :
2236         case TokenNameor :
2237         case TokenNamexor :
2238         case TokenNameAND :
2239         case TokenNameOR :
2240         case TokenNameXOR :
2241         case TokenNameDOT :
2242         case TokenNamePLUS :
2243         case TokenNameMINUS :
2244         case TokenNameMULTIPLY :
2245         case TokenNameDIVIDE :
2246         case TokenNameREMAINDER :
2247         case TokenNameLEFT_SHIFT :
2248         case TokenNameRIGHT_SHIFT :
2249         case TokenNameEQUAL_EQUAL_EQUAL :
2250         case TokenNameNOT_EQUAL_EQUAL :
2251         case TokenNameEQUAL_EQUAL :
2252         case TokenNameNOT_EQUAL :
2253         case TokenNameLESS :
2254         case TokenNameLESS_EQUAL :
2255         case TokenNameGREATER :
2256         case TokenNameGREATER_EQUAL :
2257           getNextToken();
2258           expr();
2259           break;
2260         //  | expr T_INSTANCEOF class_name_reference
2261         //      | expr '?' expr ':' expr
2262         case TokenNameinstanceof :
2263           getNextToken();
2264           class_name_reference();
2265           break;
2266         case TokenNameQUESTION :
2267           getNextToken();
2268           expr();
2269           if (token == TokenNameCOLON) {
2270             getNextToken();
2271             expr();
2272           }
2273           break;
2274         default :
2275           return;
2276       }
2277     }
2278   }
2279   private void class_name_reference() {
2280     //  class_name_reference:
2281     //  T_STRING
2282     //| dynamic_class_name_reference
2283     if (Scanner.TRACE) {
2284       System.out.println("TRACE: class_name_reference()");
2285     }
2286     if (token == TokenNameIdentifier) {
2287       getNextToken();
2288     } else {
2289       dynamic_class_name_reference();
2290     }
2291   }
2292   private void dynamic_class_name_reference() {
2293     //dynamic_class_name_reference:
2294     //  base_variable T_OBJECT_OPERATOR object_property
2295     // dynamic_class_name_variable_properties
2296     //| base_variable
2297     if (Scanner.TRACE) {
2298       System.out.println("TRACE: dynamic_class_name_reference()");
2299     }
2300     base_variable();
2301     if (token == TokenNameMINUS_GREATER) {
2302       getNextToken();
2303       object_property();
2304       dynamic_class_name_variable_properties();
2305     }
2306   }
2307   private void dynamic_class_name_variable_properties() {
2308     //  dynamic_class_name_variable_properties:
2309     //                  dynamic_class_name_variable_properties
2310     // dynamic_class_name_variable_property
2311     //          | /* empty */
2312     if (Scanner.TRACE) {
2313       System.out.println("TRACE: dynamic_class_name_variable_properties()");
2314     }
2315     while (token == TokenNameMINUS_GREATER) {
2316       dynamic_class_name_variable_property();
2317     }
2318   }
2319   private void dynamic_class_name_variable_property() {
2320     //  dynamic_class_name_variable_property:
2321     //  T_OBJECT_OPERATOR object_property
2322     if (Scanner.TRACE) {
2323       System.out.println("TRACE: dynamic_class_name_variable_property()");
2324     }
2325     if (token == TokenNameMINUS_GREATER) {
2326       getNextToken();
2327       object_property();
2328     }
2329   }
2330   private void ctor_arguments() {
2331     //  ctor_arguments:
2332     //  /* empty */
2333     //| '(' function_call_parameter_list ')'
2334     if (token == TokenNameLPAREN) {
2335       getNextToken();
2336       if (token == TokenNameRPAREN) {
2337         getNextToken();
2338         return;
2339       }
2340       non_empty_function_call_parameter_list();
2341       if (token != TokenNameRPAREN) {
2342         throwSyntaxError("')' expected in ctor_arguments.");
2343       }
2344       getNextToken();
2345     }
2346   }
2347   private void assignment_list() {
2348     //  assignment_list:
2349     //  assignment_list ',' assignment_list_element
2350     //| assignment_list_element
2351     while (true) {
2352       assignment_list_element();
2353       if (token != TokenNameCOMMA) {
2354         break;
2355       }
2356       getNextToken();
2357     }
2358   }
2359   private void assignment_list_element() {
2360     //assignment_list_element:
2361     //  variable
2362     //| T_LIST '(' assignment_list ')'
2363     //| /* empty */
2364     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2365       variable();
2366     } else {
2367       if (token == TokenNamelist) {
2368         getNextToken();
2369         if (token == TokenNameLPAREN) {
2370           getNextToken();
2371           assignment_list();
2372           if (token != TokenNameRPAREN) {
2373             throwSyntaxError("')' expected after 'list' keyword.");
2374           }
2375           getNextToken();
2376         } else {
2377           throwSyntaxError("'(' expected after 'list' keyword.");
2378         }
2379       }
2380     }
2381   }
2382   private void array_pair_list() {
2383     //  array_pair_list:
2384     //  /* empty */
2385     //| non_empty_array_pair_list possible_comma
2386     non_empty_array_pair_list();
2387     if (token == TokenNameCOMMA) {
2388       getNextToken();
2389     }
2390   }
2391   private void non_empty_array_pair_list() {
2392     //non_empty_array_pair_list:
2393     //  non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2394     //| non_empty_array_pair_list ',' expr
2395     //| expr T_DOUBLE_ARROW expr
2396     //| expr
2397     //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2398     //| non_empty_array_pair_list ',' '&' w_variable
2399     //| expr T_DOUBLE_ARROW '&' w_variable
2400     //| '&' w_variable
2401     while (true) {
2402       if (token == TokenNameAND) {
2403         getNextToken();
2404         variable();
2405       } else {
2406         expr();
2407         if (token == TokenNameAND) {
2408           getNextToken();
2409           variable();
2410         } else if (token == TokenNameEQUAL_GREATER) {
2411           getNextToken();
2412           if (token == TokenNameAND) {
2413             getNextToken();
2414             variable();
2415           } else {
2416             expr();
2417           }
2418         }
2419       }
2420       if (token != TokenNameCOMMA) {
2421         return;
2422       }
2423       getNextToken();
2424       if (token == TokenNameRPAREN) {
2425         return;
2426       }
2427     }
2428   }
2429   //  private void variableList() {
2430   //    do {
2431   //      variable();
2432   //      if (token == TokenNameCOMMA) {
2433   //        getNextToken();
2434   //      } else {
2435   //        break;
2436   //      }
2437   //    } while (true);
2438   //  }
2439   private void variable_without_objects() {
2440     //  variable_without_objects:
2441     //                  reference_variable
2442     //          | simple_indirect_reference reference_variable
2443     if (Scanner.TRACE) {
2444       System.out.println("TRACE: variable_without_objects()");
2445     }
2446     while (token == TokenNameDOLLAR) {
2447       getNextToken();
2448     }
2449     reference_variable();
2450   }
2451   private void function_call() {
2452     //  function_call:
2453     //  T_STRING '(' function_call_parameter_list ')'
2454     //| class_constant '(' function_call_parameter_list ')'
2455     //| static_member '(' function_call_parameter_list ')'
2456     //| variable_without_objects '(' function_call_parameter_list ')'
2457     if (Scanner.TRACE) {
2458       System.out.println("TRACE: function_call()");
2459     }
2460     if (token == TokenNameIdentifier) {
2461       getNextToken();
2462       switch (token) {
2463         case TokenNamePAAMAYIM_NEKUDOTAYIM :
2464           // static member:
2465           getNextToken();
2466           if (token == TokenNameIdentifier) {
2467             // class _constant
2468             getNextToken();
2469           } else {
2470             //        static member:
2471             variable_without_objects();
2472           }
2473           break;
2474       }
2475     } else {
2476       variable_without_objects();
2477     }
2478     if (token != TokenNameLPAREN) {
2479       // TODO is this ok ?
2480       return;
2481       //      throwSyntaxError("'(' expected in function call.");
2482     }
2483     getNextToken();
2484     if (token == TokenNameRPAREN) {
2485       getNextToken();
2486       return;
2487     }
2488     non_empty_function_call_parameter_list();
2489     if (token != TokenNameRPAREN) {
2490       throwSyntaxError("')' expected in function call.");
2491     }
2492     getNextToken();
2493   }
2494   //  private void function_call_parameter_list() {
2495   //    function_call_parameter_list:
2496   //            non_empty_function_call_parameter_list { $$ = $1; }
2497   //    | /* empty */
2498   //  }
2499   private void non_empty_function_call_parameter_list() {
2500     //non_empty_function_call_parameter_list:
2501     //          expr_without_variable
2502     //  | variable
2503     //  | '&' w_variable
2504     //  | non_empty_function_call_parameter_list ',' expr_without_variable
2505     //  | non_empty_function_call_parameter_list ',' variable
2506     //  | non_empty_function_call_parameter_list ',' '&' w_variable
2507     if (Scanner.TRACE) {
2508       System.out.println("TRACE: non_empty_function_call_parameter_list()");
2509     }
2510     while (true) {
2511       if (token == TokenNameAND) {
2512         getNextToken();
2513         w_variable();
2514       } else {
2515         //        if (token == TokenNameIdentifier || token ==
2516         // TokenNameVariable
2517         //            || token == TokenNameDOLLAR) {
2518         //          variable();
2519         //        } else {
2520         expr_without_variable(true);
2521         //        }
2522       }
2523       if (token != TokenNameCOMMA) {
2524         break;
2525       }
2526       getNextToken();
2527     }
2528   }
2529   private void fully_qualified_class_name() {
2530     if (token == TokenNameIdentifier) {
2531       getNextToken();
2532     } else {
2533       throwSyntaxError("Class name expected.");
2534     }
2535   }
2536   private void static_member() {
2537     //  static_member:
2538     //  fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2539     // variable_without_objects
2540     if (Scanner.TRACE) {
2541       System.out.println("TRACE: static_member()");
2542     }
2543     fully_qualified_class_name();
2544     if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2545       throwSyntaxError("'::' expected after class name (static_member).");
2546     }
2547     getNextToken();
2548     variable_without_objects();
2549   }
2550   private void base_variable_with_function_calls() {
2551     //  base_variable_with_function_calls:
2552     //  base_variable
2553     //| function_call
2554     boolean functionCall = false;
2555     if (Scanner.TRACE) {
2556       System.out.println("TRACE: base_variable_with_function_calls()");
2557     }
2558     //    if (token == TokenNameIdentifier) {
2559     //      functionCall = true;
2560     //    } else if (token == TokenNameVariable) {
2561     //      int tempToken = token;
2562     //      int tempPosition = scanner.currentPosition;
2563     //      getNextToken();
2564     //      if (token == TokenNameLPAREN) {
2565     //        functionCall = true;
2566     //      }
2567     //      token = tempToken;
2568     //      scanner.currentPosition = tempPosition;
2569     //      scanner.phpMode = true;
2570     //    }
2571     //    if (functionCall) {
2572     function_call();
2573     //    } else {
2574     //      base_variable();
2575     //    }
2576   }
2577   private void base_variable() {
2578     //  base_variable:
2579     //                  reference_variable
2580     //          | simple_indirect_reference reference_variable
2581     //          | static_member
2582     if (Scanner.TRACE) {
2583       System.out.println("TRACE: base_variable()");
2584     }
2585     if (token == TokenNameIdentifier) {
2586       static_member();
2587     } else {
2588       while (token == TokenNameDOLLAR) {
2589         getNextToken();
2590       }
2591       reference_variable();
2592     }
2593   }
2594   //  private void simple_indirect_reference() {
2595   //    // simple_indirect_reference:
2596   //    // '$'
2597   //    //| simple_indirect_reference '$'
2598   //  }
2599   private void reference_variable() {
2600     //  reference_variable:
2601     //                  reference_variable '[' dim_offset ']'
2602     //          | reference_variable '{' expr '}'
2603     //          | compound_variable
2604     if (Scanner.TRACE) {
2605       System.out.println("TRACE: reference_variable()");
2606     }
2607     compound_variable();
2608     while (true) {
2609       if (token == TokenNameLBRACE) {
2610         getNextToken();
2611         expr();
2612         if (token != TokenNameRBRACE) {
2613           throwSyntaxError("'}' expected in reference variable.");
2614         }
2615         getNextToken();
2616       } else if (token == TokenNameLBRACKET) {
2617         getNextToken();
2618         if (token != TokenNameRBRACKET) {
2619           expr();
2620           //        dim_offset();
2621           if (token != TokenNameRBRACKET) {
2622             throwSyntaxError("']' expected in reference variable.");
2623           }
2624         }
2625         getNextToken();
2626       } else {
2627         break;
2628       }
2629     }
2630   }
2631   private void compound_variable() {
2632     //  compound_variable:
2633     //                  T_VARIABLE
2634     //          | '$' '{' expr '}'
2635     if (Scanner.TRACE) {
2636       System.out.println("TRACE: compound_variable()");
2637     }
2638     if (token == TokenNameVariable) {
2639       getNextToken();
2640     } else {
2641       // because of simple_indirect_reference
2642       while (token == TokenNameDOLLAR) {
2643         getNextToken();
2644       }
2645       if (token != TokenNameLBRACE) {
2646         throwSyntaxError("'{' expected after compound variable token '$'.");
2647       }
2648       getNextToken();
2649       expr();
2650       if (token != TokenNameRBRACE) {
2651         throwSyntaxError("'}' expected after compound variable token '$'.");
2652       }
2653       getNextToken();
2654     }
2655   }
2656   //  private void dim_offset() {
2657   //    // dim_offset:
2658   //    // /* empty */
2659   //    // | expr
2660   //    expr();
2661   //  }
2662   private void object_property() {
2663     //  object_property:
2664     //  object_dim_list
2665     //| variable_without_objects
2666     if (Scanner.TRACE) {
2667       System.out.println("TRACE: object_property()");
2668     }
2669     if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2670       variable_without_objects();
2671     } else {
2672       object_dim_list();
2673     }
2674   }
2675   private void object_dim_list() {
2676     //object_dim_list:
2677     //  object_dim_list '[' dim_offset ']'
2678     //| object_dim_list '{' expr '}'
2679     //| variable_name
2680     if (Scanner.TRACE) {
2681       System.out.println("TRACE: object_dim_list()");
2682     }
2683     variable_name();
2684     while (true) {
2685       if (token == TokenNameLBRACE) {
2686         getNextToken();
2687         expr();
2688         if (token != TokenNameRBRACE) {
2689           throwSyntaxError("'}' expected in object_dim_list.");
2690         }
2691         getNextToken();
2692       } else if (token == TokenNameLBRACKET) {
2693         getNextToken();
2694         if (token == TokenNameRBRACKET) {
2695           getNextToken();
2696           continue;
2697         }
2698         expr();
2699         if (token != TokenNameRBRACKET) {
2700           throwSyntaxError("']' expected in object_dim_list.");
2701         }
2702         getNextToken();
2703       } else {
2704         break;
2705       }
2706     }
2707   }
2708   private void variable_name() {
2709     //variable_name:
2710     //  T_STRING
2711     //| '{' expr '}'
2712     if (Scanner.TRACE) {
2713       System.out.println("TRACE: variable_name()");
2714     }
2715     if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
2716       if (token > TokenNameKEYWORD) {
2717         // TODO show a warning "Keyword used as variable" ?
2718       }
2719       getNextToken();
2720     } else {
2721       if (token != TokenNameLBRACE) {
2722         throwSyntaxError("'{' expected in variable name.");
2723       }
2724       getNextToken();
2725       expr();
2726       if (token != TokenNameRBRACE) {
2727         throwSyntaxError("'}' expected in variable name.");
2728       }
2729       getNextToken();
2730     }
2731   }
2732   private void r_variable() {
2733     variable();
2734   }
2735   private void w_variable() {
2736     variable();
2737   }
2738   private void rw_variable() {
2739     variable();
2740   }
2741   private void variable() {
2742     //    variable:
2743     //          base_variable_with_function_calls T_OBJECT_OPERATOR
2744     //                  object_property method_or_not variable_properties
2745     //  | base_variable_with_function_calls
2746     base_variable_with_function_calls();
2747     if (token == TokenNameMINUS_GREATER) {
2748       getNextToken();
2749       object_property();
2750       method_or_not();
2751       variable_properties();
2752     }
2753     //    if (token == TokenNameDOLLAR_LBRACE) {
2754     //      getNextToken();
2755     //      expr();
2756     //      ;
2757     //      if (token != TokenNameRBRACE) {
2758     //        throwSyntaxError("'}' expected after indirect variable token '${'.");
2759     //      }
2760     //      getNextToken();
2761     //    } else {
2762     //      if (token == TokenNameVariable) {
2763     //        getNextToken();
2764     //        if (token == TokenNameLBRACKET) {
2765     //          getNextToken();
2766     //          expr();
2767     //          if (token != TokenNameRBRACKET) {
2768     //            throwSyntaxError("']' expected in variable-list.");
2769     //          }
2770     //          getNextToken();
2771     //        } else if (token == TokenNameEQUAL) {
2772     //          getNextToken();
2773     //          static_scalar();
2774     //        }
2775     //      } else {
2776     //        throwSyntaxError("$-variable expected in variable-list.");
2777     //      }
2778     //    }
2779   }
2780   private void variable_properties() {
2781     //  variable_properties:
2782     //                  variable_properties variable_property
2783     //          | /* empty */
2784     while (token == TokenNameMINUS_GREATER) {
2785       variable_property();
2786     }
2787   }
2788   private void variable_property() {
2789     //  variable_property:
2790     //                  T_OBJECT_OPERATOR object_property method_or_not
2791     if (Scanner.TRACE) {
2792       System.out.println("TRACE: variable_property()");
2793     }
2794     if (token == TokenNameMINUS_GREATER) {
2795       getNextToken();
2796       object_property();
2797       method_or_not();
2798     } else {
2799       throwSyntaxError("'->' expected in variable_property.");
2800     }
2801   }
2802   private void method_or_not() {
2803     //  method_or_not:
2804     //                  '(' function_call_parameter_list ')'
2805     //          | /* empty */
2806     if (Scanner.TRACE) {
2807       System.out.println("TRACE: method_or_not()");
2808     }
2809     if (token == TokenNameLPAREN) {
2810       getNextToken();
2811       if (token == TokenNameRPAREN) {
2812         getNextToken();
2813         return;
2814       }
2815       non_empty_function_call_parameter_list();
2816       if (token != TokenNameRPAREN) {
2817         throwSyntaxError("')' expected in method_or_not.");
2818       }
2819       getNextToken();
2820     }
2821   }
2822   private void exit_expr() {
2823     //  /* empty */
2824     //  | '(' ')'
2825     //  | '(' expr ')'
2826     if (token != TokenNameLPAREN) {
2827       return;
2828     }
2829     getNextToken();
2830     if (token == TokenNameRPAREN) {
2831       getNextToken();
2832       return;
2833     }
2834     expr();
2835     if (token != TokenNameRPAREN) {
2836       throwSyntaxError("')' expected after keyword 'exit'");
2837     }
2838     getNextToken();
2839   }
2840   private void encaps_list() {
2841     //                  encaps_list encaps_var
2842     //          | encaps_list T_STRING
2843     //          | encaps_list T_NUM_STRING
2844     //          | encaps_list T_ENCAPSED_AND_WHITESPACE
2845     //          | encaps_list T_CHARACTER
2846     //          | encaps_list T_BAD_CHARACTER
2847     //          | encaps_list '['
2848     //          | encaps_list ']'
2849     //          | encaps_list '{'
2850     //          | encaps_list '}'
2851     //          | encaps_list T_OBJECT_OPERATOR
2852     //          | /* empty */
2853     while (true) {
2854       switch (token) {
2855         case TokenNameSTRING :
2856           getNextToken();
2857           break;
2858         case TokenNameLBRACE :
2859           //          scanner.encapsedStringStack.pop();
2860           getNextToken();
2861           break;
2862         case TokenNameRBRACE :
2863           //          scanner.encapsedStringStack.pop();
2864           getNextToken();
2865           break;
2866         case TokenNameLBRACKET :
2867           //          scanner.encapsedStringStack.pop();
2868           getNextToken();
2869           break;
2870         case TokenNameRBRACKET :
2871           //          scanner.encapsedStringStack.pop();
2872           getNextToken();
2873           break;
2874         case TokenNameMINUS_GREATER :
2875           //          scanner.encapsedStringStack.pop();
2876           getNextToken();
2877           break;
2878         case TokenNameVariable :
2879         case TokenNameDOLLAR_LBRACE :
2880         case TokenNameCURLY_OPEN :
2881           encaps_var();
2882           break;
2883         //        case TokenNameDOLLAR :
2884         //          getNextToken();
2885         //          if (token == TokenNameLBRACE) {
2886         //            token = TokenNameDOLLAR_LBRACE;
2887         //            encaps_var();
2888         //          }
2889         //          break;
2890         default :
2891           char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
2892           if (encapsedChar == '$') {
2893             scanner.encapsedStringStack.pop();
2894             encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
2895             switch (encapsedChar) {
2896               case '`' :
2897                 if (token == TokenNameEncapsedString0) {
2898                   return;
2899                 }
2900                 token = TokenNameSTRING;
2901                 continue;
2902               case '\'' :
2903                 if (token == TokenNameEncapsedString1) {
2904                   return;
2905                 }
2906                 token = TokenNameSTRING;
2907                 continue;
2908               case '"' :
2909                 if (token == TokenNameEncapsedString2) {
2910                   return;
2911                 }
2912                 token = TokenNameSTRING;
2913                 continue;
2914             }
2915           }
2916           return;
2917       }
2918     }
2919   }
2920   private void encaps_var() {
2921     //                  T_VARIABLE
2922     //          | T_VARIABLE '[' encaps_var_offset ']'
2923     //          | T_VARIABLE T_OBJECT_OPERATOR T_STRING
2924     //          | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
2925     //          | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
2926     //          | T_CURLY_OPEN variable '}'
2927     switch (token) {
2928       case TokenNameVariable :
2929         getNextToken();
2930         if (token == TokenNameLBRACKET) {
2931           getNextToken();
2932           //          if (token == TokenNameRBRACKET) {
2933           //            getNextToken();
2934           //          } else {
2935           expr(); //encaps_var_offset();
2936           if (token != TokenNameRBRACKET) {
2937             throwSyntaxError("']' expected after variable.");
2938           }
2939           //          scanner.encapsedStringStack.pop();
2940           getNextToken();
2941           //          }
2942         } else if (token == TokenNameMINUS_GREATER) {
2943           getNextToken();
2944           if (token != TokenNameIdentifier) {
2945             throwSyntaxError("Identifier expected after '->'.");
2946           }
2947           //          scanner.encapsedStringStack.pop();
2948           getNextToken();
2949         }
2950         //        else {
2951         //          // scanner.encapsedStringStack.pop();
2952         //          int tempToken = TokenNameSTRING;
2953         //          if (!scanner.encapsedStringStack.isEmpty()
2954         //              && (token == TokenNameEncapsedString0
2955         //                  || token == TokenNameEncapsedString1
2956         //                  || token == TokenNameEncapsedString2 || token ==
2957         // TokenNameERROR)) {
2958         //            char encapsedChar = ((Character)
2959         // scanner.encapsedStringStack.peek())
2960         //                .charValue();
2961         //            switch (token) {
2962         //              case TokenNameEncapsedString0 :
2963         //                if (encapsedChar == '`') {
2964         //                  tempToken = TokenNameEncapsedString0;
2965         //                }
2966         //                break;
2967         //              case TokenNameEncapsedString1 :
2968         //                if (encapsedChar == '\'') {
2969         //                  tempToken = TokenNameEncapsedString1;
2970         //                }
2971         //                break;
2972         //              case TokenNameEncapsedString2 :
2973         //                if (encapsedChar == '"') {
2974         //                  tempToken = TokenNameEncapsedString2;
2975         //                }
2976         //                break;
2977         //              case TokenNameERROR :
2978         //                if (scanner.source[scanner.currentPosition - 1] == '\\') {
2979         //                  scanner.currentPosition--;
2980         //                  getNextToken();
2981         //                }
2982         //                break;
2983         //            }
2984         //          }
2985         //          token = tempToken;
2986         //        }
2987         break;
2988       case TokenNameDOLLAR_LBRACE :
2989         getNextToken();
2990         if (token == TokenNameIdentifier) {
2991           getNextToken();
2992           if (token == TokenNameLBRACKET) {
2993             getNextToken();
2994             //            if (token == TokenNameRBRACKET) {
2995             //              getNextToken();
2996             //            } else {
2997             expr();
2998             if (token != TokenNameRBRACKET) {
2999               throwSyntaxError("']' expected after '${'.");
3000             }
3001             getNextToken();
3002             //            }
3003           }
3004           if (token != TokenNameRBRACE) {
3005             throwSyntaxError("'}' expected after '${'.");
3006           }
3007           //          scanner.encapsedStringStack.pop();
3008           getNextToken();
3009         } else {
3010           expr();
3011           if (token != TokenNameRBRACE) {
3012             throwSyntaxError("'}' expected.");
3013           }
3014           //          scanner.encapsedStringStack.pop();
3015           getNextToken();
3016         }
3017         break;
3018       case TokenNameCURLY_OPEN :
3019         getNextToken();
3020         if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3021           getNextToken();
3022           if (token == TokenNameLBRACKET) {
3023             getNextToken();
3024             //            if (token == TokenNameRBRACKET) {
3025             //              getNextToken();
3026             //            } else {
3027             expr();
3028             if (token != TokenNameRBRACKET) {
3029               throwSyntaxError("']' expected after '{$'.");
3030             }
3031             getNextToken();
3032             //            }
3033           } else if (token == TokenNameMINUS_GREATER) {
3034             getNextToken();
3035             if (token != TokenNameIdentifier) {
3036               throwSyntaxError("String token expected.");
3037             }
3038             getNextToken();
3039           }
3040           //          if (token != TokenNameRBRACE) {
3041           //            throwSyntaxError("'}' expected after '{$'.");
3042           //          }
3043           //          // scanner.encapsedStringStack.pop();
3044           //          getNextToken();
3045         } else {
3046           expr();
3047           if (token != TokenNameRBRACE) {
3048             throwSyntaxError("'}' expected.");
3049           }
3050           //          scanner.encapsedStringStack.pop();
3051           getNextToken();
3052         }
3053         break;
3054     }
3055   }
3056   private void encaps_var_offset() {
3057     //                  T_STRING
3058     //          | T_NUM_STRING
3059     //          | T_VARIABLE
3060     switch (token) {
3061       case TokenNameSTRING :
3062         getNextToken();
3063         break;
3064       case TokenNameIntegerLiteral :
3065         getNextToken();
3066         break;
3067       case TokenNameVariable :
3068         getNextToken();
3069         break;
3070       case TokenNameIdentifier :
3071         getNextToken();
3072         break;
3073       default :
3074         throwSyntaxError("Variable or String token expected.");
3075         break;
3076     }
3077   }
3078   private void internal_functions_in_yacc() {
3079     int start = 0;
3080     ImportReference impt = null;
3081     switch (token) {
3082       case TokenNameisset :
3083         //      T_ISSET '(' isset_variables ')'
3084         getNextToken();
3085         if (token != TokenNameLPAREN) {
3086           throwSyntaxError("'(' expected after keyword 'isset'");
3087         }
3088         getNextToken();
3089         isset_variables();
3090         if (token != TokenNameRPAREN) {
3091           throwSyntaxError("')' expected after keyword 'isset'");
3092         }
3093         getNextToken();
3094         break;
3095       case TokenNameempty :
3096         //      T_EMPTY '(' variable ')'
3097         getNextToken();
3098         if (token != TokenNameLPAREN) {
3099           throwSyntaxError("'(' expected after keyword 'empty'");
3100         }
3101         getNextToken();
3102         variable();
3103         if (token != TokenNameRPAREN) {
3104           throwSyntaxError("')' expected after keyword 'empty'");
3105         }
3106         getNextToken();
3107         break;
3108       case TokenNameinclude :
3109         //T_INCLUDE expr
3110         start = scanner.getCurrentTokenStartPosition();
3111         getNextToken();
3112         expr();
3113
3114         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3115         impt.declarationSourceEnd = impt.sourceEnd;
3116         impt.declarationEnd = impt.declarationSourceEnd;
3117         //endPosition is just before the ;
3118         impt.declarationSourceStart = start;
3119         includesList.add(impt);
3120         break;
3121       case TokenNameinclude_once :
3122         //      T_INCLUDE_ONCE expr
3123         start = scanner.getCurrentTokenStartPosition();
3124         getNextToken();
3125         expr();
3126         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3127         impt.declarationSourceEnd = impt.sourceEnd;
3128         impt.declarationEnd = impt.declarationSourceEnd;
3129         //endPosition is just before the ;
3130         impt.declarationSourceStart = start;
3131         includesList.add(impt);
3132         break;
3133       case TokenNameeval :
3134         //      T_EVAL '(' expr ')'
3135         getNextToken();
3136         if (token != TokenNameLPAREN) {
3137           throwSyntaxError("'(' expected after keyword 'eval'");
3138         }
3139         getNextToken();
3140         expr();
3141         if (token != TokenNameRPAREN) {
3142           throwSyntaxError("')' expected after keyword 'eval'");
3143         }
3144         getNextToken();
3145         break;
3146       case TokenNamerequire :
3147         //T_REQUIRE expr
3148         start = scanner.getCurrentTokenStartPosition();
3149         getNextToken();
3150         expr();
3151         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3152         impt.declarationSourceEnd = impt.sourceEnd;
3153         impt.declarationEnd = impt.declarationSourceEnd;
3154         //endPosition is just before the ;
3155         impt.declarationSourceStart = start;
3156         includesList.add(impt);
3157         break;
3158       case TokenNamerequire_once :
3159         //      T_REQUIRE_ONCE expr
3160         start = scanner.getCurrentTokenStartPosition();
3161         getNextToken();
3162         expr();
3163         impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3164         impt.declarationSourceEnd = impt.sourceEnd;
3165         impt.declarationEnd = impt.declarationSourceEnd;
3166         //endPosition is just before the ;
3167         impt.declarationSourceStart = start;
3168         includesList.add(impt);
3169         break;
3170     }
3171   }
3172   private void isset_variables() {
3173     //  variable
3174     //  | isset_variables ','
3175     if (token == TokenNameRPAREN) {
3176       throwSyntaxError("Variable expected after keyword 'isset'");
3177     }
3178     while (true) {
3179       variable();
3180       if (token == TokenNameCOMMA) {
3181         getNextToken();
3182       } else {
3183         break;
3184       }
3185     }
3186   }
3187   private boolean common_scalar() {
3188     //  common_scalar:
3189     //  T_LNUMBER
3190     //  | T_DNUMBER
3191     //  | T_CONSTANT_ENCAPSED_STRING
3192     //  | T_LINE
3193     //  | T_FILE
3194     //  | T_CLASS_C
3195     //  | T_METHOD_C
3196     //  | T_FUNC_C
3197     switch (token) {
3198       case TokenNameIntegerLiteral :
3199         getNextToken();
3200         return true;
3201       case TokenNameDoubleLiteral :
3202         getNextToken();
3203         return true;
3204       case TokenNameStringDoubleQuote :
3205         getNextToken();
3206         return true;
3207       case TokenNameStringSingleQuote :
3208         getNextToken();
3209         return true;
3210       case TokenNameStringInterpolated :
3211         getNextToken();
3212         return true;
3213       case TokenNameFILE :
3214         getNextToken();
3215         return true;
3216       case TokenNameLINE :
3217         getNextToken();
3218         return true;
3219       case TokenNameCLASS_C :
3220         getNextToken();
3221         return true;
3222       case TokenNameMETHOD_C :
3223         getNextToken();
3224         return true;
3225       case TokenNameFUNC_C :
3226         getNextToken();
3227         return true;
3228     }
3229     return false;
3230   }
3231   private void scalar() {
3232     //  scalar:
3233     //  T_STRING
3234     //| T_STRING_VARNAME
3235     //| class_constant
3236     //| common_scalar
3237     //| '"' encaps_list '"'
3238     //| '\'' encaps_list '\''
3239     //| T_START_HEREDOC encaps_list T_END_HEREDOC
3240     throwSyntaxError("Not yet implemented (scalar).");
3241   }
3242   private void static_scalar() {
3243     //    static_scalar: /* compile-time evaluated scalars */
3244     //          common_scalar
3245     //  | T_STRING
3246     //  | '+' static_scalar
3247     //  | '-' static_scalar
3248     //  | T_ARRAY '(' static_array_pair_list ')'
3249     //  | static_class_constant
3250     if (common_scalar()) {
3251       return;
3252     }
3253     switch (token) {
3254       case TokenNameIdentifier :
3255         getNextToken();
3256         //        static_class_constant:
3257         //              T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3258         if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3259           getNextToken();
3260           if (token == TokenNameIdentifier) {
3261             getNextToken();
3262           } else {
3263             throwSyntaxError("Identifier expected after '::' operator.");
3264           }
3265         }
3266         break;
3267       case TokenNameEncapsedString0 :
3268         try {
3269           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3270           while (scanner.currentCharacter != '`') {
3271             if (scanner.currentCharacter == '\\') {
3272               scanner.currentPosition++;
3273             }
3274             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3275           }
3276           getNextToken();
3277         } catch (IndexOutOfBoundsException e) {
3278           throwSyntaxError("'`' expected at end of static string.");
3279         }
3280         break;
3281       case TokenNameEncapsedString1 :
3282         try {
3283           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3284           while (scanner.currentCharacter != '\'') {
3285             if (scanner.currentCharacter == '\\') {
3286               scanner.currentPosition++;
3287             }
3288             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3289           }
3290           getNextToken();
3291         } catch (IndexOutOfBoundsException e) {
3292           throwSyntaxError("'\'' expected at end of static string.");
3293         }
3294         break;
3295       case TokenNameEncapsedString2 :
3296         try {
3297           scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3298           while (scanner.currentCharacter != '"') {
3299             if (scanner.currentCharacter == '\\') {
3300               scanner.currentPosition++;
3301             }
3302             scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3303           }
3304           getNextToken();
3305         } catch (IndexOutOfBoundsException e) {
3306           throwSyntaxError("'\"' expected at end of static string.");
3307         }
3308         break;
3309       case TokenNamePLUS :
3310         getNextToken();
3311         static_scalar();
3312         break;
3313       case TokenNameMINUS :
3314         getNextToken();
3315         static_scalar();
3316         break;
3317       case TokenNamearray :
3318         getNextToken();
3319         if (token != TokenNameLPAREN) {
3320           throwSyntaxError("'(' expected after keyword 'array'");
3321         }
3322         getNextToken();
3323         if (token == TokenNameRPAREN) {
3324           getNextToken();
3325           break;
3326         }
3327         non_empty_static_array_pair_list();
3328         if (token != TokenNameRPAREN) {
3329           throwSyntaxError("')' expected after keyword 'array'");
3330         }
3331         getNextToken();
3332         break;
3333       //      case TokenNamenull :
3334       //        getNextToken();
3335       //        break;
3336       //      case TokenNamefalse :
3337       //        getNextToken();
3338       //        break;
3339       //      case TokenNametrue :
3340       //        getNextToken();
3341       //        break;
3342       default :
3343         throwSyntaxError("Static scalar/constant expected.");
3344     }
3345   }
3346   private void non_empty_static_array_pair_list() {
3347     //  non_empty_static_array_pair_list:
3348     //  non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3349     // static_scalar
3350     //| non_empty_static_array_pair_list ',' static_scalar
3351     //| static_scalar T_DOUBLE_ARROW static_scalar
3352     //| static_scalar
3353     while (true) {
3354       static_scalar();
3355       if (token == TokenNameEQUAL_GREATER) {
3356         getNextToken();
3357         static_scalar();
3358       }
3359       if (token != TokenNameCOMMA) {
3360         break;
3361       }
3362       getNextToken();
3363       if (token == TokenNameRPAREN) {
3364         break;
3365       }
3366     }
3367   }
3368   public void reportSyntaxError() { //int act, int currentKind, int
3369     // stateStackTop) {
3370     /* remember current scanner position */
3371     int startPos = scanner.startPosition;
3372     int currentPos = scanner.currentPosition;
3373     //          String[] expectings;
3374     //          String tokenName = name[symbol_index[currentKind]];
3375     //fetch all "accurate" possible terminals that could recover the error
3376     //          int start, end = start = asi(stack[stateStackTop]);
3377     //          while (asr[end] != 0)
3378     //                  end++;
3379     //          int length = end - start;
3380     //          expectings = new String[length];
3381     //          if (length != 0) {
3382     //                  char[] indexes = new char[length];
3383     //                  System.arraycopy(asr, start, indexes, 0, length);
3384     //                  for (int i = 0; i < length; i++) {
3385     //                          expectings[i] = name[symbol_index[indexes[i]]];
3386     //                  }
3387     //          }
3388     //if the pb is an EOF, try to tell the user that they are some
3389     //          if (tokenName.equals(UNEXPECTED_EOF)) {
3390     //                  if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3391     //                          char[] tokenSource;
3392     //                          try {
3393     //                                  tokenSource = this.scanner.getCurrentTokenSource();
3394     //                          } catch (Exception e) {
3395     //                                  tokenSource = new char[] {};
3396     //                          }
3397     //                          problemReporter().parseError(
3398     //                                  this.scanner.startPosition,
3399     //                                  this.scanner.currentPosition - 1,
3400     //                                  tokenSource,
3401     //                                  tokenName,
3402     //                                  expectings);
3403     //                  }
3404     //          } else { //the next test is HEAVILY grammar DEPENDENT.
3405     //                  if ((length == 14)
3406     //                          && (expectings[0] == "=") //$NON-NLS-1$
3407     //                          && (expectings[1] == "*=") //$NON-NLS-1$
3408     //                          && (expressionPtr > -1)) {
3409     //                                  switch(currentKind) {
3410     //                                          case TokenNameSEMICOLON:
3411     //                                          case TokenNamePLUS:
3412     //                                          case TokenNameMINUS:
3413     //                                          case TokenNameDIVIDE:
3414     //                                          case TokenNameREMAINDER:
3415     //                                          case TokenNameMULTIPLY:
3416     //                                          case TokenNameLEFT_SHIFT:
3417     //                                          case TokenNameRIGHT_SHIFT:
3418     //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3419     //                                          case TokenNameLESS:
3420     //                                          case TokenNameGREATER:
3421     //                                          case TokenNameLESS_EQUAL:
3422     //                                          case TokenNameGREATER_EQUAL:
3423     //                                          case TokenNameEQUAL_EQUAL:
3424     //                                          case TokenNameNOT_EQUAL:
3425     //                                          case TokenNameXOR:
3426     //                                          case TokenNameAND:
3427     //                                          case TokenNameOR:
3428     //                                          case TokenNameOR_OR:
3429     //                                          case TokenNameAND_AND:
3430     //                                                  // the ; is not the expected token ==> it ends a statement when an
3431     // expression is not ended
3432     //                                                  problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3433     //                                                  break;
3434     //                                          case TokenNameRBRACE :
3435     //                                                  problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3436     //                                                  break;
3437     //                                          default:
3438     //                                                  char[] tokenSource;
3439     //                                                  try {
3440     //                                                          tokenSource = this.scanner.getCurrentTokenSource();
3441     //                                                  } catch (Exception e) {
3442     //                                                          tokenSource = new char[] {};
3443     //                                                  }
3444     //                                                  problemReporter().parseError(
3445     //                                                          this.scanner.startPosition,
3446     //                                                          this.scanner.currentPosition - 1,
3447     //                                                          tokenSource,
3448     //                                                          tokenName,
3449     //                                                          expectings);
3450     //                                                  this.checkAndReportBracketAnomalies(problemReporter());
3451     //                                  }
3452     //                  } else {
3453     char[] tokenSource;
3454     try {
3455       tokenSource = this.scanner.getCurrentTokenSource();
3456     } catch (Exception e) {
3457       tokenSource = new char[]{};
3458     }
3459     //                          problemReporter().parseError(
3460     //                                  this.scanner.startPosition,
3461     //                                  this.scanner.currentPosition - 1,
3462     //                                  tokenSource,
3463     //                                  tokenName,
3464     //                                  expectings);
3465     this.checkAndReportBracketAnomalies(problemReporter());
3466     //                  }
3467     //          }
3468     /* reset scanner where it was */
3469     scanner.startPosition = startPos;
3470     scanner.currentPosition = currentPos;
3471   }
3472   public static final int RoundBracket = 0;
3473   public static final int SquareBracket = 1;
3474   public static final int CurlyBracket = 2;
3475   public static final int BracketKinds = 3;
3476   protected int[] nestedMethod; //the ptr is nestedType
3477   protected int nestedType, dimensions;
3478   //ast stack
3479   final static int AstStackIncrement = 100;
3480   protected int astPtr;
3481   protected AstNode[] astStack = new AstNode[AstStackIncrement];
3482   protected int astLengthPtr;
3483   protected int[] astLengthStack;
3484   AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3485   public CompilationUnitDeclaration compilationUnit; /*
3486                                                       * the result from parse()
3487                                                       */
3488   protected ReferenceContext referenceContext;
3489   protected ProblemReporter problemReporter;
3490   protected CompilerOptions options;
3491   private ArrayList includesList;
3492   //  protected CompilationResult compilationResult;
3493   /**
3494    * Returns this parser's problem reporter initialized with its reference
3495    * context. Also it is assumed that a problem is going to be reported, so
3496    * initializes the compilation result's line positions.
3497    */
3498   public ProblemReporter problemReporter() {
3499     if (scanner.recordLineSeparator) {
3500       compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
3501     }
3502     problemReporter.referenceContext = referenceContext;
3503     return problemReporter;
3504   }
3505   /*
3506    * Reconsider the entire source looking for inconsistencies in {} () []
3507    */
3508   public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3509     scanner.wasAcr = false;
3510     boolean anomaliesDetected = false;
3511     try {
3512       char[] source = scanner.source;
3513       int[] leftCount = {0, 0, 0};
3514       int[] rightCount = {0, 0, 0};
3515       int[] depths = {0, 0, 0};
3516       int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3517       int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3518       int[][] rightPositions = new int[][]{new int[10], new int[10], new int[10]};
3519       int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3520       scanner.currentPosition = scanner.initialPosition; //starting
3521       // point
3522       // (first-zero-based
3523       // char)
3524       while (scanner.currentPosition < scanner.eofPosition) { //loop for
3525         // jumping
3526         // over
3527         // comments
3528         try {
3529           // ---------Consume white space and handles
3530           // startPosition---------
3531           boolean isWhiteSpace;
3532           do {
3533             scanner.startPosition = scanner.currentPosition;
3534             //                                          if (((scanner.currentCharacter =
3535             // source[scanner.currentPosition++]) == '\\') &&
3536             // (source[scanner.currentPosition] == 'u')) {
3537             //                                                  isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3538             //                                          } else {
3539             if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3540               if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3541                 // only record line positions we have not
3542                 // recorded yet
3543                 scanner.pushLineSeparator();
3544               }
3545             }
3546             isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3547             //                                          }
3548           } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
3549           // -------consume token until } is found---------
3550           switch (scanner.currentCharacter) {
3551             case '{' : {
3552               int index = leftCount[CurlyBracket]++;
3553               if (index == leftPositions[CurlyBracket].length) {
3554                 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
3555                 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
3556               }
3557               leftPositions[CurlyBracket][index] = scanner.startPosition;
3558               leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3559             }
3560               break;
3561             case '}' : {
3562               int index = rightCount[CurlyBracket]++;
3563               if (index == rightPositions[CurlyBracket].length) {
3564                 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
3565                 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
3566               }
3567               rightPositions[CurlyBracket][index] = scanner.startPosition;
3568               rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3569             }
3570               break;
3571             case '(' : {
3572               int index = leftCount[RoundBracket]++;
3573               if (index == leftPositions[RoundBracket].length) {
3574                 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
3575                 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
3576               }
3577               leftPositions[RoundBracket][index] = scanner.startPosition;
3578               leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3579             }
3580               break;
3581             case ')' : {
3582               int index = rightCount[RoundBracket]++;
3583               if (index == rightPositions[RoundBracket].length) {
3584                 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
3585                 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
3586               }
3587               rightPositions[RoundBracket][index] = scanner.startPosition;
3588               rightDepths[RoundBracket][index] = --depths[RoundBracket];
3589             }
3590               break;
3591             case '[' : {
3592               int index = leftCount[SquareBracket]++;
3593               if (index == leftPositions[SquareBracket].length) {
3594                 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
3595                 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
3596               }
3597               leftPositions[SquareBracket][index] = scanner.startPosition;
3598               leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3599             }
3600               break;
3601             case ']' : {
3602               int index = rightCount[SquareBracket]++;
3603               if (index == rightPositions[SquareBracket].length) {
3604                 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
3605                 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
3606               }
3607               rightPositions[SquareBracket][index] = scanner.startPosition;
3608               rightDepths[SquareBracket][index] = --depths[SquareBracket];
3609             }
3610               break;
3611             case '\'' : {
3612               if (scanner.getNextChar('\\')) {
3613                 scanner.scanEscapeCharacter();
3614               } else { // consume next character
3615                 scanner.unicodeAsBackSlash = false;
3616                 //                                                                      if (((scanner.currentCharacter =
3617                 // source[scanner.currentPosition++]) ==
3618                 // '\\') &&
3619                 // (source[scanner.currentPosition] ==
3620                 // 'u')) {
3621                 //                                                                              scanner.getNextUnicodeChar();
3622                 //                                                                      } else {
3623                 if (scanner.withoutUnicodePtr != 0) {
3624                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3625                 }
3626                 //                                                                      }
3627               }
3628               scanner.getNextChar('\'');
3629               break;
3630             }
3631             case '"' :
3632               // consume next character
3633               scanner.unicodeAsBackSlash = false;
3634               //                                                        if (((scanner.currentCharacter =
3635               // source[scanner.currentPosition++]) == '\\') &&
3636               // (source[scanner.currentPosition] == 'u')) {
3637               //                                                                scanner.getNextUnicodeChar();
3638               //                                                        } else {
3639               if (scanner.withoutUnicodePtr != 0) {
3640                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3641               }
3642               //                                                        }
3643               while (scanner.currentCharacter != '"') {
3644                 if (scanner.currentCharacter == '\r') {
3645                   if (source[scanner.currentPosition] == '\n')
3646                     scanner.currentPosition++;
3647                   break; // the string cannot go further that
3648                   // the line
3649                 }
3650                 if (scanner.currentCharacter == '\n') {
3651                   break; // the string cannot go further that
3652                   // the line
3653                 }
3654                 if (scanner.currentCharacter == '\\') {
3655                   scanner.scanEscapeCharacter();
3656                 }
3657                 // consume next character
3658                 scanner.unicodeAsBackSlash = false;
3659                 //                                                              if (((scanner.currentCharacter =
3660                 // source[scanner.currentPosition++]) == '\\')
3661                 // && (source[scanner.currentPosition] == 'u'))
3662                 // {
3663                 //                                                                      scanner.getNextUnicodeChar();
3664                 //                                                              } else {
3665                 if (scanner.withoutUnicodePtr != 0) {
3666                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3667                 }
3668                 //                                                              }
3669               }
3670               break;
3671             case '/' : {
3672               int test;
3673               if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3674                 // comment
3675                 //get the next char
3676                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3677                     && (source[scanner.currentPosition] == 'u')) {
3678                   //-------------unicode traitement
3679                   // ------------
3680                   int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3681                   scanner.currentPosition++;
3682                   while (source[scanner.currentPosition] == 'u') {
3683                     scanner.currentPosition++;
3684                   }
3685                   if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3686                       || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3687                       || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3688                       || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3689                                                                                                                // don't
3690                     // care of the
3691                     // value
3692                     scanner.currentCharacter = 'A';
3693                   } //something different from \n and \r
3694                   else {
3695                     scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3696                   }
3697                 }
3698                 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
3699                   //get the next char
3700                   scanner.startPosition = scanner.currentPosition;
3701                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3702                       && (source[scanner.currentPosition] == 'u')) {
3703                     //-------------unicode traitement
3704                     // ------------
3705                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3706                     scanner.currentPosition++;
3707                     while (source[scanner.currentPosition] == 'u') {
3708                       scanner.currentPosition++;
3709                     }
3710                     if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3711                         || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3712                         || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3713                         || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3714                                                                                                                  // don't
3715                       // care of the
3716                       // value
3717                       scanner.currentCharacter = 'A';
3718                     } //something different from \n
3719                     // and \r
3720                     else {
3721                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3722                     }
3723                   }
3724                 }
3725                 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3726                   if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3727                     // only record line positions we
3728                     // have not recorded yet
3729                     scanner.pushLineSeparator();
3730                     if (this.scanner.taskTags != null) {
3731                       this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner
3732                           .getCurrentTokenEndPosition());
3733                     }
3734                   }
3735                 }
3736                 break;
3737               }
3738               if (test > 0) { //traditional and annotation
3739                 // comment
3740                 boolean star = false;
3741                 // consume next character
3742                 scanner.unicodeAsBackSlash = false;
3743                 //                                                                      if (((scanner.currentCharacter =
3744                 // source[scanner.currentPosition++]) ==
3745                 // '\\') &&
3746                 // (source[scanner.currentPosition] ==
3747                 // 'u')) {
3748                 //                                                                              scanner.getNextUnicodeChar();
3749                 //                                                                      } else {
3750                 if (scanner.withoutUnicodePtr != 0) {
3751                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3752                 }
3753                 //                                                                      }
3754                 if (scanner.currentCharacter == '*') {
3755                   star = true;
3756                 }
3757                 //get the next char
3758                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3759                     && (source[scanner.currentPosition] == 'u')) {
3760                   //-------------unicode traitement
3761                   // ------------
3762                   int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3763                   scanner.currentPosition++;
3764                   while (source[scanner.currentPosition] == 'u') {
3765                     scanner.currentPosition++;
3766                   }
3767                   if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3768                       || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3769                       || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3770                       || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3771                                                                                                                // don't
3772                     // care of the
3773                     // value
3774                     scanner.currentCharacter = 'A';
3775                   } //something different from * and /
3776                   else {
3777                     scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3778                   }
3779                 }
3780                 //loop until end of comment */
3781                 while ((scanner.currentCharacter != '/') || (!star)) {
3782                   star = scanner.currentCharacter == '*';
3783                   //get next char
3784                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3785                       && (source[scanner.currentPosition] == 'u')) {
3786                     //-------------unicode traitement
3787                     // ------------
3788                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3789                     scanner.currentPosition++;
3790                     while (source[scanner.currentPosition] == 'u') {
3791                       scanner.currentPosition++;
3792                     }
3793                     if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3794                         || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3795                         || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3796                         || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3797                                                                                                                  // don't
3798                       // care of the
3799                       // value
3800                       scanner.currentCharacter = 'A';
3801                     } //something different from * and
3802                     // /
3803                     else {
3804                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3805                     }
3806                   }
3807                 }
3808                 if (this.scanner.taskTags != null) {
3809                   this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
3810                 }
3811                 break;
3812               }
3813               break;
3814             }
3815             default :
3816               if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3817                 scanner.scanIdentifierOrKeyword(false);
3818                 break;
3819               }
3820               if (Character.isDigit(scanner.currentCharacter)) {
3821                 scanner.scanNumber(false);
3822                 break;
3823               }
3824           }
3825           //-----------------end switch while
3826           // try--------------------
3827         } catch (IndexOutOfBoundsException e) {
3828           break; // read until EOF
3829         } catch (InvalidInputException e) {
3830           return false; // no clue
3831         }
3832       }
3833       if (scanner.recordLineSeparator) {
3834         //                              compilationUnit.compilationResult.lineSeparatorPositions =
3835         // scanner.getLineEnds();
3836       }
3837       // check placement anomalies against other kinds of brackets
3838       for (int kind = 0; kind < BracketKinds; kind++) {
3839         for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3840           int start = leftPositions[kind][leftIndex]; // deepest
3841           // first
3842           // find matching closing bracket
3843           int depth = leftDepths[kind][leftIndex];
3844           int end = -1;
3845           for (int i = 0; i < rightCount[kind]; i++) {
3846             int pos = rightPositions[kind][i];
3847             // want matching bracket further in source with same
3848             // depth
3849             if ((pos > start) && (depth == rightDepths[kind][i])) {
3850               end = pos;
3851               break;
3852             }
3853           }
3854           if (end < 0) { // did not find a good closing match
3855             problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
3856             return true;
3857           }
3858           // check if even number of opening/closing other brackets
3859           // in between this pair of brackets
3860           int balance = 0;
3861           for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3862             for (int i = 0; i < leftCount[otherKind]; i++) {
3863               int pos = leftPositions[otherKind][i];
3864               if ((pos > start) && (pos < end))
3865                 balance++;
3866             }
3867             for (int i = 0; i < rightCount[otherKind]; i++) {
3868               int pos = rightPositions[otherKind][i];
3869               if ((pos > start) && (pos < end))
3870                 balance--;
3871             }
3872             if (balance != 0) {
3873               problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket
3874               // anomaly
3875               return true;
3876             }
3877           }
3878         }
3879         // too many opening brackets ?
3880         for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3881           anomaliesDetected = true;
3882           problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext,
3883               compilationUnit.compilationResult);
3884         }
3885         // too many closing brackets ?
3886         for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3887           anomaliesDetected = true;
3888           problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
3889         }
3890         if (anomaliesDetected)
3891           return true;
3892       }
3893       return anomaliesDetected;
3894     } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
3895       return anomaliesDetected;
3896     } catch (NullPointerException e) { // jdk1.2.2 jit bug
3897       return anomaliesDetected;
3898     }
3899   }
3900   protected void pushOnAstLengthStack(int pos) {
3901     try {
3902       astLengthStack[++astLengthPtr] = pos;
3903     } catch (IndexOutOfBoundsException e) {
3904       int oldStackLength = astLengthStack.length;
3905       int[] oldPos = astLengthStack;
3906       astLengthStack = new int[oldStackLength + StackIncrement];
3907       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3908       astLengthStack[astLengthPtr] = pos;
3909     }
3910   }
3911   protected void pushOnAstStack(AstNode node) {
3912     /*
3913      * add a new obj on top of the ast stack
3914      */
3915     try {
3916       astStack[++astPtr] = node;
3917     } catch (IndexOutOfBoundsException e) {
3918       int oldStackLength = astStack.length;
3919       AstNode[] oldStack = astStack;
3920       astStack = new AstNode[oldStackLength + AstStackIncrement];
3921       System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
3922       astPtr = oldStackLength;
3923       astStack[astPtr] = node;
3924     }
3925     try {
3926       astLengthStack[++astLengthPtr] = 1;
3927     } catch (IndexOutOfBoundsException e) {
3928       int oldStackLength = astLengthStack.length;
3929       int[] oldPos = astLengthStack;
3930       astLengthStack = new int[oldStackLength + AstStackIncrement];
3931       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3932       astLengthStack[astLengthPtr] = 1;
3933     }
3934   }
3935
3936   protected void resetModifiers() {
3937     this.modifiers = AccDefault;
3938     this.modifiersSourceStart = -1; // <-- see comment into
3939     // modifiersFlag(int)
3940     this.scanner.commentPtr = -1;
3941   }
3942 }