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