1 /**********************************************************************
 
   2 Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
 
   3 All rights reserved. This program and the accompanying materials
 
   4 are made available under the terms of the Common Public License v1.0
 
   5 which accompanies this distribution, and is available at
 
   6 http://www.eclipse.org/legal/cpl-v10.html
 
   9     Klaus Hartlage - www.eclipseproject.de
 
  10 **********************************************************************/
 
  11 package net.sourceforge.phpdt.internal.compiler.parser;
 
  13 import java.util.ArrayList;
 
  15 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  16 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  17 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  18 import net.sourceforge.phpeclipse.phpeditor.PHPString;
 
  20 import org.eclipse.core.resources.IFile;
 
  21 import org.eclipse.core.runtime.CoreException;
 
  22 import org.eclipse.jface.preference.IPreferenceStore;
 
  24 import test.PHPParserSuperclass;
 
  26 public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
 
  29   public Scanner scanner;
 
  31   private ArrayList phpList;
 
  33   private int currentPHPString;
 
  34   private boolean phpEnd;
 
  36   // private static HashMap keywordMap = null;
 
  44   // row counter for syntax errors:
 
  46   // column counter for syntax errors:
 
  51   //    // current identifier
 
  57   private String stringValue;
 
  59   /** Contains the current expression. */
 
  60   // private StringBuffer expression;
 
  62   private boolean phpMode;
 
  64   //    final static int TokenNameEOF = 0;
 
  65   //    final static int TokenNameERROR = 1;
 
  66   //    final static int TokenNameHTML = 2;
 
  68   //    final static int TokenNameREMAINDER = 30;
 
  69   //    final static int TokenNameNOT = 31;
 
  70   //    final static int TokenNameDOT = 32;
 
  71   //    final static int TokenNameXOR = 33;
 
  72   //    final static int TokenNameDIVIDE = 34;
 
  73   //    final static int TokenNameMULTIPLY = 35;
 
  74   //    final static int TokenNameMINUS = 36;
 
  75   //    final static int TokenNamePLUS = 37;
 
  76   //    final static int TokenNameEQUAL_EQUAL = 38;
 
  77   //    final static int TokenNameNOT_EQUAL = 39;
 
  78   //    final static int TokenNameGREATER = 40;
 
  79   //    final static int TokenNameGREATER_EQUAL = 41;
 
  80   //    final static int TokenNameLESS = 42;
 
  81   //    final static int TokenNameLESS_EQUAL = 43;
 
  82   //    final static int TokenNameAND_AND = 44;
 
  83   //    final static int TokenNameOR_OR = 45;
 
  84   //    // final static int TokenNameHASH = 46; 
 
  85   //    final static int TokenNameCOLON = 47;
 
  86   //    final static int TokenNameDOT_EQUAL = 48;
 
  88   //    final static int TokenNameEQUAL = 49;
 
  89   //    final static int TokenNameMINUS_GREATER = 50; // ->
 
  90   //    final static int TokenNameFOREACH = 51;
 
  91   //    final static int TokenNameAND = 52;
 
  92   //    //final static int TokenNameDOLLARLISTOPEN = 53;
 
  93   //    final static int TokenNameTWIDDLE = 54;
 
  94   //    final static int TokenNameTWIDDLE_EQUAL = 55;
 
  95   //    final static int TokenNameREMAINDER_EQUAL = 56;
 
  96   //    final static int TokenNameXOR_EQUAL = 57;
 
  97   //    final static int TokenNameRIGHT_SHIFT_EQUAL = 58;
 
  98   //    final static int TokenNameLEFT_SHIFT_EQUAL = 59;
 
  99   //    final static int TokenNameAND_EQUAL = 60;
 
 100   //    final static int TokenNameOR_EQUAL = 61;
 
 101   //    final static int TokenNameQUESTION = 62;
 
 102   //    final static int TokenNameCOLON_COLON = 63;
 
 103   //    final static int TokenNameAT = 63;
 
 104   //    // final static int TokenNameHEREDOC = 64;
 
 106   //    final static int TokenNameDOLLAROPEN = 127;
 
 107   //    final static int TokenNameLPAREN = 128;
 
 108   //    final static int TokenNameRPAREN = 129;
 
 109   //    final static int TokenNameLBRACE = 130;
 
 110   //    final static int TokenNameRBRACE = 131;
 
 111   //    final static int TokenNameLBRACKET = 132;
 
 112   //    final static int TokenNameRBRACKET = 133;
 
 113   //    final static int TokenNameCOMMA = 134;
 
 115   //    final static int TokenNameStringLiteral = 136;
 
 116   //    final static int TokenNameIdentifier = 138;
 
 117   //    // final static int TokenNameDIGIT = 139;
 
 118   //    final static int TokenNameSEMICOLON = 140;
 
 119   //    // final static int TokenNameSLOT = 141;
 
 120   //    // final static int TokenNameSLOTSEQUENCE = 142;
 
 121   //    final static int TokenNameMINUS_MINUS = 144;
 
 122   //    final static int TokenNamePLUS_PLUS = 145;
 
 123   //    final static int TokenNamePLUS_EQUAL = 146;
 
 124   //    final static int TokenNameDIVIDE_EQUAL = 147;
 
 125   //    final static int TokenNameMINUS_EQUAL = 148;
 
 126   //    final static int TokenNameMULTIPLY_EQUAL = 149;
 
 127   //    final static int TokenNameVariable = 150;
 
 128   //    final static int TokenNameIntegerLiteral = 151;
 
 129   //    final static int TokenNameDoubleLiteral = 152;
 
 130   //    final static int TokenNameStringInterpolated = 153;
 
 131   //    final static int TokenNameStringConstant = 154;
 
 133   //    final static int TokenNameLEFT_SHIFT = 155;
 
 134   //    final static int TokenNameRIGHT_SHIFT = 156;
 
 135   //    final static int TokenNameEQUAL_EQUAL_EQUAL = 157;
 
 136   //    final static int TokenNameNOT_EQUAL_EQUAL = 158;
 
 137   //    final static int TokenNameOR = 159;
 
 138   //  final static int TokenNameAT = 153; // @
 
 143   public void setFileToParse(IFile fileToParse) {
 
 144     this.currentPHPString = 0;
 
 145     this.fileToParse = fileToParse;
 
 148     this.token = TokenNameEOF;
 
 150     this.initializeScanner();
 
 153    *  ClassDeclaration Constructor.
 
 156    *@param  sess  Description of Parameter
 
 159   public Parser(IFile fileToParse) {
 
 160     //    if (keywordMap == null) {
 
 161     //      keywordMap = new HashMap();
 
 162     //      for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 163     //        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 166     this.currentPHPString = 0;
 
 167     this.fileToParse = fileToParse;
 
 170     this.token = TokenNameEOF;
 
 172     //    this.rowCount = 1;
 
 173     //    this.columnCount = 0;
 
 177     this.initializeScanner();
 
 180   public void initializeScanner() {
 
 181     this.scanner = new Scanner(false, false, false, false);
 
 184    * Create marker for the parse error
 
 186   private void setMarker(String message, int charStart, int charEnd, int errorLevel) throws CoreException {
 
 187     setMarker(fileToParse, message, charStart, charEnd, errorLevel);
 
 191    * This method will throw the SyntaxError.
 
 192    * It will add the good lines and columns to the Error
 
 193    * @param error the error message
 
 194    * @throws SyntaxError the error raised
 
 196   private void throwSyntaxError(String error) {
 
 198     //    if (str.length() < chIndx) {
 
 201     //    // read until end-of-line
 
 203     //    while (str.length() > eol) {
 
 204     //      ch = str.charAt(eol++);
 
 210     //    throw new SyntaxError(
 
 212     //      chIndx - columnCount + 1,
 
 213     //      str.substring(columnCount, eol),
 
 215     throw new SyntaxError(1, 1, "", error);
 
 219    * This method will throw the SyntaxError.
 
 220    * It will add the good lines and columns to the Error
 
 221    * @param error the error message
 
 222    * @throws SyntaxError the error raised
 
 224   private void throwSyntaxError(String error, int startRow) {
 
 225     throw new SyntaxError(startRow, 0, " ", error);
 
 229    *  Method Declaration.
 
 233   //  private void getChar() {
 
 234   //    if (str.length() > chIndx) {
 
 235   //      ch = str.charAt(chIndx++);
 
 240   //    chIndx = str.length() + 1;
 
 242   //    //  token = TokenNameEOF;
 
 247    * gets the next token from input
 
 249   private void getNextToken() throws CoreException {
 
 251       token = scanner.getNextToken();
 
 253         int currentEndPosition = scanner.getCurrentTokenEndPosition();
 
 254         int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
 256         System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
 
 257         System.out.println(scanner.toStringAction(token));
 
 259     } catch (InvalidInputException e) {
 
 260       token = TokenNameERROR;
 
 268    * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
 
 269    * value {@link Parser#TokenNameDOUBLE_NUMBER}<br />
 
 270    * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
 
 271    * value {@link Parser#TokenNameINT_NUMBER}
 
 273   //  private void getNumber() {
 
 274   //    StringBuffer inum = new StringBuffer();
 
 276   //    int numFormat = 10;
 
 278   //    // save first digit
 
 279   //    char firstCh = ch;
 
 283   //    // determine number conversions:
 
 284   //    if (firstCh == '0') {
 
 313   //    if (numFormat == 16) {
 
 314   //      while ((ch >= '0' && ch <= '9')
 
 315   //        || (ch >= 'a' && ch <= 'f')
 
 316   //        || (ch >= 'A' && ch <= 'F')) {
 
 321   //      while ((ch >= '0' && ch <= '9')
 
 325   //        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
 
 326   //          if (ch == '.' && dFlag != ' ') {
 
 329   //          if ((dFlag == 'E') || (dFlag == 'e')) {
 
 335   //          if ((ch == '-') || (ch == '+')) {
 
 348   //      if (dFlag != ' ') {
 
 349   //        doubleNumber = new Double(inum.toString());
 
 350   //        token = TokenNameDoubleLiteral;
 
 353   //        longNumber = Long.valueOf(inum.toString(), numFormat);
 
 354   //        token = TokenNameIntegerLiteral;
 
 358   //    } catch (Throwable e) {
 
 359   //      throwSyntaxError("Number format error: " + inum.toString());
 
 365   //   * @param openChar the opening char ('\'', '"', '`')
 
 366   //   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
 
 367   //   * @param errorMsg the error message in case of parse error in the string
 
 369   //  private void getString(
 
 370   //    final char openChar,
 
 371   //    final int typeString,
 
 372   //    final String errorMsg) {
 
 373   //    StringBuffer sBuffer = new StringBuffer();
 
 374   //    boolean openString = true;
 
 375   //    int startRow = rowCount;
 
 376   //    while (str.length() > chIndx) {
 
 377   //      ch = str.charAt(chIndx++);
 
 379   //        sBuffer.append(ch);
 
 380   //        if (str.length() > chIndx) {
 
 381   //          ch = str.charAt(chIndx++);
 
 382   //          sBuffer.append(ch);
 
 384   //      } else if (ch == openChar) {
 
 385   //        openString = false;
 
 387   //      } else if (ch == '\n') {
 
 389   //        columnCount = chIndx;
 
 391   //        sBuffer.append(ch);
 
 395   //      if (typeString == TokenNameStringConstant) {
 
 396   //        throwSyntaxError(errorMsg, startRow);
 
 398   //        throwSyntaxError(errorMsg);
 
 401   //    token = typeString;
 
 402   //    stringValue = sBuffer.toString();
 
 405   //    public void htmlParserTester(String input) {
 
 406   //            int lineNumber = 1;
 
 407   //            int startLineNumber = 1;
 
 408   //            int startIndex = 0;
 
 411   //            boolean phpMode = false;
 
 412   //            boolean phpFound = false;
 
 414   //            phpList = new ArrayList();
 
 415   //            currentPHPString = 0;
 
 419   //                    while (i < input.length()) {
 
 420   //                            ch = input.charAt(i++);
 
 424   //                            if ((!phpMode) && ch == '<') {
 
 425   //                                    ch2 = input.charAt(i++);
 
 427   //                                            ch2 = input.charAt(i++);
 
 428   //                                            if (Character.isWhitespace(ch2)) {
 
 433   //                                                    startLineNumber = lineNumber;
 
 435   //                                            } else if (ch2 == 'p') {
 
 436   //                                                    ch2 = input.charAt(i++);
 
 438   //                                                            ch2 = input.charAt(i++);
 
 443   //                                                                    startLineNumber = lineNumber;
 
 449   //                                            } else if (ch2 == 'P') {
 
 450   //                                                    ch2 = input.charAt(i++);
 
 452   //                                                            ch2 = input.charAt(i++);
 
 457   //                                                                    startLineNumber = lineNumber;
 
 470   //                                    if (ch == '/' && i < input.length()) {
 
 471   //                                            ch2 = input.charAt(i++);
 
 473   //                                                    while (i < input.length()) {
 
 474   //                                                            ch = input.charAt(i++);
 
 475   //                                                            if (ch == '?' && i < input.length()) {
 
 476   //                                                                    ch2 = input.charAt(i++);
 
 485   //                                                                                            startLineNumber));
 
 489   //                                                            } else if (ch == '\n') {
 
 495   //                                            } else if (ch2 == '*') {
 
 496   //                                                    // multi-line comment
 
 497   //                                                    while (i < input.length()) {
 
 498   //                                                            ch = input.charAt(i++);
 
 501   //                                                            } else if (ch == '*' && i < input.length()) {
 
 502   //                                                                    ch2 = input.charAt(i++);
 
 513   //                                    } else if (ch == '#') {
 
 514   //                                            while (i < input.length()) {
 
 515   //                                                    ch = input.charAt(i++);
 
 516   //                                                    if (ch == '?' && i < input.length()) {
 
 517   //                                                            ch2 = input.charAt(i++);
 
 523   //                                                                                    input.substring(startIndex, i - 2),
 
 524   //                                                                                    startLineNumber));
 
 528   //                                                    } else if (ch == '\n') {
 
 534   //                                    } else if (ch == '"') {
 
 536   //                                            while (i < input.length()) {
 
 537   //                                                    ch = input.charAt(i++);
 
 541   //                                                            ch == '\\' && i < input.length()) { // escape
 
 543   //                                                    } else if (ch == '"') {
 
 548   //                                    } else if (ch == '\'') {
 
 550   //                                            while (i < input.length()) {
 
 551   //                                                    ch = input.charAt(i++);
 
 555   //                                                            ch == '\\' && i < input.length()) { // escape
 
 557   //                                                    } else if (ch == '\'') {
 
 564   //                                    if (ch == '?' && i < input.length()) {
 
 565   //                                            ch2 = input.charAt(i++);
 
 571   //                                                                    input.substring(startIndex, i - 2),
 
 572   //                                                                    startLineNumber));
 
 582   //                                    "No PHP source code found.",
 
 588   //                                            "Open PHP tag at end of file.",
 
 593   //                                                    input.substring(startIndex, i - 2),
 
 594   //                                                    startLineNumber));
 
 596   //                            //        for (int j=0;j<phpList.size();j++) {
 
 597   //                            //          String temp = ((PHPString)phpList.get(j)).getPHPString();
 
 598   //                            //          int startIndx = temp.length()-10;
 
 599   //                            //          if (startIndx<0) {
 
 602   //                            //          System.out.println(temp.substring(startIndx)+"?>");
 
 604   //                            phpParserTester(null, 1);
 
 605   //                            //        PHPString temp;
 
 606   //                            //        for(int j=0;j<phpList.size();j++) {
 
 607   //                            //          temp = (PHPString) phpList.get(j);
 
 608   //                            //          parser.start(temp.getPHPString(), temp.getLineNumber());
 
 611   //            } catch (CoreException e) {
 
 615   public void phpParserTester(String s, int rowCount) throws CoreException {
 
 618       if (phpList.size() != 0) {
 
 619         this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
 
 622     this.token = TokenNameEOF;
 
 624     //    this.rowCount = rowCount;
 
 625     //    this.columnCount = 0;
 
 628     scanner.setSource(s.toCharArray());
 
 629     scanner.setPHPMode(true);
 
 633         if (token != TokenNameEOF && token != TokenNameERROR) {
 
 636         if (token != TokenNameEOF) {
 
 637           if (token == TokenNameERROR) {
 
 638             throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
 
 640           if (token == TokenNameRPAREN) {
 
 641             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
 643           if (token == TokenNameRBRACE) {
 
 644             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
 646           if (token == TokenNameRBRACKET) {
 
 647             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
 650           if (token == TokenNameLPAREN) {
 
 651             throwSyntaxError("Read character '('; end-of-file not reached.");
 
 653           if (token == TokenNameLBRACE) {
 
 654             throwSyntaxError("Read character '{';  end-of-file not reached.");
 
 656           if (token == TokenNameLBRACKET) {
 
 657             throwSyntaxError("Read character '[';  end-of-file not reached.");
 
 660           throwSyntaxError("End-of-file not reached.");
 
 663       } catch (SyntaxError err) {
 
 667           //   setMarker(err.getMessage(), err.getLine(), ERROR);
 
 668           setMarker(err.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
 
 670         // if an error occured,
 
 671         // try to find keywords 'class' or 'function'
 
 672         // to parse the rest of the string
 
 673         while (token != TokenNameEOF && token != TokenNameERROR) {
 
 674           if (token == TokenNameclass || token == TokenNamefunction) {
 
 679         if (token == TokenNameEOF || token == TokenNameERROR) {
 
 688    * Parses a string with php tags
 
 689    * i.e. '<body> <?php phpinfo() ?> </body>'
 
 691   public void parse(String s) throws CoreException {
 
 693     this.token = TokenNameEOF;
 
 695     //    this.rowCount = 1;
 
 696     //    this.columnCount = 0;
 
 698     this.phpMode = false;
 
 699     /* scanner initialization */
 
 700     scanner.setSource(s.toCharArray());
 
 701     scanner.setPHPMode(false);
 
 705         if (token != TokenNameEOF && token != TokenNameERROR) {
 
 708         if (token != TokenNameEOF) {
 
 709           if (token == TokenNameERROR) {
 
 710             throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
 
 712           if (token == TokenNameRPAREN) {
 
 713             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
 715           if (token == TokenNameRBRACE) {
 
 716             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
 718           if (token == TokenNameRBRACKET) {
 
 719             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
 722           if (token == TokenNameLPAREN) {
 
 723             throwSyntaxError("Read character '('; end-of-file not reached.");
 
 725           if (token == TokenNameLBRACE) {
 
 726             throwSyntaxError("Read character '{';  end-of-file not reached.");
 
 728           if (token == TokenNameLBRACKET) {
 
 729             throwSyntaxError("Read character '[';  end-of-file not reached.");
 
 732           throwSyntaxError("End-of-file not reached.");
 
 735       } catch (SyntaxError sytaxErr1) {
 
 736         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
 
 737         setMarker(sytaxErr1.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
 
 739           // if an error occured,
 
 740           // try to find keywords 'class' or 'function'
 
 741           // to parse the rest of the string
 
 742           while (token != TokenNameEOF && token != TokenNameERROR) {
 
 743             if (token == TokenNameclass || token == TokenNamefunction) {
 
 748           if (token == TokenNameEOF || token == TokenNameERROR) {
 
 751         } catch (SyntaxError sytaxErr2) {
 
 752           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
 
 753           setMarker(sytaxErr2.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
 
 761   public PHPOutlineInfo parseInfo(Object parent, String s) {
 
 762     PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
 
 763     //    Stack stack = new Stack();
 
 764     //    stack.push(outlineInfo.getDeclarations());
 
 767     this.token = TokenNameEOF;
 
 769     //    this.rowCount = 1;
 
 770     //    this.columnCount = 0;
 
 772     this.phpMode = false;
 
 773     scanner.setSource(s.toCharArray());
 
 774     scanner.setPHPMode(false);
 
 778       parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
 
 779     } catch (CoreException e) {
 
 784   private boolean isVariable() {
 
 785     return token == TokenNameVariable || token == TokenNamethis;
 
 788   private void parseDeclarations(PHPOutlineInfo outlineInfo, OutlineableWithChildren current, boolean goBack) {
 
 790     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
 
 791     PHPSegmentWithChildren temp;
 
 794     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
 
 796       while (token != TokenNameEOF && token != TokenNameERROR) {
 
 797         if (token == TokenNameVariable) {
 
 798           ident = scanner.getCurrentIdentifierSource();
 
 799           outlineInfo.addVariable(new String(ident));
 
 801         } else if (token == TokenNamevar) {
 
 803           if (token == TokenNameVariable && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
 
 804             ident = scanner.getCurrentIdentifierSource();
 
 805             //substring(1) added because PHPVarDeclaration doesn't need the $ anymore
 
 806             String variableName = new String(ident).substring(1);
 
 807             outlineInfo.addVariable(variableName);
 
 809             if (token != TokenNameSEMICOLON) {
 
 812               ident = scanner.getCurrentTokenSource();
 
 813               if (token > TokenNameKEYWORD) {
 
 814                 current.add(new PHPVarDeclaration(current, variableName,
 
 815                 //                      chIndx - ident.length,
 
 816                 scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 819                   case TokenNameVariable :
 
 821                     current.add(new PHPVarDeclaration(current, variableName,
 
 822                     //                      chIndx - ident.length,
 
 823                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 825                   case TokenNameIdentifier :
 
 826                     current.add(new PHPVarDeclaration(current, variableName,
 
 827                     //                    chIndx - ident.length,
 
 828                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 830                   case TokenNameDoubleLiteral :
 
 831                     current.add(new PHPVarDeclaration(current, variableName + doubleNumber,
 
 832                     //   chIndx - ident.length,
 
 833                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 835                   case TokenNameIntegerLiteral :
 
 836                     current.add(new PHPVarDeclaration(current, variableName,
 
 837                     //                 chIndx - ident.length,
 
 838                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 840                   case TokenNameStringInterpolated :
 
 841                   case TokenNameStringLiteral :
 
 842                     current.add(new PHPVarDeclaration(current, variableName,
 
 843                     //              chIndx - ident.length,
 
 844                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 846                   case TokenNameStringConstant :
 
 847                     current.add(new PHPVarDeclaration(current, variableName,
 
 848                     //   chIndx - ident.length,
 
 849                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
 852                     current.add(new PHPVarDeclaration(current, variableName,
 
 853                     //               chIndx - ident.length
 
 854                     scanner.getCurrentTokenStartPosition()));
 
 860               ident = scanner.getCurrentIdentifierSource();
 
 862               current.add(new PHPVarDeclaration(current, variableName,
 
 863               //          chIndx - ident.length
 
 864               scanner.getCurrentTokenStartPosition()));
 
 867         } else if (token == TokenNamefunction) {
 
 869           if (token == TokenNameAND) {
 
 872           if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
 
 873             ident = scanner.getCurrentIdentifierSource();
 
 874             outlineInfo.addVariable(new String(ident));
 
 875             temp = new PHPFunctionDeclaration(current, new String(ident),
 
 876               // chIndx - ident.length
 
 877   scanner.getCurrentTokenStartPosition());
 
 880             parseDeclarations(outlineInfo, temp, true);
 
 882         } else if (token == TokenNameclass) {
 
 884           if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
 
 885             ident = scanner.getCurrentIdentifierSource();
 
 886             outlineInfo.addVariable(new String(ident));
 
 887             temp = new PHPClassDeclaration(current, new String(ident),
 
 888               //      chIndx - ident.len
 
 889   scanner.getCurrentTokenStartPosition());
 
 894             //skip tokens for classname, extends and others until we have the opening '{'
 
 895             while (token != TokenNameLBRACE && token != TokenNameEOF && token != TokenNameERROR) {
 
 898             parseDeclarations(outlineInfo, temp, true);
 
 901         } else if ((token == TokenNameLBRACE) || (token == TokenNameDOLLAR_LBRACE)) {
 
 904         } else if (token == TokenNameRBRACE) {
 
 907           if (counter == 0 && goBack) {
 
 911           token == TokenNamerequire
 
 912             || token == TokenNamerequire_once
 
 913             || token == TokenNameinclude
 
 914             || token == TokenNameinclude_once) {
 
 915           ident = scanner.getCurrentTokenSource();
 
 918           int startPosition = scanner.getCurrentTokenStartPosition();
 
 920           char[] expr = scanner.getCurrentTokenSource(startPosition);
 
 921           outlineInfo.addVariable(new String(ident));
 
 922           current.add(new PHPReqIncDeclaration(current, new String(ident),
 
 923           //    chIndx - ident.length,
 
 924           startPosition, new String(expr)));
 
 930     } catch (CoreException e) {
 
 931     } catch (SyntaxError sytaxErr) {
 
 933         //  setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
 
 934         setMarker(sytaxErr.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
 
 935       } catch (CoreException e) {
 
 940   private void statementList() throws CoreException {
 
 943       if ((token == TokenNameRBRACE)
 
 944         || (token == TokenNamecase)
 
 945         || (token == TokenNamedefault)
 
 946         || (token == TokenNameelse)
 
 947         || (token == TokenNameelseif)
 
 948         || (token == TokenNameendif)
 
 949         || (token == TokenNameendfor)
 
 950         || (token == TokenNameendforeach)
 
 951         || (token == TokenNameendwhile)
 
 952         || (token == TokenNameendswitch)
 
 953         || (token == TokenNameEOF)
 
 954         || (token == TokenNameERROR)) {
 
 960   private void compoundStatement() throws CoreException {
 
 961     // '{' [statement-list] '}'
 
 962     if (token == TokenNameLBRACE) {
 
 965       throwSyntaxError("'{' expected in compound-statement.");
 
 967     if (token != TokenNameRBRACE) {
 
 970     if (token == TokenNameRBRACE) {
 
 973       throwSyntaxError("'}' expected in compound-statement.");
 
 977   private void statement() throws CoreException {
 
 978     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
 
 979     //  char[] ident = scanner.getCurrentIdentifierSource();
 
 980     //  String keyword = new String(ident);
 
 981     if (token == TokenNameinclude || token == TokenNameinclude_once) {
 
 984       if (token == TokenNameSEMICOLON) {
 
 987         if (token != TokenNameStopPHP) {
 
 988           throwSyntaxError("';' character after 'include' or 'include_once' expected.");
 
 993     } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
 
 997       if (token == TokenNameSEMICOLON) {
 
1000         if (token != TokenNameStopPHP) {
 
1001           throwSyntaxError("';' character after 'require' or 'require_once' expected.");
 
1006     } else if (token == TokenNameif) {
 
1008       if (token == TokenNameLPAREN) {
 
1011         throwSyntaxError("'(' expected after 'if' keyword.");
 
1014       if (token == TokenNameRPAREN) {
 
1017         throwSyntaxError("')' expected after 'if' condition.");
 
1022     } else if (token == TokenNameswitch) {
 
1024       if (token == TokenNameLPAREN) {
 
1027         throwSyntaxError("'(' expected after 'switch' keyword.");
 
1030       if (token == TokenNameRPAREN) {
 
1033         throwSyntaxError("')' expected after 'switch' condition.");
 
1037     } else if (token == TokenNamefor) {
 
1039       if (token == TokenNameLPAREN) {
 
1042         throwSyntaxError("'(' expected after 'for' keyword.");
 
1044       if (token == TokenNameSEMICOLON) {
 
1048         if (token == TokenNameSEMICOLON) {
 
1051           throwSyntaxError("';' expected after 'for'.");
 
1054       if (token == TokenNameSEMICOLON) {
 
1058         if (token == TokenNameSEMICOLON) {
 
1061           throwSyntaxError("';' expected after 'for'.");
 
1064       if (token == TokenNameRPAREN) {
 
1068         if (token == TokenNameRPAREN) {
 
1071           throwSyntaxError("')' expected after 'for'.");
 
1076     } else if (token == TokenNamewhile) {
 
1078       if (token == TokenNameLPAREN) {
 
1081         throwSyntaxError("'(' expected after 'while' keyword.");
 
1084       if (token == TokenNameRPAREN) {
 
1087         throwSyntaxError("')' expected after 'while' condition.");
 
1091     } else if (token == TokenNamedo) {
 
1093       if (token == TokenNameLBRACE) {
 
1096         throwSyntaxError("'{' expected after 'do' keyword.");
 
1098       if (token != TokenNameRBRACE) {
 
1101       if (token == TokenNameRBRACE) {
 
1104         throwSyntaxError("'}' expected after 'do' keyword.");
 
1106       if (token == TokenNamewhile) {
 
1108         if (token == TokenNameLPAREN) {
 
1111           throwSyntaxError("'(' expected after 'while' keyword.");
 
1114         if (token == TokenNameRPAREN) {
 
1117           throwSyntaxError("')' expected after 'while' condition.");
 
1120         throwSyntaxError("'while' expected after 'do' keyword.");
 
1122       if (token == TokenNameSEMICOLON) {
 
1125         if (token != TokenNameStopPHP) {
 
1126           throwSyntaxError("';' expected after do-while statement.");
 
1131     } else if (token == TokenNameforeach) {
 
1133       if (token == TokenNameLPAREN) {
 
1136         throwSyntaxError("'(' expected after 'foreach' keyword.");
 
1139       if (token == TokenNameas) {
 
1142         throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
1145       if (token == TokenNameEQUAL_GREATER) {
 
1149       if (token == TokenNameRPAREN) {
 
1152         throwSyntaxError("')' expected after 'foreach' expression.");
 
1157     } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
 
1159       if (token != TokenNameSEMICOLON) {
 
1162       if (token == TokenNameSEMICOLON) {
 
1165         if (token != TokenNameStopPHP) {
 
1166           throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
 
1172     } else if (token == TokenNameecho) {
 
1175       if (token == TokenNameSEMICOLON) {
 
1178         if (token != TokenNameStopPHP) {
 
1179           throwSyntaxError("';' expected after 'echo' statement.");
 
1184       //    } else if (token == TokenNameprint) {
 
1187       //      if (token == TokenNameSEMICOLON) {
 
1190       //        if (token != TokenNameStopPHP) {
 
1191       //          throwSyntaxError("';' expected after 'print' statement.");
 
1197     } else if (token == TokenNameglobal || token == TokenNamestatic) {
 
1200       if (token == TokenNameSEMICOLON) {
 
1203         if (token != TokenNameStopPHP) {
 
1204           throwSyntaxError("';' expected after 'global' or 'static' statement.");
 
1210       //      } else if (token == TokenNameunset) {
 
1212       //        if (token == TokenNameARGOPEN) {
 
1215       //          throwSyntaxError("'(' expected after 'unset' keyword.");
 
1218       //        if (token == TokenNameARGCLOSE) {
 
1221       //          throwSyntaxError("')' expected after 'unset' statement.");
 
1223       //        if (token == TokenNameSEMICOLON) {
 
1226       //          if (token != TokenNameStopPHP) {
 
1227       //            throwSyntaxError("';' expected after 'unset' statement.");
 
1233       //      } else if (token == TokenNameexit || token == TokenNamedie) {
 
1235       //        if (token != TokenNameSEMICOLON) {
 
1238       //        if (token == TokenNameSEMICOLON) {
 
1241       //          if (token != TokenNameStopPHP) {
 
1242       //            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
 
1248     } else if (token == TokenNamedefine) {
 
1250       if (token == TokenNameLPAREN) {
 
1253         throwSyntaxError("'(' expected after 'define' keyword.");
 
1256       if (token == TokenNameCOMMA) {
 
1259         throwSyntaxError("',' expected after first 'define' constant.");
 
1262       if (token == TokenNameCOMMA) {
 
1266       if (token == TokenNameRPAREN) {
 
1269         throwSyntaxError("')' expected after 'define' statement.");
 
1271       if (token == TokenNameSEMICOLON) {
 
1274         if (token != TokenNameStopPHP) {
 
1275           throwSyntaxError("';' expected after 'define' statement.");
 
1280     } else if (token == TokenNamefunction) {
 
1282       functionDefinition();
 
1284     } else if (token == TokenNameclass) {
 
1290       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
 
1291     } else if (token == TokenNameLBRACE) {
 
1292       // compoundStatement
 
1294       if (token != TokenNameRBRACE) {
 
1297       if (token == TokenNameRBRACE) {
 
1301         throwSyntaxError("'}' expected.");
 
1304       if (token != TokenNameSEMICOLON) {
 
1307       if (token == TokenNameSEMICOLON) {
 
1311         if (token != TokenNameStopPHP && token != TokenNameEOF) {
 
1312           throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
 
1319   private void classDeclarator() throws CoreException {
 
1321     //identifier 'extends' identifier
 
1322     if (token == TokenNameIdentifier) {
 
1324       if (token == TokenNameextends) {
 
1326         if (token == TokenNameIdentifier) {
 
1329           throwSyntaxError("ClassDeclaration name expected after keyword 'extends'.");
 
1333       if (token > TokenNameKEYWORD) {
 
1334         throwSyntaxError("Don't use keyword for class declaration [" + token + "].");
 
1336       throwSyntaxError("ClassDeclaration name expected after keyword 'class'.");
 
1340   private void classBody() throws CoreException {
 
1341     //'{' [class-element-list] '}'
 
1342     if (token == TokenNameLBRACE) {
 
1344       if (token != TokenNameRBRACE) {
 
1347       if (token == TokenNameRBRACE) {
 
1350         throwSyntaxError("'}' expected at end of class body.");
 
1353       throwSyntaxError("'{' expected at start of class body.");
 
1357   private void classElementList() throws CoreException {
 
1360     } while (token == TokenNamefunction || token == TokenNamevar);
 
1363   private void classElement() throws CoreException {
 
1365     //function-definition
 
1366     if (token == TokenNamefunction) {
 
1368       functionDefinition();
 
1369     } else if (token == TokenNamevar) {
 
1373       throwSyntaxError("'function' or 'var' expected.");
 
1377   private void classProperty() throws CoreException {
 
1378     //'var' variable ';'
 
1379     //'var' variable '=' constant ';'
 
1381       if (token == TokenNameVariable) {
 
1383         if (token == TokenNameEQUAL) {
 
1388         if (token == TokenNamethis) {
 
1389           throwSyntaxError("Reserved word '$this' not allowed after keyword 'var'.");
 
1391         throwSyntaxError("Variable expected after keyword 'var'.");
 
1393       if (token != TokenNameCOMMA) {
 
1398     if (token == TokenNameSEMICOLON) {
 
1401       throwSyntaxError("';' expected after variable declaration.");
 
1405   private void functionDefinition() throws CoreException {
 
1406     functionDeclarator();
 
1407     compoundStatement();
 
1410   private void functionDeclarator() throws CoreException {
 
1411     //identifier '(' [parameter-list] ')'
 
1412     if (token == TokenNameAND) {
 
1415     if (token == TokenNameIdentifier) {
 
1417       if (token == TokenNameLPAREN) {
 
1420         throwSyntaxError("'(' expected in function declaration.");
 
1422       if (token != TokenNameRPAREN) {
 
1425       if (token != TokenNameRPAREN) {
 
1426         throwSyntaxError("')' expected in function declaration.");
 
1431       if (token > TokenNameKEYWORD) {
 
1432         throwSyntaxError("Don't use keyword for function declaration [" + token + "].");
 
1434       throwSyntaxError("Function name expected after keyword 'function'.");
 
1438   private void parameterList() throws CoreException {
 
1439     //parameter-declaration
 
1440     //parameter-list ',' parameter-declaration
 
1442       parameterDeclaration();
 
1443       if (token != TokenNameCOMMA) {
 
1450   private void parameterDeclaration() throws CoreException {
 
1452     //variable-reference
 
1453     if (token == TokenNameAND) {
 
1458         throwSyntaxError("Variable expected after reference operator '&'.");
 
1461     //variable '=' constant
 
1462     if (token == TokenNameVariable) {
 
1464       if (token == TokenNameEQUAL) {
 
1470     if (token == TokenNamethis) {
 
1471       throwSyntaxError("Reserved word '$this' not allowed in parameter declaration.");
 
1475   private void labeledStatementList() throws CoreException {
 
1476     if (token != TokenNamecase && token != TokenNamedefault) {
 
1477       throwSyntaxError("'case' or 'default' expected.");
 
1480       if (token == TokenNamecase) {
 
1482         expression(); //constant();
 
1483         if (token == TokenNameCOLON) {
 
1485           if (token == TokenNamecase || token == TokenNamedefault) { // empty case statement ?
 
1489         } else if (token == TokenNameSEMICOLON) {
 
1491           //            "':' expected after 'case' keyword (Found token: "
 
1492           //              + scanner.toStringAction(token)
 
1497             "':' expected after 'case' keyword (Found token: " + scanner.toStringAction(token) + ")",
 
1498             scanner.getCurrentTokenStartPosition(),
 
1499             scanner.getCurrentTokenEndPosition(),
 
1502           if (token == TokenNamecase) { // empty case statement ?
 
1507           throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")");
 
1509       } else { // TokenNamedefault
 
1511         if (token == TokenNameCOLON) {
 
1515           throwSyntaxError("':' character after 'default' expected.");
 
1518     } while (token == TokenNamecase || token == TokenNamedefault);
 
1521   //  public void labeledStatement() {
 
1522   //    if (token == TokenNamecase) {
 
1525   //      if (token == TokenNameDDOT) {
 
1529   //        throwSyntaxError("':' character after 'case' constant expected.");
 
1532   //    } else if (token == TokenNamedefault) {
 
1534   //      if (token == TokenNameDDOT) {
 
1538   //        throwSyntaxError("':' character after 'default' expected.");
 
1544   //  public void expressionStatement() {
 
1547   //  private void inclusionStatement() {
 
1550   //  public void compoundStatement() {
 
1553   //  public void selectionStatement() {
 
1556   //  public void iterationStatement() {
 
1559   //  public void jumpStatement() {
 
1562   //  public void outputStatement() {
 
1565   //  public void scopeStatement() {
 
1568   //  public void flowStatement() {
 
1571   //  public void definitionStatement() {
 
1574   private void ifStatement() throws CoreException {
 
1575     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
 
1576     if (token == TokenNameCOLON) {
 
1578       if (token != TokenNameendif) {
 
1581           case TokenNameelse :
 
1583             if (token == TokenNameCOLON) {
 
1585               if (token != TokenNameendif) {
 
1589               if (token == TokenNameif) { //'else if'
 
1591                 elseifStatementList();
 
1593                 throwSyntaxError("':' expected after 'else'.");
 
1597           case TokenNameelseif :
 
1599             elseifStatementList();
 
1604       if (token != TokenNameendif) {
 
1605         throwSyntaxError("'endif' expected.");
 
1608       if (token != TokenNameSEMICOLON) {
 
1609         throwSyntaxError("';' expected after if-statement.");
 
1613       // statement [else-statement]
 
1615       if (token == TokenNameelseif) {
 
1617         if (token == TokenNameLPAREN) {
 
1620           throwSyntaxError("'(' expected after 'elseif' keyword.");
 
1623         if (token == TokenNameRPAREN) {
 
1626           throwSyntaxError("')' expected after 'elseif' condition.");
 
1629       } else if (token == TokenNameelse) {
 
1636   private void elseifStatementList() throws CoreException {
 
1640         case TokenNameelse :
 
1642           if (token == TokenNameCOLON) {
 
1644             if (token != TokenNameendif) {
 
1649             if (token == TokenNameif) { //'else if'
 
1652               throwSyntaxError("':' expected after 'else'.");
 
1656         case TokenNameelseif :
 
1665   private void elseifStatement() throws CoreException {
 
1666     if (token == TokenNameLPAREN) {
 
1669       if (token != TokenNameRPAREN) {
 
1670         throwSyntaxError("')' expected in else-if-statement.");
 
1673       if (token != TokenNameCOLON) {
 
1674         throwSyntaxError("':' expected in else-if-statement.");
 
1677       if (token != TokenNameendif) {
 
1683   private void switchStatement() throws CoreException {
 
1684     if (token == TokenNameCOLON) {
 
1685       // ':' [labeled-statement-list] 'endswitch' ';'
 
1687       labeledStatementList();
 
1688       if (token != TokenNameendswitch) {
 
1689         throwSyntaxError("'endswitch' expected.");
 
1692       if (token != TokenNameSEMICOLON) {
 
1693         throwSyntaxError("';' expected after switch-statement.");
 
1697       // '{' [labeled-statement-list] '}'
 
1698       if (token != TokenNameLBRACE) {
 
1699         throwSyntaxError("'{' expected in switch statement.");
 
1702       if (token != TokenNameRBRACE) {
 
1703         labeledStatementList();
 
1705       if (token != TokenNameRBRACE) {
 
1706         throwSyntaxError("'}' expected in switch statement.");
 
1713   private void forStatement() throws CoreException {
 
1714     if (token == TokenNameCOLON) {
 
1717       if (token != TokenNameendfor) {
 
1718         throwSyntaxError("'endfor' expected.");
 
1721       if (token != TokenNameSEMICOLON) {
 
1722         throwSyntaxError("';' expected after for-statement.");
 
1730   private void whileStatement() throws CoreException {
 
1731     // ':' statement-list 'endwhile' ';'
 
1732     if (token == TokenNameCOLON) {
 
1735       if (token != TokenNameendwhile) {
 
1736         throwSyntaxError("'endwhile' expected.");
 
1739       if (token != TokenNameSEMICOLON) {
 
1740         throwSyntaxError("';' expected after while-statement.");
 
1748   private void foreachStatement() throws CoreException {
 
1749     if (token == TokenNameCOLON) {
 
1752       if (token != TokenNameendforeach) {
 
1753         throwSyntaxError("'endforeach' expected.");
 
1756       if (token != TokenNameSEMICOLON) {
 
1757         throwSyntaxError("';' expected after foreach-statement.");
 
1765   private void exitStatus() throws CoreException {
 
1766     if (token == TokenNameLPAREN) {
 
1769       throwSyntaxError("'(' expected in 'exit-status'.");
 
1771     if (token != TokenNameRPAREN) {
 
1774     if (token == TokenNameRPAREN) {
 
1777       throwSyntaxError("')' expected after 'exit-status'.");
 
1781   private void expressionList() throws CoreException {
 
1784       if (token == TokenNameCOMMA) {
 
1792   private void expression() throws CoreException {
 
1793     //todo: find a better way to get the expression
 
1794     //    expression = new StringBuffer();
 
1795     //    for (int i = chIndx; i < str.length(); i++) {
 
1796     //      if (str.charAt(i) == ';') {
 
1799     //      expression.append(str.charAt(i));
 
1802     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
 
1805     logicalinclusiveorExpression();
 
1806     //      while (token != TokenNameSEMICOLON) {
 
1812   private void postfixExpression() throws CoreException {
 
1815     boolean castFlag = false;
 
1821       case TokenNamenull :
 
1824       case TokenNamefalse :
 
1827       case TokenNametrue :
 
1830       case TokenNameStringConstant :
 
1833       case TokenNameHEREDOC :
 
1834       case TokenNameStringInterpolated :
 
1835       case TokenNameStringLiteral :
 
1838       case TokenNameLPAREN :
 
1840         if (token == TokenNameIdentifier) {
 
1841           // check if identifier is a type:
 
1842           //    ident = identifier;
 
1843           ident = scanner.getCurrentIdentifierSource();
 
1844           String str = new String(ident).toLowerCase();
 
1845           for (int i = 0; i < PHP_TYPES.length; i++) {
 
1846             if (PHP_TYPES[i].equals(str)) {
 
1853             if (token != TokenNameRPAREN) {
 
1854               throwSyntaxError(") expected after cast-type '" + str + "'.");
 
1864         if (token != TokenNameRPAREN) {
 
1865           throwSyntaxError(") expected in postfix-expression.");
 
1869       case TokenNameDoubleLiteral :
 
1872       case TokenNameIntegerLiteral :
 
1875       case TokenNameDOLLAR_LBRACE :
 
1878         if (token != TokenNameRBRACE) {
 
1879           throwSyntaxError("'}' expected after indirect variable token '${'.");
 
1883       case TokenNameVariable :
 
1884       case TokenNamethis :
 
1885         ident = scanner.getCurrentIdentifierSource();
 
1887         if (token == TokenNameLBRACE) {
 
1890           if (token != TokenNameRBRACE) {
 
1891             throwSyntaxError("'}' expected after variable '" + new String(ident) + "' in variable-expression.");
 
1894         } else if (token == TokenNameLPAREN) {
 
1896           if (token != TokenNameRPAREN) {
 
1898             if (token != TokenNameRPAREN) {
 
1899               throwSyntaxError("')' expected after variable '" + new String(ident) + "' in postfix-expression.");
 
1905       case TokenNameIdentifier :
 
1906         ident = scanner.getCurrentIdentifierSource();
 
1908         if (token == TokenNameLPAREN) {
 
1910           if (token != TokenNameRPAREN) {
 
1912             if (token != TokenNameRPAREN) {
 
1914                 "')' expected after identifier '"
 
1916                   + "' in postfix-expression."
 
1918                   + scanner.toStringAction(token)
 
1925       case TokenNameprint :
 
1928         //        if (token == TokenNameSEMICOLON) {
 
1931         //          if (token != TokenNameStopPHP) {
 
1932         //            throwSyntaxError("';' expected after 'print' statement.");
 
1937       case TokenNamelist :
 
1939         if (token == TokenNameLPAREN) {
 
1941           if (token == TokenNameCOMMA) {
 
1945           if (token != TokenNameRPAREN) {
 
1946             throwSyntaxError("')' expected after 'list' keyword.");
 
1949           //          if (token == TokenNameSET) {
 
1951           //            logicalinclusiveorExpression();
 
1954           throwSyntaxError("'(' expected after 'list' keyword.");
 
1957         //      case TokenNameexit :
 
1959         //        if (token != TokenNameSEMICOLON) {
 
1962         //        if (token == TokenNameSEMICOLON) {
 
1965         //          if (token != TokenNameStopPHP) {
 
1966         //            throwSyntaxError("';' expected after 'exit' expression.");
 
1971         //      case TokenNamedie :
 
1973         //        if (token != TokenNameSEMICOLON) {
 
1976         //        if (token == TokenNameSEMICOLON) {
 
1979         //          if (token != TokenNameStopPHP) {
 
1980         //            throwSyntaxError("';' expected after 'die' expression.");
 
1985         //      case TokenNamearray :
 
1987         //        if (token == TokenNameARGOPEN) {
 
1989         //          if (token == TokenNameCOMMA) {
 
1992         //          expressionList();
 
1993         //          if (token != TokenNameARGCLOSE) {
 
1994         //            throwSyntaxError("')' expected after 'list' keyword.");
 
1997         //          if (token == TokenNameSET) {
 
1999         //            logicalinclusiveorExpression();
 
2002         //          throwSyntaxError("'(' expected after 'list' keyword.");
 
2006     boolean while_flag = true;
 
2009         case TokenNameLBRACKET :
 
2012           if (token != TokenNameRBRACKET) {
 
2013             throwSyntaxError("] expected in postfix-expression.");
 
2017         case TokenNameCOLON_COLON : // ::
 
2018         case TokenNameMINUS_GREATER : // ->
 
2020           if (token > TokenNameKEYWORD) {
 
2021             ident = scanner.getCurrentIdentifierSource();
 
2023             //              "Avoid using keyword '"
 
2024             //                + new String(ident)
 
2025             //                + "' as variable name.",
 
2029               "Avoid using keyword '" + new String(ident) + "' as variable name.",
 
2030               scanner.getCurrentTokenStartPosition(),
 
2031               scanner.getCurrentTokenEndPosition(),
 
2035             case TokenNameVariable :
 
2036               ident = scanner.getCurrentIdentifierSource();
 
2038               //              if (token == TokenNameARGOPEN) {
 
2040               //                expressionList();
 
2041               //                if (token != TokenNameARGCLOSE) {
 
2042               //                  throwSyntaxError(") expected after variable '" + ident + "'.");
 
2047             case TokenNameIdentifier :
 
2048               //ident = scanner.getCurrentIdentifierSource();
 
2051             case TokenNameLBRACE :
 
2054               if (token != TokenNameRBRACE) {
 
2055                 throwSyntaxError("} expected in postfix-expression.");
 
2060               throwSyntaxError("Syntax error after '->' token.");
 
2061           } while (token == TokenNameLBRACKET || token == TokenNameLPAREN || token == TokenNameLBRACE) {
 
2062               if (token == TokenNameLBRACKET) {
 
2065                 if (token != TokenNameRBRACKET) {
 
2066                   throwSyntaxError("] expected after '->'.");
 
2069               } else if (token == TokenNameLPAREN) {
 
2072                 if (token != TokenNameRPAREN) {
 
2073                   throwSyntaxError(") expected after '->'.");
 
2076               } else if (token == TokenNameLBRACE) {
 
2079                 if (token != TokenNameRBRACE) {
 
2080                   throwSyntaxError("} expected after '->'.");
 
2086         case TokenNamePLUS_PLUS :
 
2089         case TokenNameMINUS_MINUS :
 
2100   private void unaryExpression() throws CoreException {
 
2102       case TokenNamePLUS_PLUS :
 
2106       case TokenNameMINUS_MINUS :
 
2110         // '@' '&' '*' '+' '-' '~' '!'
 
2113         if (token == TokenNameinclude
 
2114           || token == TokenNameinclude_once
 
2115           || token == TokenNamerequire
 
2116           || token == TokenNamerequire_once) {
 
2119           postfixExpression(); //  castExpression();
 
2126       case TokenNameMULTIPLY :
 
2130       case TokenNamePLUS :
 
2134       case TokenNameMINUS :
 
2138       case TokenNameTWIDDLE :
 
2147         postfixExpression();
 
2151   private void castExpression() throws CoreException {
 
2152     //    if (token == TokenNameARGOPEN) {
 
2155     //      if (token != TokenNameARGCLOSE) {
 
2156     //        throwSyntaxError(") expected after cast-expression.");
 
2163   private void assignExpression() throws CoreException {
 
2165     if (token == TokenNameEQUAL) { // =
 
2167       logicalinclusiveorExpression();
 
2168     } else if (token == TokenNameDOT_EQUAL) { // .=
 
2170       logicalinclusiveorExpression();
 
2171     } else if (token == TokenNameEQUAL_GREATER) { // =>
 
2173       logicalinclusiveorExpression();
 
2174     } else if (token == TokenNamePLUS_EQUAL) { // +=
 
2176       logicalinclusiveorExpression();
 
2177     } else if (token == TokenNameMINUS_EQUAL) { // -=
 
2179       logicalinclusiveorExpression();
 
2180     } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
 
2182       logicalinclusiveorExpression();
 
2183     } else if (token == TokenNameDIVIDE_EQUAL) { // *=
 
2185       logicalinclusiveorExpression();
 
2186     } else if (token == TokenNameREMAINDER_EQUAL) { // %=
 
2188       logicalinclusiveorExpression();
 
2189     } else if (token == TokenNameAND_EQUAL) { // &=
 
2191       logicalinclusiveorExpression();
 
2192     } else if (token == TokenNameOR_EQUAL) { // |=
 
2194       logicalinclusiveorExpression();
 
2195     } else if (token == TokenNameXOR_EQUAL) { // ^=
 
2197       logicalinclusiveorExpression();
 
2198     } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
 
2200       logicalinclusiveorExpression();
 
2201     } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
 
2203       logicalinclusiveorExpression();
 
2204     } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
 
2206       logicalinclusiveorExpression();
 
2210   private void multiplicativeExpression() throws CoreException {
 
2213       if (token != TokenNameMULTIPLY && token != TokenNameDIVIDE && token != TokenNameREMAINDER) {
 
2220   private void concatenationExpression() throws CoreException {
 
2222       multiplicativeExpression();
 
2223       if (token != TokenNameDOT) {
 
2230   private void additiveExpression() throws CoreException {
 
2232       concatenationExpression();
 
2233       if (token != TokenNamePLUS && token != TokenNameMINUS) {
 
2240   private void shiftExpression() throws CoreException {
 
2242       additiveExpression();
 
2243       if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
 
2250   private void relationalExpression() throws CoreException {
 
2253       if (token != TokenNameLESS && token != TokenNameGREATER && token != TokenNameLESS_EQUAL && token != TokenNameGREATER_EQUAL) {
 
2260   private void identicalExpression() throws CoreException {
 
2262       relationalExpression();
 
2263       if (token != TokenNameEQUAL_EQUAL_EQUAL && token != TokenNameNOT_EQUAL_EQUAL) {
 
2270   private void equalityExpression() throws CoreException {
 
2272       identicalExpression();
 
2273       if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
 
2280   private void ternaryExpression() throws CoreException {
 
2281     equalityExpression();
 
2282     if (token == TokenNameQUESTION) {
 
2285       if (token == TokenNameCOLON) {
 
2289         throwSyntaxError("':' expected in ternary operator '? :'.");
 
2294   private void andExpression() throws CoreException {
 
2296       ternaryExpression();
 
2297       if (token != TokenNameAND) {
 
2304   private void exclusiveorExpression() throws CoreException {
 
2307       if (token != TokenNameXOR) {
 
2314   private void inclusiveorExpression() throws CoreException {
 
2316       exclusiveorExpression();
 
2317       if (token != TokenNameOR) {
 
2324   private void booleanandExpression() throws CoreException {
 
2326       inclusiveorExpression();
 
2327       if (token != TokenNameAND_AND) {
 
2334   private void booleanorExpression() throws CoreException {
 
2336       booleanandExpression();
 
2337       if (token != TokenNameOR_OR) {
 
2344   private void logicalandExpression() throws CoreException {
 
2346       booleanorExpression();
 
2347       if (token != TokenNameAND) {
 
2354   private void logicalexclusiveorExpression() throws CoreException {
 
2356       logicalandExpression();
 
2357       if (token != TokenNameXOR) {
 
2364   private void logicalinclusiveorExpression() throws CoreException {
 
2366       logicalexclusiveorExpression();
 
2367       if (token != TokenNameOR) {
 
2374   //  public void assignmentExpression() {
 
2375   //    if (token == TokenNameVARIABLE) {
 
2377   //      if (token == TokenNameSET) {
 
2379   //        logicalinclusiveorExpression();
 
2382   //      logicalinclusiveorExpression();
 
2386   private void variableList() throws CoreException {
 
2389       if (token == TokenNameCOMMA) {
 
2397   private void variable() throws CoreException {
 
2398     if (token == TokenNameDOLLAR_LBRACE) {
 
2402       if (token != TokenNameRBRACE) {
 
2403         throwSyntaxError("'}' expected after indirect variable token '${'.");
 
2407       if (token == TokenNameVariable) {
 
2409         if (token == TokenNameLBRACKET) {
 
2412           if (token != TokenNameRBRACKET) {
 
2413             throwSyntaxError("']' expected in variable-list.");
 
2416         } else if (token == TokenNameEQUAL) {
 
2421         throwSyntaxError("$-variable expected in variable-list.");
 
2427    * It will look for a value (after a '=' for example)
 
2428    * @throws CoreException
 
2430   private void constant() throws CoreException {
 
2433       case TokenNamePLUS :
 
2436           case TokenNameDoubleLiteral :
 
2439           case TokenNameIntegerLiteral :
 
2443             throwSyntaxError("Constant expected after '+' presign.");
 
2446       case TokenNameMINUS :
 
2449           case TokenNameDoubleLiteral :
 
2452           case TokenNameIntegerLiteral :
 
2456             throwSyntaxError("Constant expected after '-' presign.");
 
2459       case TokenNamenull :
 
2462       case TokenNamefalse :
 
2465       case TokenNametrue :
 
2468       case TokenNameIdentifier :
 
2469         //   ident = identifier;
 
2470         char[] ident = scanner.getCurrentIdentifierSource();
 
2472         if (token == TokenNameLPAREN) {
 
2474           if (token != TokenNameRPAREN) {
 
2476             if (token != TokenNameRPAREN) {
 
2477               throwSyntaxError("')' expected after identifier '" + new String(ident) + "' in postfix-expression.");
 
2483       case TokenNameStringLiteral :
 
2486       case TokenNameStringConstant :
 
2489       case TokenNameStringInterpolated :
 
2492       case TokenNameDoubleLiteral :
 
2495       case TokenNameIntegerLiteral :
 
2499         throwSyntaxError("Constant expected.");