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