7369a248fcf12a980720fead0daa8e25d7dbe7e7
[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 class body.");
1414       }
1415     } else {
1416       throwSyntaxError("'{' expected at start of class 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 == TokenNamepublic || 
1496         token == TokenNameprotected || 
1497         token == TokenNameprivate || 
1498         token == TokenNamestatic || 
1499         token == TokenNameabstract || 
1500         token == TokenNamefinal || 
1501         token == TokenNamefunction || 
1502         token == TokenNamevar);
1503   }
1504   private void class_statement() {
1505     //    class_statement:
1506     //          variable_modifiers class_variable_declaration ';'
1507     //  | class_constant_declaration ';'
1508     //  | method_modifiers T_FUNCTION is_reference T_STRING
1509     //    '(' parameter_list ')' method_body
1510     initializeModifiers();
1511     if (token == TokenNamevar) {
1512       checkAndSetModifiers(AccPublic);
1513       reportSyntaxError(
1514           "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected' modifier for field declarations.",
1515           scanner.getCurrentTokenStartPosition(), scanner
1516               .getCurrentTokenEndPosition());
1517       getNextToken();
1518       classProperty();
1519     } else {
1520       boolean hasModifiers = member_modifiers();
1521       if (token == TokenNamefunction) {
1522         if (!hasModifiers) {
1523           checkAndSetModifiers(AccPublic);
1524         }
1525         MethodDeclaration methodDecl = new MethodDeclaration(
1526             this.compilationUnit.compilationResult);
1527         methodDecl.declarationSourceStart = scanner
1528             .getCurrentTokenStartPosition();
1529         methodDecl.modifiers = this.modifiers;
1530         getNextToken();
1531         functionDefinition(methodDecl);
1532       } else {
1533         if (!hasModifiers) {
1534           throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1535         }
1536         classProperty();
1537       }
1538     }
1539     //    if (token == TokenNamefunction) {
1540     //      MethodDeclaration methodDecl = new MethodDeclaration(
1541     //          this.compilationUnit.compilationResult);
1542     //      methodDecl.declarationSourceStart = scanner
1543     //          .getCurrentTokenStartPosition();
1544     //      getNextToken();
1545     //      functionDefinition(methodDecl);
1546     //    } else if (token == TokenNamevar) {
1547     //      getNextToken();
1548     //      classProperty();
1549     //    } else {
1550     //      throwSyntaxError("'function' or 'var' expected.");
1551     //    }
1552   }
1553   //  private void variable_modifiers() {
1554   //    // variable_modifiers:
1555   //    // non_empty_member_modifiers
1556   //    //| T_VAR
1557   //    initializeModifiers();
1558   //    if (token == TokenNamevar) {
1559   //      checkAndSetModifiers(AccPublic);
1560   //      reportSyntaxError(
1561   //          "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected'
1562   // modifier for field declarations.",
1563   //          scanner.getCurrentTokenStartPosition(), scanner
1564   //              .getCurrentTokenEndPosition());
1565   //      getNextToken();
1566   //    } else {
1567   //      if (!member_modifiers()) {
1568   //        throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1569   // field declarations.");
1570   //      }
1571   //    }
1572   //  }
1573   //  private void method_modifiers() {
1574   //    //method_modifiers:
1575   //    // /* empty */
1576   //    //| non_empty_member_modifiers
1577   //    initializeModifiers();
1578   //    if (!member_modifiers()) {
1579   //      checkAndSetModifiers(AccPublic);
1580   //    }
1581   //  }
1582   private boolean member_modifiers() {
1583     //  T_PUBLIC
1584     //| T_PROTECTED
1585     //| T_PRIVATE
1586     //| T_STATIC
1587     //| T_ABSTRACT
1588     //| T_FINAL
1589     boolean foundToken = false;
1590     while (true) {
1591       if (token == TokenNamepublic) {
1592         checkAndSetModifiers(AccPublic);
1593         getNextToken();
1594         foundToken = true;
1595       } else if (token == TokenNameprotected) {
1596         checkAndSetModifiers(AccProtected);
1597         getNextToken();
1598         foundToken = true;
1599       } else if (token == TokenNameprivate) {
1600         checkAndSetModifiers(AccPrivate);
1601         getNextToken();
1602         foundToken = true;
1603       } else if (token == TokenNamestatic) {
1604         checkAndSetModifiers(AccStatic);
1605         getNextToken();
1606         foundToken = true;
1607       } else if (token == TokenNameabstract) {
1608         checkAndSetModifiers(AccAbstract);
1609         getNextToken();
1610         foundToken = true;
1611       } else if (token == TokenNamefinal) {
1612         checkAndSetModifiers(AccFinal);
1613         getNextToken();
1614         foundToken = true;
1615       } else {
1616         break;
1617       }
1618     }
1619     return foundToken;
1620   }
1621   private void classProperty() {
1622     //'var' variable ';'
1623     //'var' variable '=' constant ';'
1624     do {
1625       if (token == TokenNameVariable) {
1626         getNextToken();
1627         if (token == TokenNameEQUAL) {
1628           getNextToken();
1629           constant();
1630         }
1631       } else {
1632         if (token == TokenNamethis) {
1633           throwSyntaxError("Reserved word '$this' not allowed after keyword 'var'.");
1634         }
1635         throwSyntaxError("Variable expected after keyword 'var'.");
1636       }
1637       if (token != TokenNameCOMMA) {
1638         break;
1639       }
1640       getNextToken();
1641     } while (true);
1642     if (token == TokenNameSEMICOLON) {
1643       getNextToken();
1644     } else {
1645       throwSyntaxError("';' expected after variable declaration.");
1646     }
1647   }
1648   private void functionDefinition(MethodDeclaration methodDecl) {
1649     if (astPtr == 0) {
1650       compilationUnit.types.add(methodDecl);
1651     } else {
1652       AstNode node = astStack[astPtr];
1653       if (node instanceof TypeDeclaration) {
1654         TypeDeclaration typeDecl = ((TypeDeclaration) node);
1655         if (typeDecl.methods == null) {
1656           typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1657         } else {
1658           AbstractMethodDeclaration[] newMethods;
1659           System
1660               .arraycopy(
1661                   typeDecl.methods,
1662                   0,
1663                   newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1664                   1, typeDecl.methods.length);
1665           newMethods[0] = methodDecl;
1666           typeDecl.methods = newMethods;
1667         }
1668       }
1669     }
1670     functionDeclarator(methodDecl);
1671     functionBody(methodDecl);
1672   }
1673   private void functionDeclarator(MethodDeclaration methodDecl) {
1674     //identifier '(' [parameter-list] ')'
1675     if (token == TokenNameAND) {
1676       getNextToken();
1677     }
1678     if (token == TokenNameIdentifier) {
1679       methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1680       methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1681       methodDecl.selector = scanner.getCurrentIdentifierSource();
1682       getNextToken();
1683       if (token == TokenNameLPAREN) {
1684         getNextToken();
1685       } else {
1686         throwSyntaxError("'(' expected in function declaration.");
1687       }
1688       if (token != TokenNameRPAREN) {
1689         parameterList();
1690       }
1691       if (token != TokenNameRPAREN) {
1692         throwSyntaxError("')' expected in function declaration.");
1693       } else {
1694         methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1695         getNextToken();
1696       }
1697     } else {
1698       if (token > TokenNameKEYWORD) {
1699         throwSyntaxError("Don't use keyword for function declaration [" + token
1700             + "].");
1701       }
1702       throwSyntaxError("Function name expected after keyword 'function'.");
1703     }
1704   }
1705   //
1706   private void parameterList() {
1707     //parameter-declaration
1708     //parameter-list ',' parameter-declaration
1709     do {
1710       parameterDeclaration();
1711       if (token != TokenNameCOMMA) {
1712         break;
1713       }
1714       getNextToken();
1715     } while (true);
1716   }
1717   private void parameterDeclaration() {
1718     //variable
1719     //variable-reference
1720     if (token == TokenNameAND) {
1721       getNextToken();
1722       if (isVariable()) {
1723         getNextToken();
1724       } else {
1725         throwSyntaxError("Variable expected after reference operator '&'.");
1726       }
1727     }
1728     //variable '=' constant
1729     if (token == TokenNameVariable) {
1730       getNextToken();
1731       if (token == TokenNameEQUAL) {
1732         getNextToken();
1733         constant();
1734       }
1735       return;
1736     }
1737     if (token == TokenNamethis) {
1738       throwSyntaxError("Reserved word '$this' not allowed in parameter declaration.");
1739     }
1740   }
1741   private void labeledStatementList() {
1742     if (token != TokenNamecase && token != TokenNamedefault) {
1743       throwSyntaxError("'case' or 'default' expected.");
1744     }
1745     do {
1746       if (token == TokenNamecase) {
1747         getNextToken();
1748         expr(); //constant();
1749         if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1750           getNextToken();
1751           if (token == TokenNamecase || token == TokenNamedefault) { // empty
1752             // case
1753             // statement
1754             // ?
1755             continue;
1756           }
1757           statementList();
1758         }
1759         //        else if (token == TokenNameSEMICOLON) {
1760         //          setMarker(
1761         //            "':' expected after 'case' keyword (Found token: " +
1762         // scanner.toStringAction(token) + ")",
1763         //            scanner.getCurrentTokenStartPosition(),
1764         //            scanner.getCurrentTokenEndPosition(),
1765         //            INFO);
1766         //          getNextToken();
1767         //          if (token == TokenNamecase) { // empty case statement ?
1768         //            continue;
1769         //          }
1770         //          statementList();
1771         //        }
1772         else {
1773           throwSyntaxError("':' character after 'case' constant expected (Found token: "
1774               + scanner.toStringAction(token) + ")");
1775         }
1776       } else { // TokenNamedefault
1777         getNextToken();
1778         if (token == TokenNameCOLON) {
1779           getNextToken();
1780           statementList();
1781         } else {
1782           throwSyntaxError("':' character after 'default' expected.");
1783         }
1784       }
1785     } while (token == TokenNamecase || token == TokenNamedefault);
1786   }
1787   //  public void labeledStatement() {
1788   //    if (token == TokenNamecase) {
1789   //      getNextToken();
1790   //      constant();
1791   //      if (token == TokenNameDDOT) {
1792   //        getNextToken();
1793   //        statement();
1794   //      } else {
1795   //        throwSyntaxError("':' character after 'case' constant expected.");
1796   //      }
1797   //      return;
1798   //    } else if (token == TokenNamedefault) {
1799   //      getNextToken();
1800   //      if (token == TokenNameDDOT) {
1801   //        getNextToken();
1802   //        statement();
1803   //      } else {
1804   //        throwSyntaxError("':' character after 'default' expected.");
1805   //      }
1806   //      return;
1807   //    }
1808   //  }
1809   //  public void expressionStatement() {
1810   //  }
1811   //  private void inclusionStatement() {
1812   //  }
1813   //  public void compoundStatement() {
1814   //  }
1815   //  public void selectionStatement() {
1816   //  }
1817   //
1818   //  public void iterationStatement() {
1819   //  }
1820   //
1821   //  public void jumpStatement() {
1822   //  }
1823   //
1824   //  public void outputStatement() {
1825   //  }
1826   //
1827   //  public void scopeStatement() {
1828   //  }
1829   //
1830   //  public void flowStatement() {
1831   //  }
1832   //
1833   //  public void definitionStatement() {
1834   //  }
1835   private void ifStatement() {
1836     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1837     if (token == TokenNameCOLON) {
1838       getNextToken();
1839       if (token != TokenNameendif) {
1840         statementList();
1841         switch (token) {
1842           case TokenNameelse :
1843             getNextToken();
1844             if (token == TokenNameCOLON) {
1845               getNextToken();
1846               if (token != TokenNameendif) {
1847                 statementList();
1848               }
1849             } else {
1850               if (token == TokenNameif) { //'else if'
1851                 getNextToken();
1852                 elseifStatementList();
1853               } else {
1854                 throwSyntaxError("':' expected after 'else'.");
1855               }
1856             }
1857             break;
1858           case TokenNameelseif :
1859             getNextToken();
1860             elseifStatementList();
1861             break;
1862         }
1863       }
1864       if (token != TokenNameendif) {
1865         throwSyntaxError("'endif' expected.");
1866       }
1867       getNextToken();
1868       if (token != TokenNameSEMICOLON) {
1869         throwSyntaxError("';' expected after if-statement.");
1870       }
1871       getNextToken();
1872     } else {
1873       // statement [else-statement]
1874       statement(TokenNameEOF);
1875       if (token == TokenNameelseif) {
1876         getNextToken();
1877         if (token == TokenNameLPAREN) {
1878           getNextToken();
1879         } else {
1880           throwSyntaxError("'(' expected after 'elseif' keyword.");
1881         }
1882         expr();
1883         if (token == TokenNameRPAREN) {
1884           getNextToken();
1885         } else {
1886           throwSyntaxError("')' expected after 'elseif' condition.");
1887         }
1888         ifStatement();
1889       } else if (token == TokenNameelse) {
1890         getNextToken();
1891         statement(TokenNameEOF);
1892       }
1893     }
1894   }
1895   private void elseifStatementList() {
1896     do {
1897       elseifStatement();
1898       switch (token) {
1899         case TokenNameelse :
1900           getNextToken();
1901           if (token == TokenNameCOLON) {
1902             getNextToken();
1903             if (token != TokenNameendif) {
1904               statementList();
1905             }
1906             return;
1907           } else {
1908             if (token == TokenNameif) { //'else if'
1909               getNextToken();
1910             } else {
1911               throwSyntaxError("':' expected after 'else'.");
1912             }
1913           }
1914           break;
1915         case TokenNameelseif :
1916           getNextToken();
1917           break;
1918         default :
1919           return;
1920       }
1921     } while (true);
1922   }
1923   private void elseifStatement() {
1924     if (token == TokenNameLPAREN) {
1925       getNextToken();
1926       expr();
1927       if (token != TokenNameRPAREN) {
1928         throwSyntaxError("')' expected in else-if-statement.");
1929       }
1930       getNextToken();
1931       if (token != TokenNameCOLON) {
1932         throwSyntaxError("':' expected in else-if-statement.");
1933       }
1934       getNextToken();
1935       if (token != TokenNameendif) {
1936         statementList();
1937       }
1938     }
1939   }
1940   private void switchStatement() {
1941     if (token == TokenNameCOLON) {
1942       // ':' [labeled-statement-list] 'endswitch' ';'
1943       getNextToken();
1944       labeledStatementList();
1945       if (token != TokenNameendswitch) {
1946         throwSyntaxError("'endswitch' expected.");
1947       }
1948       getNextToken();
1949       if (token != TokenNameSEMICOLON) {
1950         throwSyntaxError("';' expected after switch-statement.");
1951       }
1952       getNextToken();
1953     } else {
1954       // '{' [labeled-statement-list] '}'
1955       if (token != TokenNameLBRACE) {
1956         throwSyntaxError("'{' expected in switch statement.");
1957       }
1958       getNextToken();
1959       if (token != TokenNameRBRACE) {
1960         labeledStatementList();
1961       }
1962       if (token != TokenNameRBRACE) {
1963         throwSyntaxError("'}' expected in switch statement.");
1964       }
1965       getNextToken();
1966     }
1967   }
1968   private void forStatement() {
1969     if (token == TokenNameCOLON) {
1970       getNextToken();
1971       statementList();
1972       if (token != TokenNameendfor) {
1973         throwSyntaxError("'endfor' expected.");
1974       }
1975       getNextToken();
1976       if (token != TokenNameSEMICOLON) {
1977         throwSyntaxError("';' expected after for-statement.");
1978       }
1979       getNextToken();
1980     } else {
1981       statement(TokenNameEOF);
1982     }
1983   }
1984   private void whileStatement() {
1985     // ':' statement-list 'endwhile' ';'
1986     if (token == TokenNameCOLON) {
1987       getNextToken();
1988       statementList();
1989       if (token != TokenNameendwhile) {
1990         throwSyntaxError("'endwhile' expected.");
1991       }
1992       getNextToken();
1993       if (token != TokenNameSEMICOLON) {
1994         throwSyntaxError("';' expected after while-statement.");
1995       }
1996       getNextToken();
1997     } else {
1998       statement(TokenNameEOF);
1999     }
2000   }
2001   private void foreachStatement() {
2002     if (token == TokenNameCOLON) {
2003       getNextToken();
2004       statementList();
2005       if (token != TokenNameendforeach) {
2006         throwSyntaxError("'endforeach' expected.");
2007       }
2008       getNextToken();
2009       if (token != TokenNameSEMICOLON) {
2010         throwSyntaxError("';' expected after foreach-statement.");
2011       }
2012       getNextToken();
2013     } else {
2014       statement(TokenNameEOF);
2015     }
2016   }
2017   //  private void exitStatus() {
2018   //    if (token == TokenNameLPAREN) {
2019   //      getNextToken();
2020   //    } else {
2021   //      throwSyntaxError("'(' expected in 'exit-status'.");
2022   //    }
2023   //    if (token != TokenNameRPAREN) {
2024   //      expression();
2025   //    }
2026   //    if (token == TokenNameRPAREN) {
2027   //      getNextToken();
2028   //    } else {
2029   //      throwSyntaxError("')' expected after 'exit-status'.");
2030   //    }
2031   //  }
2032   private void expressionList() {
2033     do {
2034       expr();
2035       if (token == TokenNameCOMMA) {
2036         getNextToken();
2037       } else {
2038         break;
2039       }
2040     } while (true);
2041   }
2042   private void expr() {
2043     //todo: find a better way to get the expression
2044     //    expression = new StringBuffer();
2045     //    for (int i = chIndx; i < str.length(); i++) {
2046     //      if (str.charAt(i) == ';') {
2047     //        break;
2048     //      }
2049     //      expression.append(str.charAt(i));
2050     //    }
2051     //    if (token == TokenNameSTRING_CONSTANT || token ==
2052     // TokenNameINTERPOLATED_STRING) {
2053     //      getNextToken();
2054     //    } else {
2055     logicalinclusiveorExpression();
2056     //      while (token != TokenNameSEMICOLON) {
2057     //        getNextToken();
2058     //      // }
2059     //    }
2060   }
2061   private void expr_without_variable() {
2062     //  String ident;
2063     char[] ident;
2064     boolean castFlag = false;
2065     boolean arrayFlag = false;
2066     switch (token) {
2067       case TokenNameisset :
2068       case TokenNameempty :
2069       case TokenNameeval :
2070       case TokenNameinclude :
2071       case TokenNameinclude_once :
2072       case TokenNamerequire :
2073       case TokenNamerequire_once :
2074         internal_functions_in_yacc();
2075         break;
2076       case TokenNamenew :
2077         getNextToken();
2078         expr();
2079         break;
2080       case TokenNamenull :
2081         getNextToken();
2082         break;
2083       case TokenNamefalse :
2084         getNextToken();
2085         break;
2086       case TokenNametrue :
2087         getNextToken();
2088         break;
2089       case TokenNameStringConstant :
2090         getNextToken();
2091         break;
2092       case TokenNameHEREDOC :
2093       case TokenNameStringInterpolated :
2094       case TokenNameStringLiteral :
2095         getNextToken();
2096         break;
2097       case TokenNameLPAREN :
2098         getNextToken();
2099         if (token == TokenNameIdentifier) {
2100           // check if identifier is a type:
2101           //    ident = identifier;
2102           ident = scanner.getCurrentIdentifierSource();
2103           String str = new String(ident).toLowerCase();
2104           for (int i = 0; i < PHP_TYPES.length; i++) {
2105             if (PHP_TYPES[i].equals(str)) {
2106               castFlag = true;
2107               if (PHP_TYPES[i].equals("array")) {
2108                 arrayFlag = true;
2109               }
2110               break;
2111             }
2112           }
2113         }
2114         if (castFlag) {
2115           getNextToken();
2116           if (arrayFlag && token == TokenNameLPAREN) {
2117             getNextToken();
2118             if (token == TokenNameRPAREN) {
2119               getNextToken();
2120             } else {
2121               expr();
2122               if (token != TokenNameRPAREN) {
2123                 throwSyntaxError(") expected after 'array('.");
2124               }
2125             }
2126           }
2127           if (token != TokenNameRPAREN) {
2128             throwSyntaxError(") expected after cast-type '" + str + "'.");
2129           }
2130           getNextToken();
2131           expr();
2132           break;
2133         } else {
2134           expr();
2135         }
2136         if (token != TokenNameRPAREN) {
2137           throwSyntaxError(") expected in postfix-expression.");
2138         }
2139         getNextToken();
2140         break;
2141       case TokenNameDoubleLiteral :
2142         getNextToken();
2143         break;
2144       case TokenNameIntegerLiteral :
2145         getNextToken();
2146         break;
2147       case TokenNameDOLLAR_LBRACE :
2148         getNextToken();
2149         expr();
2150         if (token != TokenNameRBRACE) {
2151           throwSyntaxError("'}' expected after indirect variable token '${'.");
2152         }
2153         getNextToken();
2154         break;
2155       case TokenNameVariable :
2156       case TokenNamethis :
2157         ident = scanner.getCurrentIdentifierSource();
2158         getNextToken();
2159         if (token == TokenNameLBRACE) {
2160           getNextToken();
2161           expr();
2162           if (token != TokenNameRBRACE) {
2163             throwSyntaxError("'}' expected after variable '"
2164                 + new String(ident) + "' in variable-expression.");
2165           }
2166           getNextToken();
2167         } else if (token == TokenNameLPAREN) {
2168           getNextToken();
2169           if (token != TokenNameRPAREN) {
2170             expressionList();
2171             if (token != TokenNameRPAREN) {
2172               throwSyntaxError("')' expected after variable '"
2173                   + new String(ident) + "' in postfix-expression.");
2174             }
2175           }
2176           getNextToken();
2177         }
2178         break;
2179       case TokenNameIdentifier :
2180         ident = scanner.getCurrentIdentifierSource();
2181         getNextToken();
2182         if (token == TokenNameLPAREN) {
2183           getNextToken();
2184           if (token != TokenNameRPAREN) {
2185             expressionList();
2186             if (token != TokenNameRPAREN) {
2187               throwSyntaxError("')' expected after identifier '"
2188                   + new String(ident) + "' in postfix-expression."
2189                   + "(Found token: " + scanner.toStringAction(token) + ")");
2190             }
2191           }
2192           getNextToken();
2193         }
2194         break;
2195       case TokenNamearray :
2196     //    T_ARRAY '(' array_pair_list ')'
2197         getNextToken();
2198         if (token == TokenNameLPAREN) {
2199           getNextToken();
2200           if (token == TokenNameRPAREN) {
2201             getNextToken();
2202             break;
2203           }
2204           array_pair_list();
2205           if (token != TokenNameRPAREN) {
2206             throwSyntaxError("')' expected after keyword 'array'"
2207                 + "(Found token: " + scanner.toStringAction(token) + ")");
2208           }
2209           getNextToken();
2210         } else {
2211           throwSyntaxError("'(' expected after keyword 'array'"
2212               + "(Found token: " + scanner.toStringAction(token) + ")");
2213         }
2214         break;
2215       case TokenNameprint :
2216         getNextToken();
2217         expr();
2218         break;
2219       case TokenNameexit :
2220         getNextToken();
2221         exit_expr();
2222         break;
2223       case TokenNamelist :
2224         getNextToken();
2225         if (token == TokenNameLPAREN) {
2226           getNextToken();
2227           if (token == TokenNameCOMMA) {
2228             getNextToken();
2229           }
2230           expressionList();
2231           if (token != TokenNameRPAREN) {
2232             throwSyntaxError("')' expected after 'list' keyword.");
2233           }
2234           getNextToken();
2235           //          if (token == TokenNameSET) {
2236           //            getNextToken();
2237           //            logicalinclusiveorExpression();
2238           //          }
2239         } else {
2240           throwSyntaxError("'(' expected after 'list' keyword.");
2241         }
2242         break;
2243     //      case TokenNameexit :
2244     //        getNextToken();
2245     //        if (token != TokenNameSEMICOLON) {
2246     //          exitStatus();
2247     //        }
2248     //        if (token == TokenNameSEMICOLON) {
2249     //          getNextToken();
2250     //        } else {
2251     //          if (token != TokenNameStopPHP) {
2252     //            throwSyntaxError("';' expected after 'exit' expression.");
2253     //          }
2254     //          getNextToken();
2255     //        }
2256     //        break;
2257     //      case TokenNamedie :
2258     //        getNextToken();
2259     //        if (token != TokenNameSEMICOLON) {
2260     //          exitStatus();
2261     //        }
2262     //        if (token == TokenNameSEMICOLON) {
2263     //          getNextToken();
2264     //        } else {
2265     //          if (token != TokenNameStopPHP) {
2266     //            throwSyntaxError("';' expected after 'die' expression.");
2267     //          }
2268     //        }
2269     //        break;
2270     //      case TokenNamearray :
2271     //        getNextToken();
2272     //        if (token == TokenNameARGOPEN) {
2273     //          getNextToken();
2274     //          if (token == TokenNameCOMMA) {
2275     //            getNextToken();
2276     //          }
2277     //          expressionList();
2278     //          if (token != TokenNameARGCLOSE) {
2279     //            throwSyntaxError("')' expected after 'list' keyword.");
2280     //          }
2281     //          getNextToken();
2282     //          if (token == TokenNameSET) {
2283     //            getNextToken();
2284     //            logicalinclusiveorExpression();
2285     //          }
2286     //        } else {
2287     //          throwSyntaxError("'(' expected after 'list' keyword.");
2288     //        }
2289     //        break;
2290     }
2291     boolean while_flag = true;
2292     do {
2293       switch (token) {
2294         case TokenNameLBRACKET :
2295           getNextToken();
2296           expr();
2297           if (token != TokenNameRBRACKET) {
2298             throwSyntaxError("] expected in postfix-expression.");
2299           }
2300           getNextToken();
2301           break;
2302         case TokenNameCOLON_COLON :
2303         // ::
2304         case TokenNameMINUS_GREATER :
2305           // ->
2306           getNextToken();
2307           if (token > TokenNameKEYWORD) {
2308             ident = scanner.getCurrentIdentifierSource();
2309             //            setMarker(
2310             //              "Avoid using keyword '"
2311             //                + new String(ident)
2312             //                + "' as variable name.",
2313             //              rowCount,
2314             //              PHPParser.INFO);
2315             //            setMarker(
2316             //              "Avoid using keyword '" + new String(ident) + "' as
2317             // variable name.",
2318             //              scanner.getCurrentTokenStartPosition(),
2319             //              scanner.getCurrentTokenEndPosition(),
2320             //              INFO);
2321           }
2322           switch (token) {
2323             case TokenNameVariable :
2324               ident = scanner.getCurrentIdentifierSource();
2325               getNextToken();
2326               //              if (token == TokenNameARGOPEN) {
2327               //                getNextToken();
2328               //                expressionList();
2329               //                if (token != TokenNameARGCLOSE) {
2330               //                  throwSyntaxError(") expected after variable '" +
2331               // ident + "'.");
2332               //                }
2333               //                getNextToken();
2334               //              }
2335               break;
2336             case TokenNameIdentifier :
2337               //ident = scanner.getCurrentIdentifierSource();
2338               getNextToken();
2339               break;
2340             case TokenNameLBRACE :
2341               getNextToken();
2342               expr();
2343               if (token != TokenNameRBRACE) {
2344                 throwSyntaxError("} expected in postfix-expression.");
2345               }
2346               getNextToken();
2347               break;
2348             default :
2349               throwSyntaxError("Syntax error after '->' token.");
2350           }
2351           while (token == TokenNameLBRACKET || token == TokenNameLPAREN
2352               || token == TokenNameLBRACE) {
2353             if (token == TokenNameLBRACKET) {
2354               getNextToken();
2355               expressionList();
2356               if (token != TokenNameRBRACKET) {
2357                 throwSyntaxError("] expected after '->'.");
2358               }
2359               getNextToken();
2360             } else if (token == TokenNameLPAREN) {
2361               getNextToken();
2362               expressionList();
2363               if (token != TokenNameRPAREN) {
2364                 throwSyntaxError(") expected after '->'.");
2365               }
2366               getNextToken();
2367             } else if (token == TokenNameLBRACE) {
2368               getNextToken();
2369               expr();
2370               if (token != TokenNameRBRACE) {
2371                 throwSyntaxError("} expected after '->'.");
2372               }
2373               getNextToken();
2374             }
2375           }
2376           break;
2377         case TokenNamePLUS_PLUS :
2378           getNextToken();
2379           break;
2380         case TokenNameMINUS_MINUS :
2381           getNextToken();
2382           break;
2383         default :
2384           while_flag = false;
2385       }
2386     } while (while_flag);
2387   }
2388   private void array_pair_list() {
2389 //  array_pair_list:
2390 //      /* empty */  
2391 //|     non_empty_array_pair_list possible_comma        
2392     non_empty_array_pair_list();
2393     if (token == TokenNameCOMMA) {
2394       getNextToken();
2395     }
2396   }
2397  
2398  
2399   private void non_empty_array_pair_list() {
2400 //non_empty_array_pair_list:
2401 //      non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr   
2402 //|     non_empty_array_pair_list ',' expr                       
2403 //|     expr T_DOUBLE_ARROW expr 
2404 //|     expr                             
2405 //|     non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable 
2406 //|     non_empty_array_pair_list ',' '&' w_variable  
2407 //|     expr T_DOUBLE_ARROW '&' w_variable 
2408 //|     '&' w_variable                   
2409   }
2410   
2411   private void unaryExpression() {
2412     switch (token) {
2413       case TokenNamePLUS_PLUS :
2414         getNextToken();
2415         unaryExpression();
2416         break;
2417       case TokenNameMINUS_MINUS :
2418         getNextToken();
2419         unaryExpression();
2420         break;
2421       // '@' '&' '*' '+' '-' '~' '!'
2422       case TokenNameAT :
2423         getNextToken();
2424         if (token == TokenNameinclude || token == TokenNameinclude_once
2425             || token == TokenNamerequire || token == TokenNamerequire_once) {
2426           statement(TokenNameAT);
2427         } else {
2428           expr_without_variable(); //  castExpression();
2429         }
2430         break;
2431       case TokenNameAND :
2432         getNextToken();
2433         castExpression();
2434         break;
2435       case TokenNameMULTIPLY :
2436         getNextToken();
2437         castExpression();
2438         break;
2439       case TokenNamePLUS :
2440         getNextToken();
2441         castExpression();
2442         break;
2443       case TokenNameMINUS :
2444         getNextToken();
2445         castExpression();
2446         break;
2447       case TokenNameTWIDDLE :
2448         getNextToken();
2449         castExpression();
2450         break;
2451       case TokenNameNOT :
2452         getNextToken();
2453         castExpression();
2454         break;
2455       default :
2456         expr_without_variable();
2457     }
2458   }
2459   private void castExpression() {
2460     //    if (token == TokenNameARGOPEN) {
2461     //      getNextToken();
2462     //      typeName();
2463     //      if (token != TokenNameARGCLOSE) {
2464     //        throwSyntaxError(") expected after cast-expression.");
2465     //      }
2466     //      getNextToken();
2467     //    }
2468     unaryExpression();
2469   }
2470   private void assignExpression() {
2471     castExpression();
2472     if (token == TokenNameEQUAL) { // =
2473       getNextToken();
2474       logicalinclusiveorExpression();
2475     } else if (token == TokenNameDOT_EQUAL) { // .=
2476       getNextToken();
2477       logicalinclusiveorExpression();
2478     } else if (token == TokenNameEQUAL_GREATER) { // =>
2479       getNextToken();
2480       logicalinclusiveorExpression();
2481     } else if (token == TokenNamePLUS_EQUAL) { // +=
2482       getNextToken();
2483       logicalinclusiveorExpression();
2484     } else if (token == TokenNameMINUS_EQUAL) { // -=
2485       getNextToken();
2486       logicalinclusiveorExpression();
2487     } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
2488       getNextToken();
2489       logicalinclusiveorExpression();
2490     } else if (token == TokenNameDIVIDE_EQUAL) { // *=
2491       getNextToken();
2492       logicalinclusiveorExpression();
2493     } else if (token == TokenNameREMAINDER_EQUAL) { // %=
2494       getNextToken();
2495       logicalinclusiveorExpression();
2496     } else if (token == TokenNameAND_EQUAL) { // &=
2497       getNextToken();
2498       logicalinclusiveorExpression();
2499     } else if (token == TokenNameOR_EQUAL) { // |=
2500       getNextToken();
2501       logicalinclusiveorExpression();
2502     } else if (token == TokenNameXOR_EQUAL) { // ^=
2503       getNextToken();
2504       logicalinclusiveorExpression();
2505     } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
2506       getNextToken();
2507       logicalinclusiveorExpression();
2508     } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
2509       getNextToken();
2510       logicalinclusiveorExpression();
2511     } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
2512       getNextToken();
2513       logicalinclusiveorExpression();
2514     }
2515   }
2516   private void multiplicativeExpression() {
2517     do {
2518       assignExpression();
2519       if (token != TokenNameMULTIPLY && token != TokenNameDIVIDE
2520           && token != TokenNameREMAINDER) {
2521         return;
2522       }
2523       getNextToken();
2524     } while (true);
2525   }
2526   private void concatenationExpression() {
2527     do {
2528       multiplicativeExpression();
2529       if (token != TokenNameDOT) {
2530         return;
2531       }
2532       getNextToken();
2533     } while (true);
2534   }
2535   private void additiveExpression() {
2536     do {
2537       concatenationExpression();
2538       if (token != TokenNamePLUS && token != TokenNameMINUS) {
2539         return;
2540       }
2541       getNextToken();
2542     } while (true);
2543   }
2544   private void shiftExpression() {
2545     do {
2546       additiveExpression();
2547       if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
2548         return;
2549       }
2550       getNextToken();
2551     } while (true);
2552   }
2553   private void relationalExpression() {
2554     do {
2555       shiftExpression();
2556       if (token != TokenNameLESS && token != TokenNameGREATER
2557           && token != TokenNameLESS_EQUAL && token != TokenNameGREATER_EQUAL) {
2558         return;
2559       }
2560       getNextToken();
2561     } while (true);
2562   }
2563   private void identicalExpression() {
2564     do {
2565       relationalExpression();
2566       if (token != TokenNameEQUAL_EQUAL_EQUAL
2567           && token != TokenNameNOT_EQUAL_EQUAL) {
2568         return;
2569       }
2570       getNextToken();
2571     } while (true);
2572   }
2573   private void equalityExpression() {
2574     do {
2575       identicalExpression();
2576       if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
2577         return;
2578       }
2579       getNextToken();
2580     } while (true);
2581   }
2582   private void ternaryExpression() {
2583     equalityExpression();
2584     if (token == TokenNameQUESTION) {
2585       getNextToken();
2586       expr();
2587       if (token == TokenNameCOLON) {
2588         getNextToken();
2589         expr();
2590       } else {
2591         throwSyntaxError("':' expected in ternary operator '? :'.");
2592       }
2593     }
2594   }
2595   private void andExpression() {
2596     do {
2597       ternaryExpression();
2598       if (token != TokenNameAND) {
2599         return;
2600       }
2601       getNextToken();
2602     } while (true);
2603   }
2604   private void exclusiveorExpression() {
2605     do {
2606       andExpression();
2607       if (token != TokenNameXOR) {
2608         return;
2609       }
2610       getNextToken();
2611     } while (true);
2612   }
2613   private void inclusiveorExpression() {
2614     do {
2615       exclusiveorExpression();
2616       if (token != TokenNameOR) {
2617         return;
2618       }
2619       getNextToken();
2620     } while (true);
2621   }
2622   private void booleanandExpression() {
2623     do {
2624       inclusiveorExpression();
2625       if (token != TokenNameAND_AND) {
2626         return;
2627       }
2628       getNextToken();
2629     } while (true);
2630   }
2631   private void booleanorExpression() {
2632     do {
2633       booleanandExpression();
2634       if (token != TokenNameOR_OR) {
2635         return;
2636       }
2637       getNextToken();
2638     } while (true);
2639   }
2640   private void logicalandExpression() {
2641     do {
2642       booleanorExpression();
2643       if (token != TokenNameAND) {
2644         return;
2645       }
2646       getNextToken();
2647     } while (true);
2648   }
2649   private void logicalexclusiveorExpression() {
2650     do {
2651       logicalandExpression();
2652       if (token != TokenNameXOR) {
2653         return;
2654       }
2655       getNextToken();
2656     } while (true);
2657   }
2658   private void logicalinclusiveorExpression() {
2659     do {
2660       logicalexclusiveorExpression();
2661       if (token != TokenNameOR) {
2662         return;
2663       }
2664       getNextToken();
2665     } while (true);
2666   }
2667   //  public void assignmentExpression() {
2668   //    if (token == TokenNameVARIABLE) {
2669   //      getNextToken();
2670   //      if (token == TokenNameSET) {
2671   //        getNextToken();
2672   //        logicalinclusiveorExpression();
2673   //      }
2674   //    } else {
2675   //      logicalinclusiveorExpression();
2676   //    }
2677   //  }
2678   private void variableList() {
2679     do {
2680       variable();
2681       if (token == TokenNameCOMMA) {
2682         getNextToken();
2683       } else {
2684         break;
2685       }
2686     } while (true);
2687   }
2688   private void variable() {
2689     if (token == TokenNameDOLLAR_LBRACE) {
2690       getNextToken();
2691       expr();
2692       ;
2693       if (token != TokenNameRBRACE) {
2694         throwSyntaxError("'}' expected after indirect variable token '${'.");
2695       }
2696       getNextToken();
2697     } else {
2698       if (token == TokenNameVariable) {
2699         getNextToken();
2700         if (token == TokenNameLBRACKET) {
2701           getNextToken();
2702           expr();
2703           if (token != TokenNameRBRACKET) {
2704             throwSyntaxError("']' expected in variable-list.");
2705           }
2706           getNextToken();
2707         } else if (token == TokenNameEQUAL) {
2708           getNextToken();
2709           constant();
2710         }
2711       } else {
2712         throwSyntaxError("$-variable expected in variable-list.");
2713       }
2714     }
2715   }
2716   private void exit_expr() {
2717     //  /* empty */
2718     //  | '(' ')'
2719     //  | '(' expr ')'
2720     if (token != TokenNameLPAREN) {
2721       return;
2722     }
2723     getNextToken();
2724     if (token == TokenNameRPAREN) {
2725       getNextToken();
2726       return;
2727     }
2728     expr();
2729     if (token != TokenNameRPAREN) {
2730       throwSyntaxError("')' expected after keyword 'exit'");
2731     }
2732     getNextToken();
2733   }
2734   private void internal_functions_in_yacc() {
2735     switch (token) {
2736       case TokenNameisset :
2737         //      T_ISSET '(' isset_variables ')'
2738         getNextToken();
2739         if (token != TokenNameLPAREN) {
2740           throwSyntaxError("'(' expected after keyword 'isset'");
2741         }
2742         getNextToken();
2743         isset_variables();
2744         if (token != TokenNameRPAREN) {
2745           throwSyntaxError("')' expected after keyword 'isset'");
2746         }
2747         getNextToken();
2748         break;
2749       case TokenNameempty :
2750         //      T_EMPTY '(' variable ')'
2751         getNextToken();
2752         if (token != TokenNameLPAREN) {
2753           throwSyntaxError("'(' expected after keyword 'empty'");
2754         }
2755         getNextToken();
2756         variable();
2757         if (token != TokenNameRPAREN) {
2758           throwSyntaxError("')' expected after keyword 'empty'");
2759         }
2760         getNextToken();
2761         break;
2762       case TokenNameinclude :
2763         //T_INCLUDE expr
2764         getNextToken();
2765         expr();
2766         break;
2767       case TokenNameinclude_once :
2768         //      T_INCLUDE_ONCE expr
2769         getNextToken();
2770         expr();
2771         break;
2772       case TokenNameeval :
2773         //      T_EVAL '(' expr ')'
2774         getNextToken();
2775         if (token != TokenNameLPAREN) {
2776           throwSyntaxError("'(' expected after keyword 'eval'");
2777         }
2778         getNextToken();
2779         expr();
2780         if (token != TokenNameRPAREN) {
2781           throwSyntaxError("')' expected after keyword 'eval'");
2782         }
2783         getNextToken();
2784         break;
2785       case TokenNamerequire :
2786         //T_REQUIRE expr
2787         getNextToken();
2788         expr();
2789         break;
2790       case TokenNamerequire_once :
2791         //      T_REQUIRE_ONCE expr
2792         getNextToken();
2793         expr();
2794         break;
2795     }
2796   }
2797   private void isset_variables() {
2798     //  variable
2799     //  | isset_variables ','
2800     if (token == TokenNameRPAREN) {
2801       throwSyntaxError("Variable expected after keyword 'isset'");
2802     }
2803     while (true) {
2804       variable();
2805       if (token == TokenNameCOMMA) {
2806         getNextToken();
2807       } else {
2808         break;
2809       }
2810     }
2811   }
2812   /**
2813    * It will look for a value (after a '=' for example) @
2814    */
2815   private void constant() {
2816     //   String ident;
2817     switch (token) {
2818       case TokenNamePLUS :
2819         getNextToken();
2820         switch (token) {
2821           case TokenNameDoubleLiteral :
2822             getNextToken();
2823             break;
2824           case TokenNameIntegerLiteral :
2825             getNextToken();
2826             break;
2827           default :
2828             throwSyntaxError("Constant expected after '+' presign.");
2829         }
2830         break;
2831       case TokenNameMINUS :
2832         getNextToken();
2833         switch (token) {
2834           case TokenNameDoubleLiteral :
2835             getNextToken();
2836             break;
2837           case TokenNameIntegerLiteral :
2838             getNextToken();
2839             break;
2840           default :
2841             throwSyntaxError("Constant expected after '-' presign.");
2842         }
2843         break;
2844       case TokenNamenull :
2845         getNextToken();
2846         break;
2847       case TokenNamefalse :
2848         getNextToken();
2849         break;
2850       case TokenNametrue :
2851         getNextToken();
2852         break;
2853       case TokenNameIdentifier :
2854         //   ident = identifier;
2855         char[] ident = scanner.getCurrentIdentifierSource();
2856         getNextToken();
2857         if (token == TokenNameLPAREN) {
2858           getNextToken();
2859           if (token != TokenNameRPAREN) {
2860             expressionList();
2861             if (token != TokenNameRPAREN) {
2862               throwSyntaxError("')' expected after identifier '"
2863                   + new String(ident) + "' in postfix-expression.");
2864             }
2865           }
2866           getNextToken();
2867         }
2868         break;
2869       case TokenNameStringLiteral :
2870         getNextToken();
2871         break;
2872       case TokenNameStringConstant :
2873         getNextToken();
2874         break;
2875       case TokenNameStringInterpolated :
2876         getNextToken();
2877         break;
2878       case TokenNameDoubleLiteral :
2879         getNextToken();
2880         break;
2881       case TokenNameIntegerLiteral :
2882         getNextToken();
2883         break;
2884       default :
2885         throwSyntaxError("Constant expected.");
2886     }
2887   }
2888   public void reportSyntaxError() { //int act, int currentKind, int
2889     // stateStackTop) {
2890     /* remember current scanner position */
2891     int startPos = scanner.startPosition;
2892     int currentPos = scanner.currentPosition;
2893     //          String[] expectings;
2894     //          String tokenName = name[symbol_index[currentKind]];
2895     //fetch all "accurate" possible terminals that could recover the error
2896     //          int start, end = start = asi(stack[stateStackTop]);
2897     //          while (asr[end] != 0)
2898     //                  end++;
2899     //          int length = end - start;
2900     //          expectings = new String[length];
2901     //          if (length != 0) {
2902     //                  char[] indexes = new char[length];
2903     //                  System.arraycopy(asr, start, indexes, 0, length);
2904     //                  for (int i = 0; i < length; i++) {
2905     //                          expectings[i] = name[symbol_index[indexes[i]]];
2906     //                  }
2907     //          }
2908     //if the pb is an EOF, try to tell the user that they are some
2909     //          if (tokenName.equals(UNEXPECTED_EOF)) {
2910     //                  if (!this.checkAndReportBracketAnomalies(problemReporter())) {
2911     //                          char[] tokenSource;
2912     //                          try {
2913     //                                  tokenSource = this.scanner.getCurrentTokenSource();
2914     //                          } catch (Exception e) {
2915     //                                  tokenSource = new char[] {};
2916     //                          }
2917     //                          problemReporter().parseError(
2918     //                                  this.scanner.startPosition,
2919     //                                  this.scanner.currentPosition - 1,
2920     //                                  tokenSource,
2921     //                                  tokenName,
2922     //                                  expectings);
2923     //                  }
2924     //          } else { //the next test is HEAVILY grammar DEPENDENT.
2925     //                  if ((length == 14)
2926     //                          && (expectings[0] == "=") //$NON-NLS-1$
2927     //                          && (expectings[1] == "*=") //$NON-NLS-1$
2928     //                          && (expressionPtr > -1)) {
2929     //                                  switch(currentKind) {
2930     //                                          case TokenNameSEMICOLON:
2931     //                                          case TokenNamePLUS:
2932     //                                          case TokenNameMINUS:
2933     //                                          case TokenNameDIVIDE:
2934     //                                          case TokenNameREMAINDER:
2935     //                                          case TokenNameMULTIPLY:
2936     //                                          case TokenNameLEFT_SHIFT:
2937     //                                          case TokenNameRIGHT_SHIFT:
2938     //// case TokenNameUNSIGNED_RIGHT_SHIFT:
2939     //                                          case TokenNameLESS:
2940     //                                          case TokenNameGREATER:
2941     //                                          case TokenNameLESS_EQUAL:
2942     //                                          case TokenNameGREATER_EQUAL:
2943     //                                          case TokenNameEQUAL_EQUAL:
2944     //                                          case TokenNameNOT_EQUAL:
2945     //                                          case TokenNameXOR:
2946     //                                          case TokenNameAND:
2947     //                                          case TokenNameOR:
2948     //                                          case TokenNameOR_OR:
2949     //                                          case TokenNameAND_AND:
2950     //                                                  // the ; is not the expected token ==> it ends a statement when an
2951     // expression is not ended
2952     //                                                  problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
2953     //                                                  break;
2954     //                                          case TokenNameRBRACE :
2955     //                                                  problemReporter().missingSemiColon(expressionStack[expressionPtr]);
2956     //                                                  break;
2957     //                                          default:
2958     //                                                  char[] tokenSource;
2959     //                                                  try {
2960     //                                                          tokenSource = this.scanner.getCurrentTokenSource();
2961     //                                                  } catch (Exception e) {
2962     //                                                          tokenSource = new char[] {};
2963     //                                                  }
2964     //                                                  problemReporter().parseError(
2965     //                                                          this.scanner.startPosition,
2966     //                                                          this.scanner.currentPosition - 1,
2967     //                                                          tokenSource,
2968     //                                                          tokenName,
2969     //                                                          expectings);
2970     //                                                  this.checkAndReportBracketAnomalies(problemReporter());
2971     //                                  }
2972     //                  } else {
2973     char[] tokenSource;
2974     try {
2975       tokenSource = this.scanner.getCurrentTokenSource();
2976     } catch (Exception e) {
2977       tokenSource = new char[]{};
2978     }
2979     //                          problemReporter().parseError(
2980     //                                  this.scanner.startPosition,
2981     //                                  this.scanner.currentPosition - 1,
2982     //                                  tokenSource,
2983     //                                  tokenName,
2984     //                                  expectings);
2985     this.checkAndReportBracketAnomalies(problemReporter());
2986     //                  }
2987     //          }
2988     /* reset scanner where it was */
2989     scanner.startPosition = startPos;
2990     scanner.currentPosition = currentPos;
2991   }
2992   public static final int RoundBracket = 0;
2993   public static final int SquareBracket = 1;
2994   public static final int CurlyBracket = 2;
2995   public static final int BracketKinds = 3;
2996   protected int[] nestedMethod; //the ptr is nestedType
2997   protected int nestedType, dimensions;
2998   //ast stack
2999   final static int AstStackIncrement = 100;
3000   protected int astPtr;
3001   protected AstNode[] astStack = new AstNode[AstStackIncrement];
3002   protected int astLengthPtr;
3003   protected int[] astLengthStack;
3004   AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3005   public CompilationUnitDeclaration compilationUnit; /*
3006                                                       * the result from parse()
3007                                                       */
3008   protected ReferenceContext referenceContext;
3009   protected ProblemReporter problemReporter;
3010   //  protected CompilationResult compilationResult;
3011   /**
3012    * Returns this parser's problem reporter initialized with its reference
3013    * context. Also it is assumed that a problem is going to be reported, so
3014    * initializes the compilation result's line positions.
3015    */
3016   public ProblemReporter problemReporter() {
3017     if (scanner.recordLineSeparator) {
3018       compilationUnit.compilationResult.lineSeparatorPositions = scanner
3019           .getLineEnds();
3020     }
3021     problemReporter.referenceContext = referenceContext;
3022     return problemReporter;
3023   }
3024   /*
3025    * Reconsider the entire source looking for inconsistencies in {} () []
3026    */
3027   public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3028     scanner.wasAcr = false;
3029     boolean anomaliesDetected = false;
3030     try {
3031       char[] source = scanner.source;
3032       int[] leftCount = {0, 0, 0};
3033       int[] rightCount = {0, 0, 0};
3034       int[] depths = {0, 0, 0};
3035       int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3036       int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3037       int[][] rightPositions = new int[][]{new int[10], new int[10],
3038           new int[10]};
3039       int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3040       scanner.currentPosition = scanner.initialPosition; //starting
3041       // point
3042       // (first-zero-based
3043       // char)
3044       while (scanner.currentPosition < scanner.eofPosition) { //loop for
3045         // jumping
3046         // over
3047         // comments
3048         try {
3049           // ---------Consume white space and handles
3050           // startPosition---------
3051           boolean isWhiteSpace;
3052           do {
3053             scanner.startPosition = scanner.currentPosition;
3054             //                                          if (((scanner.currentCharacter =
3055             // source[scanner.currentPosition++]) == '\\') &&
3056             // (source[scanner.currentPosition] == 'u')) {
3057             //                                                  isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3058             //                                          } else {
3059             if (scanner.recordLineSeparator
3060                 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3061               if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3062                 // only record line positions we have not
3063                 // recorded yet
3064                 scanner.pushLineSeparator();
3065               }
3066             }
3067             isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3068             //                                          }
3069           } while (isWhiteSpace
3070               && (scanner.currentPosition < scanner.eofPosition));
3071           // -------consume token until } is found---------
3072           switch (scanner.currentCharacter) {
3073             case '{' :
3074               {
3075                 int index = leftCount[CurlyBracket]++;
3076                 if (index == leftPositions[CurlyBracket].length) {
3077                   System.arraycopy(leftPositions[CurlyBracket], 0,
3078                       (leftPositions[CurlyBracket] = new int[index * 2]), 0,
3079                       index);
3080                   System
3081                       .arraycopy(leftDepths[CurlyBracket], 0,
3082                           (leftDepths[CurlyBracket] = new int[index * 2]), 0,
3083                           index);
3084                 }
3085                 leftPositions[CurlyBracket][index] = scanner.startPosition;
3086                 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3087               }
3088               break;
3089             case '}' :
3090               {
3091                 int index = rightCount[CurlyBracket]++;
3092                 if (index == rightPositions[CurlyBracket].length) {
3093                   System.arraycopy(rightPositions[CurlyBracket], 0,
3094                       (rightPositions[CurlyBracket] = new int[index * 2]), 0,
3095                       index);
3096                   System.arraycopy(rightDepths[CurlyBracket], 0,
3097                       (rightDepths[CurlyBracket] = new int[index * 2]), 0,
3098                       index);
3099                 }
3100                 rightPositions[CurlyBracket][index] = scanner.startPosition;
3101                 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3102               }
3103               break;
3104             case '(' :
3105               {
3106                 int index = leftCount[RoundBracket]++;
3107                 if (index == leftPositions[RoundBracket].length) {
3108                   System.arraycopy(leftPositions[RoundBracket], 0,
3109                       (leftPositions[RoundBracket] = new int[index * 2]), 0,
3110                       index);
3111                   System
3112                       .arraycopy(leftDepths[RoundBracket], 0,
3113                           (leftDepths[RoundBracket] = new int[index * 2]), 0,
3114                           index);
3115                 }
3116                 leftPositions[RoundBracket][index] = scanner.startPosition;
3117                 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3118               }
3119               break;
3120             case ')' :
3121               {
3122                 int index = rightCount[RoundBracket]++;
3123                 if (index == rightPositions[RoundBracket].length) {
3124                   System.arraycopy(rightPositions[RoundBracket], 0,
3125                       (rightPositions[RoundBracket] = new int[index * 2]), 0,
3126                       index);
3127                   System.arraycopy(rightDepths[RoundBracket], 0,
3128                       (rightDepths[RoundBracket] = new int[index * 2]), 0,
3129                       index);
3130                 }
3131                 rightPositions[RoundBracket][index] = scanner.startPosition;
3132                 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3133               }
3134               break;
3135             case '[' :
3136               {
3137                 int index = leftCount[SquareBracket]++;
3138                 if (index == leftPositions[SquareBracket].length) {
3139                   System.arraycopy(leftPositions[SquareBracket], 0,
3140                       (leftPositions[SquareBracket] = new int[index * 2]), 0,
3141                       index);
3142                   System.arraycopy(leftDepths[SquareBracket], 0,
3143                       (leftDepths[SquareBracket] = new int[index * 2]), 0,
3144                       index);
3145                 }
3146                 leftPositions[SquareBracket][index] = scanner.startPosition;
3147                 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3148               }
3149               break;
3150             case ']' :
3151               {
3152                 int index = rightCount[SquareBracket]++;
3153                 if (index == rightPositions[SquareBracket].length) {
3154                   System.arraycopy(rightPositions[SquareBracket], 0,
3155                       (rightPositions[SquareBracket] = new int[index * 2]), 0,
3156                       index);
3157                   System.arraycopy(rightDepths[SquareBracket], 0,
3158                       (rightDepths[SquareBracket] = new int[index * 2]), 0,
3159                       index);
3160                 }
3161                 rightPositions[SquareBracket][index] = scanner.startPosition;
3162                 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3163               }
3164               break;
3165             case '\'' :
3166               {
3167                 if (scanner.getNextChar('\\')) {
3168                   scanner.scanEscapeCharacter();
3169                 } else { // consume next character
3170                   scanner.unicodeAsBackSlash = false;
3171                   //                                                                    if (((scanner.currentCharacter =
3172                   // source[scanner.currentPosition++]) ==
3173                   // '\\') &&
3174                   // (source[scanner.currentPosition] ==
3175                   // 'u')) {
3176                   //                                                                            scanner.getNextUnicodeChar();
3177                   //                                                                    } else {
3178                   if (scanner.withoutUnicodePtr != 0) {
3179                     scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3180                   }
3181                   //                                                                    }
3182                 }
3183                 scanner.getNextChar('\'');
3184                 break;
3185               }
3186             case '"' :
3187               // consume next character
3188               scanner.unicodeAsBackSlash = false;
3189               //                                                        if (((scanner.currentCharacter =
3190               // source[scanner.currentPosition++]) == '\\') &&
3191               // (source[scanner.currentPosition] == 'u')) {
3192               //                                                                scanner.getNextUnicodeChar();
3193               //                                                        } else {
3194               if (scanner.withoutUnicodePtr != 0) {
3195                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3196               }
3197               //                                                        }
3198               while (scanner.currentCharacter != '"') {
3199                 if (scanner.currentCharacter == '\r') {
3200                   if (source[scanner.currentPosition] == '\n')
3201                     scanner.currentPosition++;
3202                   break; // the string cannot go further that
3203                   // the line
3204                 }
3205                 if (scanner.currentCharacter == '\n') {
3206                   break; // the string cannot go further that
3207                   // the line
3208                 }
3209                 if (scanner.currentCharacter == '\\') {
3210                   scanner.scanEscapeCharacter();
3211                 }
3212                 // consume next character
3213                 scanner.unicodeAsBackSlash = false;
3214                 //                                                              if (((scanner.currentCharacter =
3215                 // source[scanner.currentPosition++]) == '\\')
3216                 // && (source[scanner.currentPosition] == 'u'))
3217                 // {
3218                 //                                                                      scanner.getNextUnicodeChar();
3219                 //                                                              } else {
3220                 if (scanner.withoutUnicodePtr != 0) {
3221                   scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3222                 }
3223                 //                                                              }
3224               }
3225               break;
3226             case '/' :
3227               {
3228                 int test;
3229                 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3230                   // comment
3231                   //get the next char
3232                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3233                       && (source[scanner.currentPosition] == 'u')) {
3234                     //-------------unicode traitement
3235                     // ------------
3236                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3237                     scanner.currentPosition++;
3238                     while (source[scanner.currentPosition] == 'u') {
3239                       scanner.currentPosition++;
3240                     }
3241                     if ((c1 = Character
3242                         .getNumericValue(source[scanner.currentPosition++])) > 15
3243                         || c1 < 0
3244                         || (c2 = Character
3245                             .getNumericValue(source[scanner.currentPosition++])) > 15
3246                         || c2 < 0
3247                         || (c3 = Character
3248                             .getNumericValue(source[scanner.currentPosition++])) > 15
3249                         || c3 < 0
3250                         || (c4 = Character
3251                             .getNumericValue(source[scanner.currentPosition++])) > 15
3252                         || c4 < 0) { //error don't
3253                       // care of the
3254                       // value
3255                       scanner.currentCharacter = 'A';
3256                     } //something different from \n and \r
3257                     else {
3258                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3259                     }
3260                   }
3261                   while (scanner.currentCharacter != '\r'
3262                       && scanner.currentCharacter != '\n') {
3263                     //get the next char
3264                     scanner.startPosition = scanner.currentPosition;
3265                     if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3266                         && (source[scanner.currentPosition] == 'u')) {
3267                       //-------------unicode traitement
3268                       // ------------
3269                       int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3270                       scanner.currentPosition++;
3271                       while (source[scanner.currentPosition] == 'u') {
3272                         scanner.currentPosition++;
3273                       }
3274                       if ((c1 = Character
3275                           .getNumericValue(source[scanner.currentPosition++])) > 15
3276                           || c1 < 0
3277                           || (c2 = Character
3278                               .getNumericValue(source[scanner.currentPosition++])) > 15
3279                           || c2 < 0
3280                           || (c3 = Character
3281                               .getNumericValue(source[scanner.currentPosition++])) > 15
3282                           || c3 < 0
3283                           || (c4 = Character
3284                               .getNumericValue(source[scanner.currentPosition++])) > 15
3285                           || c4 < 0) { //error don't
3286                         // care of the
3287                         // value
3288                         scanner.currentCharacter = 'A';
3289                       } //something different from \n
3290                       // and \r
3291                       else {
3292                         scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3293                       }
3294                     }
3295                   }
3296                   if (scanner.recordLineSeparator
3297                       && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3298                     if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3299                       // only record line positions we
3300                       // have not recorded yet
3301                       scanner.pushLineSeparator();
3302                       if (this.scanner.taskTags != null) {
3303                         this.scanner.checkTaskTag(this.scanner
3304                             .getCurrentTokenStartPosition(), this.scanner
3305                             .getCurrentTokenEndPosition());
3306                       }
3307                     }
3308                   }
3309                   break;
3310                 }
3311                 if (test > 0) { //traditional and annotation
3312                   // comment
3313                   boolean star = false;
3314                   // consume next character
3315                   scanner.unicodeAsBackSlash = false;
3316                   //                                                                    if (((scanner.currentCharacter =
3317                   // source[scanner.currentPosition++]) ==
3318                   // '\\') &&
3319                   // (source[scanner.currentPosition] ==
3320                   // 'u')) {
3321                   //                                                                            scanner.getNextUnicodeChar();
3322                   //                                                                    } else {
3323                   if (scanner.withoutUnicodePtr != 0) {
3324                     scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3325                   }
3326                   //                                                                    }
3327                   if (scanner.currentCharacter == '*') {
3328                     star = true;
3329                   }
3330                   //get the next char
3331                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3332                       && (source[scanner.currentPosition] == 'u')) {
3333                     //-------------unicode traitement
3334                     // ------------
3335                     int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3336                     scanner.currentPosition++;
3337                     while (source[scanner.currentPosition] == 'u') {
3338                       scanner.currentPosition++;
3339                     }
3340                     if ((c1 = Character
3341                         .getNumericValue(source[scanner.currentPosition++])) > 15
3342                         || c1 < 0
3343                         || (c2 = Character
3344                             .getNumericValue(source[scanner.currentPosition++])) > 15
3345                         || c2 < 0
3346                         || (c3 = Character
3347                             .getNumericValue(source[scanner.currentPosition++])) > 15
3348                         || c3 < 0
3349                         || (c4 = Character
3350                             .getNumericValue(source[scanner.currentPosition++])) > 15
3351                         || c4 < 0) { //error don't
3352                       // care of the
3353                       // value
3354                       scanner.currentCharacter = 'A';
3355                     } //something different from * and /
3356                     else {
3357                       scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3358                     }
3359                   }
3360                   //loop until end of comment */
3361                   while ((scanner.currentCharacter != '/') || (!star)) {
3362                     star = scanner.currentCharacter == '*';
3363                     //get next char
3364                     if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3365                         && (source[scanner.currentPosition] == 'u')) {
3366                       //-------------unicode traitement
3367                       // ------------
3368                       int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3369                       scanner.currentPosition++;
3370                       while (source[scanner.currentPosition] == 'u') {
3371                         scanner.currentPosition++;
3372                       }
3373                       if ((c1 = Character
3374                           .getNumericValue(source[scanner.currentPosition++])) > 15
3375                           || c1 < 0
3376                           || (c2 = Character
3377                               .getNumericValue(source[scanner.currentPosition++])) > 15
3378                           || c2 < 0
3379                           || (c3 = Character
3380                               .getNumericValue(source[scanner.currentPosition++])) > 15
3381                           || c3 < 0
3382                           || (c4 = Character
3383                               .getNumericValue(source[scanner.currentPosition++])) > 15
3384                           || c4 < 0) { //error don't
3385                         // care of the
3386                         // value
3387                         scanner.currentCharacter = 'A';
3388                       } //something different from * and
3389                       // /
3390                       else {
3391                         scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3392                       }
3393                     }
3394                   }
3395                   if (this.scanner.taskTags != null) {
3396                     this.scanner.checkTaskTag(this.scanner
3397                         .getCurrentTokenStartPosition(), this.scanner
3398                         .getCurrentTokenEndPosition());
3399                   }
3400                   break;
3401                 }
3402                 break;
3403               }
3404             default :
3405               if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3406                 scanner.scanIdentifierOrKeyword(false);
3407                 break;
3408               }
3409               if (Character.isDigit(scanner.currentCharacter)) {
3410                 scanner.scanNumber(false);
3411                 break;
3412               }
3413           }
3414           //-----------------end switch while
3415           // try--------------------
3416         } catch (IndexOutOfBoundsException e) {
3417           break; // read until EOF
3418         } catch (InvalidInputException e) {
3419           return false; // no clue
3420         }
3421       }
3422       if (scanner.recordLineSeparator) {
3423         //                              compilationUnit.compilationResult.lineSeparatorPositions =
3424         // scanner.getLineEnds();
3425       }
3426       // check placement anomalies against other kinds of brackets
3427       for (int kind = 0; kind < BracketKinds; kind++) {
3428         for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3429           int start = leftPositions[kind][leftIndex]; // deepest
3430           // first
3431           // find matching closing bracket
3432           int depth = leftDepths[kind][leftIndex];
3433           int end = -1;
3434           for (int i = 0; i < rightCount[kind]; i++) {
3435             int pos = rightPositions[kind][i];
3436             // want matching bracket further in source with same
3437             // depth
3438             if ((pos > start) && (depth == rightDepths[kind][i])) {
3439               end = pos;
3440               break;
3441             }
3442           }
3443           if (end < 0) { // did not find a good closing match
3444             problemReporter.unmatchedBracket(start, referenceContext,
3445                 compilationUnit.compilationResult);
3446             return true;
3447           }
3448           // check if even number of opening/closing other brackets
3449           // in between this pair of brackets
3450           int balance = 0;
3451           for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3452             for (int i = 0; i < leftCount[otherKind]; i++) {
3453               int pos = leftPositions[otherKind][i];
3454               if ((pos > start) && (pos < end))
3455                 balance++;
3456             }
3457             for (int i = 0; i < rightCount[otherKind]; i++) {
3458               int pos = rightPositions[otherKind][i];
3459               if ((pos > start) && (pos < end))
3460                 balance--;
3461             }
3462             if (balance != 0) {
3463               problemReporter.unmatchedBracket(start, referenceContext,
3464                   compilationUnit.compilationResult); //bracket
3465               // anomaly
3466               return true;
3467             }
3468           }
3469         }
3470         // too many opening brackets ?
3471         for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3472           anomaliesDetected = true;
3473           problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind]
3474               - i - 1], referenceContext, compilationUnit.compilationResult);
3475         }
3476         // too many closing brackets ?
3477         for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3478           anomaliesDetected = true;
3479           problemReporter.unmatchedBracket(rightPositions[kind][i],
3480               referenceContext, compilationUnit.compilationResult);
3481         }
3482         if (anomaliesDetected)
3483           return true;
3484       }
3485       return anomaliesDetected;
3486     } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
3487       return anomaliesDetected;
3488     } catch (NullPointerException e) { // jdk1.2.2 jit bug
3489       return anomaliesDetected;
3490     }
3491   }
3492   protected void pushOnAstLengthStack(int pos) {
3493     try {
3494       astLengthStack[++astLengthPtr] = pos;
3495     } catch (IndexOutOfBoundsException e) {
3496       int oldStackLength = astLengthStack.length;
3497       int[] oldPos = astLengthStack;
3498       astLengthStack = new int[oldStackLength + StackIncrement];
3499       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3500       astLengthStack[astLengthPtr] = pos;
3501     }
3502   }
3503   protected void pushOnAstStack(AstNode node) {
3504     /*
3505      * add a new obj on top of the ast stack
3506      */
3507     try {
3508       astStack[++astPtr] = node;
3509     } catch (IndexOutOfBoundsException e) {
3510       int oldStackLength = astStack.length;
3511       AstNode[] oldStack = astStack;
3512       astStack = new AstNode[oldStackLength + AstStackIncrement];
3513       System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
3514       astPtr = oldStackLength;
3515       astStack[astPtr] = node;
3516     }
3517     try {
3518       astLengthStack[++astLengthPtr] = 1;
3519     } catch (IndexOutOfBoundsException e) {
3520       int oldStackLength = astLengthStack.length;
3521       int[] oldPos = astLengthStack;
3522       astLengthStack = new int[oldStackLength + AstStackIncrement];
3523       System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3524       astLengthStack[astLengthPtr] = 1;
3525     }
3526   }
3527 }