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;
 
  14 import java.util.Hashtable;
 
  16 import net.sourceforge.phpdt.core.compiler.*;
 
  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.resources.IMarker;
 
  22 import org.eclipse.core.runtime.CoreException;
 
  23 import org.eclipse.jface.preference.IPreferenceStore;
 
  24 import org.eclipse.ui.texteditor.MarkerUtilities;
 
  25 import test.PHPParserSuperclass;
 
  27 public class Parser extends PHPParserSuperclass implements ITerminalSymbols {
 
  30   public Scanner scanner;
 
  32   private IFile fileToParse;
 
  33   private ArrayList phpList;
 
  35   private int currentPHPString;
 
  36   private boolean phpEnd;
 
  38   // private static HashMap keywordMap = null;
 
  46   // row counter for syntax errors:
 
  48   // column counter for syntax errors:
 
  53   //    // current identifier
 
  59   private String stringValue;
 
  61   /** Contains the current expression. */
 
  62   // private StringBuffer expression;
 
  64   private boolean phpMode;
 
  66   //    final static int TokenNameEOF = 0;
 
  67   //    final static int TokenNameERROR = 1;
 
  68   //    final static int TokenNameHTML = 2;
 
  70   //    final static int TokenNameREMAINDER = 30;
 
  71   //    final static int TokenNameNOT = 31;
 
  72   //    final static int TokenNameDOT = 32;
 
  73   //    final static int TokenNameXOR = 33;
 
  74   //    final static int TokenNameDIVIDE = 34;
 
  75   //    final static int TokenNameMULTIPLY = 35;
 
  76   //    final static int TokenNameMINUS = 36;
 
  77   //    final static int TokenNamePLUS = 37;
 
  78   //    final static int TokenNameEQUAL_EQUAL = 38;
 
  79   //    final static int TokenNameNOT_EQUAL = 39;
 
  80   //    final static int TokenNameGREATER = 40;
 
  81   //    final static int TokenNameGREATER_EQUAL = 41;
 
  82   //    final static int TokenNameLESS = 42;
 
  83   //    final static int TokenNameLESS_EQUAL = 43;
 
  84   //    final static int TokenNameAND_AND = 44;
 
  85   //    final static int TokenNameOR_OR = 45;
 
  86   //    // final static int TokenNameHASH = 46; 
 
  87   //    final static int TokenNameCOLON = 47;
 
  88   //    final static int TokenNameDOT_EQUAL = 48;
 
  90   //    final static int TokenNameEQUAL = 49;
 
  91   //    final static int TokenNameMINUS_GREATER = 50; // ->
 
  92   //    final static int TokenNameFOREACH = 51;
 
  93   //    final static int TokenNameAND = 52;
 
  94   //    //final static int TokenNameDOLLARLISTOPEN = 53;
 
  95   //    final static int TokenNameTWIDDLE = 54;
 
  96   //    final static int TokenNameTWIDDLE_EQUAL = 55;
 
  97   //    final static int TokenNameREMAINDER_EQUAL = 56;
 
  98   //    final static int TokenNameXOR_EQUAL = 57;
 
  99   //    final static int TokenNameRIGHT_SHIFT_EQUAL = 58;
 
 100   //    final static int TokenNameLEFT_SHIFT_EQUAL = 59;
 
 101   //    final static int TokenNameAND_EQUAL = 60;
 
 102   //    final static int TokenNameOR_EQUAL = 61;
 
 103   //    final static int TokenNameQUESTION = 62;
 
 104   //    final static int TokenNameCOLON_COLON = 63;
 
 105   //    final static int TokenNameAT = 63;
 
 106   //    // final static int TokenNameHEREDOC = 64;
 
 108   //    final static int TokenNameDOLLAROPEN = 127;
 
 109   //    final static int TokenNameLPAREN = 128;
 
 110   //    final static int TokenNameRPAREN = 129;
 
 111   //    final static int TokenNameLBRACE = 130;
 
 112   //    final static int TokenNameRBRACE = 131;
 
 113   //    final static int TokenNameLBRACKET = 132;
 
 114   //    final static int TokenNameRBRACKET = 133;
 
 115   //    final static int TokenNameCOMMA = 134;
 
 117   //    final static int TokenNameStringLiteral = 136;
 
 118   //    final static int TokenNameIdentifier = 138;
 
 119   //    // final static int TokenNameDIGIT = 139;
 
 120   //    final static int TokenNameSEMICOLON = 140;
 
 121   //    // final static int TokenNameSLOT = 141;
 
 122   //    // final static int TokenNameSLOTSEQUENCE = 142;
 
 123   //    final static int TokenNameMINUS_MINUS = 144;
 
 124   //    final static int TokenNamePLUS_PLUS = 145;
 
 125   //    final static int TokenNamePLUS_EQUAL = 146;
 
 126   //    final static int TokenNameDIVIDE_EQUAL = 147;
 
 127   //    final static int TokenNameMINUS_EQUAL = 148;
 
 128   //    final static int TokenNameMULTIPLY_EQUAL = 149;
 
 129   //    final static int TokenNameVariable = 150;
 
 130   //    final static int TokenNameIntegerLiteral = 151;
 
 131   //    final static int TokenNameDoubleLiteral = 152;
 
 132   //    final static int TokenNameStringInterpolated = 153;
 
 133   //    final static int TokenNameStringConstant = 154;
 
 135   //    final static int TokenNameLEFT_SHIFT = 155;
 
 136   //    final static int TokenNameRIGHT_SHIFT = 156;
 
 137   //    final static int TokenNameEQUAL_EQUAL_EQUAL = 157;
 
 138   //    final static int TokenNameNOT_EQUAL_EQUAL = 158;
 
 139   //    final static int TokenNameOR = 159;
 
 140   //  final static int TokenNameAT = 153; // @
 
 145   public void setFileToParse(IFile fileToParse) {
 
 146     this.currentPHPString = 0;
 
 147     this.fileToParse = fileToParse;
 
 150     this.token = TokenNameEOF;
 
 152     this.initializeScanner();
 
 158    *@param  sess  Description of Parameter
 
 161   public Parser(IFile fileToParse) {
 
 162     //    if (keywordMap == null) {
 
 163     //      keywordMap = new HashMap();
 
 164     //      for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 165     //        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 168     this.currentPHPString = 0;
 
 169     this.fileToParse = fileToParse;
 
 172     this.token = TokenNameEOF;
 
 174     //    this.rowCount = 1;
 
 175     //    this.columnCount = 0;
 
 179     this.initializeScanner();
 
 182   public void initializeScanner() {
 
 183     this.scanner = new Scanner(false, false, false, false);
 
 186    * Create marker for the parse error
 
 188   private void setMarker(
 
 193     throws CoreException {
 
 194     setMarker(fileToParse, message, charStart, charEnd, errorLevel);
 
 198    * This method will throw the SyntaxError.
 
 199    * It will add the good lines and columns to the Error
 
 200    * @param error the error message
 
 201    * @throws SyntaxError the error raised
 
 203   private void throwSyntaxError(String error) {
 
 205     //    if (str.length() < chIndx) {
 
 208     //    // read until end-of-line
 
 210     //    while (str.length() > eol) {
 
 211     //      ch = str.charAt(eol++);
 
 217     //    throw new SyntaxError(
 
 219     //      chIndx - columnCount + 1,
 
 220     //      str.substring(columnCount, eol),
 
 222     throw new SyntaxError(1, 1, "", error);
 
 226    * This method will throw the SyntaxError.
 
 227    * It will add the good lines and columns to the Error
 
 228    * @param error the error message
 
 229    * @throws SyntaxError the error raised
 
 231   private void throwSyntaxError(String error, int startRow) {
 
 232     throw new SyntaxError(startRow, 0, " ", error);
 
 236    *  Method Declaration.
 
 240   //  private void getChar() {
 
 241   //    if (str.length() > chIndx) {
 
 242   //      ch = str.charAt(chIndx++);
 
 247   //    chIndx = str.length() + 1;
 
 249   //    //  token = TokenNameEOF;
 
 254    * gets the next token from input
 
 256   private void getNextToken() throws CoreException {
 
 258       token = scanner.getNextToken();
 
 260         int currentEndPosition = scanner.getCurrentTokenEndPosition();
 
 261         int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
 264           currentStartPosition + "," + currentEndPosition + ": ");
 
 265         System.out.println(scanner.toStringAction(token));
 
 267     } catch (InvalidInputException e) {
 
 268       token = TokenNameERROR;
 
 272     //          boolean phpFound = false;
 
 279     //                          while (str.length() > chIndx) {
 
 280     //                                  token = TokenNameERROR;
 
 281     //                                  ch = str.charAt(chIndx++);
 
 287     //                                          ch2 = str.charAt(chIndx++);
 
 289     //                                                  ch2 = str.charAt(chIndx++);
 
 290     //                                                  if (Character.isWhitespace(ch2)) {
 
 295     //                                                  } else if (ch2 == 'p' || ch2 == 'P') {
 
 296     //                                                          ch2 = str.charAt(chIndx++);
 
 297     //                                                          if (ch2 == 'h' || ch2 == 'H') {
 
 298     //                                                                  ch2 = str.charAt(chIndx++);
 
 299     //                                                                  if (ch2 == 'p' || ch2 == 'P') {
 
 317     //                          while (str.length() > chIndx) {
 
 318     //                                  ch = str.charAt(chIndx++);
 
 319     //                                  token = TokenNameERROR;
 
 322     //                                          columnCount = chIndx;
 
 323     //                                          continue; // while loop
 
 325     //                                  if (str.length() == chIndx) {
 
 328     //                                  if (!Character.isWhitespace(ch)) {
 
 330     //                                                  if (str.length() > chIndx) {
 
 331     //                                                          if (str.charAt(chIndx) == '{') {
 
 333     //                                                                  token = TokenNameDOLLAROPEN;
 
 340     //                                          if ((ch >= 'a' && ch <= 'z')
 
 341     //                                                  || (ch >= 'A' && ch <= 'Z')
 
 347     //                                          if (ch >= '0' && ch <= '9') {
 
 352     //                                                  if (str.length() > chIndx) {
 
 353     //                                                          if (str.charAt(chIndx) == '/') {
 
 356     //                                                                  // read comment until end of line:
 
 357     //                                                                  while ((str.length() > chIndx)
 
 358     //                                                                          && (ch != '\n')) {
 
 359     //                                                                          ch = str.charAt(chIndx++);
 
 361     //                                                                                  ch2 = str.charAt(chIndx);
 
 364     //                                                                                          token = TokenNameHTML;
 
 375     //                                                          } else if (str.charAt(chIndx) == '*') {
 
 377     //                                                                  // multi line comment:
 
 378     //                                                                  while (str.length() > chIndx) {
 
 379     //                                                                          if (str.charAt(chIndx) == '*'
 
 380     //                                                                                  && (str.length() > (chIndx + 1))
 
 381     //                                                                                  && str.charAt(chIndx + 1) == '/') {
 
 385     //                                                                          ch = str.charAt(chIndx++);
 
 388     //                                                                                  columnCount = chIndx;
 
 394     //                                          } else if (ch == '#') {
 
 395     //                                                  // read comment until end of line:
 
 396     //                                                  while ((str.length() > chIndx) && (ch != '\n')) {
 
 397     //                                                          ch = str.charAt(chIndx++);
 
 399     //                                                                  ch2 = str.charAt(chIndx);
 
 402     //                                                                          token = TokenNameHTML;
 
 413     //                                          } else if (ch == '"') {
 
 416     //                                                          TokenNameStringInterpolated,
 
 417     //                                                          "Open string character '\"' at end of file.");
 
 419     //                                          } else if (ch == '\'') {
 
 422     //                                                          TokenNameStringConstant,
 
 423     //                                                          "Open string character \"'\" at end of file.");
 
 425     //                                          } else if (ch == '`') {
 
 428     //                                                          TokenNameStringConstant,
 
 429     //                                                          "Open string character \"`\" at end of file.");
 
 431     //                                                          "Other string delimiters prefered (found \"`\").",
 
 440     //                                                          token = TokenNameLPAREN;
 
 444     //                                                          token = TokenNameRPAREN;
 
 448     //                                                          token = TokenNameLBRACE;
 
 452     //                                                          token = TokenNameRBRACE;
 
 456     //                                                          token = TokenNameLBRACKET;
 
 460     //                                                          token = TokenNameRBRACKET;
 
 464     //                                                          token = TokenNameCOMMA;
 
 468     //                                                          token = TokenNameQUESTION;
 
 469     //                                                          if (str.length() > chIndx) {
 
 470     //                                                                  if (str.charAt(chIndx) == '>') {
 
 472     //                                                                          token = TokenNameHTML;
 
 482     //                                                          token = TokenNameAT;
 
 485     //                                                          token = TokenNameTWIDDLE;
 
 486     //                                                          if (str.length() > chIndx) {
 
 487     //                                                                  if (str.charAt(chIndx) == '=') {
 
 489     //                                                                          token = TokenNameTWIDDLE_EQUAL;
 
 496     //                                                          token = TokenNameDOT;
 
 497     //                                                          if (str.length() > chIndx) {
 
 498     //                                                                  if (str.charAt(chIndx) == '=') {
 
 500     //                                                                          token = TokenNameDOT_EQUAL;
 
 508     //                                                          token = TokenNameStringLiteral;
 
 512     //                                                          token = TokenNameREMAINDER;
 
 513     //                                                          if (str.length() > chIndx) {
 
 514     //                                                                  if (str.charAt(chIndx) == '=') {
 
 516     //                                                                          token = TokenNameREMAINDER_EQUAL;
 
 523     //                                                          token = TokenNameSEMICOLON;
 
 527     //                                                          token = TokenNameXOR;
 
 528     //                                                          if (str.length() > chIndx) {
 
 529     //                                                                  if (str.charAt(chIndx) == '=') {
 
 531     //                                                                          token = TokenNameXOR_EQUAL;
 
 538     //                                                          token = TokenNameDIVIDE;
 
 540     //                                                          if (str.length() > chIndx) {
 
 541     //                                                                  if (str.charAt(chIndx) == '=') {
 
 543     //                                                                          token = TokenNameDIVIDE_EQUAL;
 
 551     //                                                          token = TokenNameMULTIPLY;
 
 552     //                                                          if (str.length() > chIndx) {
 
 553     //                                                                  if (str.charAt(chIndx) == '*') {
 
 555     //                                                                          token = TokenNameXOR;
 
 559     //                                                                  if (str.charAt(chIndx) == '=') {
 
 561     //                                                                          token = TokenNameMULTIPLY_EQUAL;
 
 569     //                                                          token = TokenNamePLUS;
 
 570     //                                                          if (str.length() > chIndx) {
 
 571     //                                                                  if (str.charAt(chIndx) == '+') {
 
 573     //                                                                          token = TokenNamePLUS_PLUS;
 
 577     //                                                                  if (str.charAt(chIndx) == '=') {
 
 579     //                                                                          token = TokenNamePLUS_EQUAL;
 
 586     //                                                          token = TokenNameMINUS;
 
 587     //                                                          if (str.length() > chIndx) {
 
 588     //                                                                  if (str.charAt(chIndx) == '-') {
 
 590     //                                                                          token = TokenNameMINUS_MINUS;
 
 594     //                                                                  if (str.charAt(chIndx) == '=') {
 
 596     //                                                                          token = TokenNameMINUS_EQUAL;
 
 600     //                                                                  if (str.charAt(chIndx) == '>') {
 
 602     //                                                                          token = TokenNameMINUS_GREATER;
 
 610     //                                                          token = TokenNameEQUAL;
 
 612     //                                                          if (str.length() > chIndx) {
 
 613     //                                                                  ch = str.charAt(chIndx);
 
 617     //                                                                          token = TokenNameEQUAL_EQUAL;
 
 618     //                                                                          if (str.length() > chIndx) {
 
 619     //                                                                                  ch = str.charAt(chIndx);
 
 624     //                                                                                                  TokenNameEQUAL_EQUAL_EQUAL;
 
 631     //                                                                          token = TokenNameEQUAL_GREATER;
 
 639     //                                                          token = TokenNameNOT;
 
 641     //                                                          if (str.length() > chIndx) {
 
 642     //                                                                  if (str.charAt(chIndx) == '=') {
 
 644     //                                                                          token = TokenNameNOT_EQUAL;
 
 645     //                                                                          if (str.length() > chIndx) {
 
 646     //                                                                                  ch = str.charAt(chIndx);
 
 651     //                                                                                                  TokenNameNOT_EQUAL_EQUAL;
 
 660     //                                                          token = TokenNameGREATER;
 
 662     //                                                          if (str.length() > chIndx) {
 
 663     //                                                                  if (str.charAt(chIndx) == '=') {
 
 665     //                                                                          token = TokenNameGREATER_EQUAL;
 
 668     //                                                                  if (str.charAt(chIndx) == '>') {
 
 670     //                                                                          token = TokenNameRIGHT_SHIFT;
 
 671     //                                                                          if (str.length() > chIndx) {
 
 672     //                                                                                  if (str.charAt(chIndx) == '=') {
 
 675     //                                                                                                  TokenNameRIGHT_SHIFT_EQUAL;
 
 685     //                                                          token = TokenNameLESS;
 
 687     //                                                          if (str.length() > chIndx) {
 
 688     //                                                                  if (str.charAt(chIndx) == '=') {
 
 690     //                                                                          token = TokenNameLESS_EQUAL;
 
 694     //                                                                  if (str.charAt(chIndx) == '<') {
 
 696     //                                                                          token = TokenNameLEFT_SHIFT;
 
 697     //                                                                          if (str.charAt(chIndx) == '<') {
 
 699     //                                                                                  int startRow = rowCount;
 
 700     //                                                                                  if (str.length() > chIndx) {
 
 702     //                                                                                          ch = str.charAt(++chIndx);
 
 703     //                                                                                          if ((ch >= 'a' && ch <= 'z')
 
 704     //                                                                                                  || (ch >= 'A' && ch <= 'Z')
 
 709     //                                                                                                          TokenNameStringConstant;
 
 710     //                                                                                                  while (str.length()
 
 726     //                                                                                                                                  .equals(identifier)) {
 
 738     //                                                                                          "Open heredoc syntax after operator '<<<'.",
 
 740     //                                                                          } else if (str.charAt(chIndx) == '=') {
 
 742     //                                                                                  token = TokenNameLEFT_SHIFT_EQUAL;
 
 752     //                                                          token = TokenNameOR;
 
 754     //                                                          if (str.length() > chIndx) {
 
 755     //                                                                  if (str.charAt(chIndx) == '|') {
 
 757     //                                                                          token = TokenNameOR_OR;
 
 760     //                                                                  if (str.charAt(chIndx) == '=') {
 
 762     //                                                                          token = TokenNameOR_EQUAL;
 
 769     //                                                          token = TokenNameAND;
 
 770     //                                                          if (str.length() > chIndx) {
 
 771     //                                                                  if (str.charAt(chIndx) == '&') {
 
 773     //                                                                          token = TokenNameAND_AND;
 
 776     //                                                                  if (str.charAt(chIndx) == '=') {
 
 778     //                                                                          token = TokenNameAND_EQUAL;
 
 786     //                                                          token = TokenNameCOLON;
 
 787     //                                                          if (str.length() > chIndx) {
 
 788     //                                                                  if (str.charAt(chIndx) == ':') {
 
 790     //                                                                          token = TokenNameCOLON_COLON;
 
 795     //                                                          //                token = TokenNameHASH;
 
 799     //                                                          //            token = TokenNameAT;
 
 804     //                                                                  "unexpected character: '" + ch + "'");
 
 807     //                                          if (token == TokenNameERROR) {
 
 808     //                                                  throwSyntaxError("token not found");
 
 815     //          } catch (StringIndexOutOfBoundsException e) {
 
 816     //                  // catched from charAt
 
 819     //          chIndx = str.length() + 1;
 
 821     //          token = TokenNameEOF;
 
 824     //          //    if (phpList != null) {
 
 825     //          //      if (currentPHPString < phpList.size()) {
 
 826     //          //        token = TokenNameUNDEFINED;
 
 827     //          //        temp = (PHPString) phpList.get(currentPHPString++);
 
 828     //          //        this.str = temp.getPHPString();
 
 829     //          //        this.token = TokenNameEOF;
 
 830     //          //        this.chIndx = 0;
 
 831     //          //        this.rowCount = temp.getLineNumber();
 
 832     //          //        this.columnCount = 0;
 
 833     //          //        getNextToken();
 
 836     //          //        token = TokenNameUNDEFINED;
 
 843   //     * Get an identifier.
 
 845   //    private void getIdentifier() {
 
 846   //            //  StringBuffer ident = new StringBuffer();
 
 847   //            int startPosition = chIndx - 1;
 
 848   //            //    ident.append(ch);
 
 851   //                    // attention recursive call:
 
 853   //                    token = TokenNameVariable;
 
 856   //                    token = TokenNameIdentifier;
 
 861   //            //this will read the buffer until the next character is a forbidden character for identifier
 
 862   //            while ((ch >= 'a' && ch <= 'z')
 
 863   //                    || (ch >= 'A' && ch <= 'Z')
 
 864   //                    || (ch >= '0' && ch <= '9')
 
 866   //                    //    ident.append(ch);
 
 869   //            int endPosition = chIndx--;
 
 870   //            int length = (--endPosition) - startPosition;
 
 872   //            identifier = str.substring(startPosition, endPosition);
 
 873   //            // System.out.println(identifier);
 
 875   //            // determine if this identitfer is a keyword
 
 876   //            // @todo improve this in future version
 
 877   //            Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
 
 879   //                    token = i.intValue();
 
 885    * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
 
 886    * value {@link Parser#TokenNameDOUBLE_NUMBER}<br />
 
 887    * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
 
 888    * value {@link Parser#TokenNameINT_NUMBER}
 
 890   //  private void getNumber() {
 
 891   //    StringBuffer inum = new StringBuffer();
 
 893   //    int numFormat = 10;
 
 895   //    // save first digit
 
 896   //    char firstCh = ch;
 
 900   //    // determine number conversions:
 
 901   //    if (firstCh == '0') {
 
 930   //    if (numFormat == 16) {
 
 931   //      while ((ch >= '0' && ch <= '9')
 
 932   //        || (ch >= 'a' && ch <= 'f')
 
 933   //        || (ch >= 'A' && ch <= 'F')) {
 
 938   //      while ((ch >= '0' && ch <= '9')
 
 942   //        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
 
 943   //          if (ch == '.' && dFlag != ' ') {
 
 946   //          if ((dFlag == 'E') || (dFlag == 'e')) {
 
 952   //          if ((ch == '-') || (ch == '+')) {
 
 965   //      if (dFlag != ' ') {
 
 966   //        doubleNumber = new Double(inum.toString());
 
 967   //        token = TokenNameDoubleLiteral;
 
 970   //        longNumber = Long.valueOf(inum.toString(), numFormat);
 
 971   //        token = TokenNameIntegerLiteral;
 
 975   //    } catch (Throwable e) {
 
 976   //      throwSyntaxError("Number format error: " + inum.toString());
 
 982   //   * @param openChar the opening char ('\'', '"', '`')
 
 983   //   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
 
 984   //   * @param errorMsg the error message in case of parse error in the string
 
 986   //  private void getString(
 
 987   //    final char openChar,
 
 988   //    final int typeString,
 
 989   //    final String errorMsg) {
 
 990   //    StringBuffer sBuffer = new StringBuffer();
 
 991   //    boolean openString = true;
 
 992   //    int startRow = rowCount;
 
 993   //    while (str.length() > chIndx) {
 
 994   //      ch = str.charAt(chIndx++);
 
 996   //        sBuffer.append(ch);
 
 997   //        if (str.length() > chIndx) {
 
 998   //          ch = str.charAt(chIndx++);
 
 999   //          sBuffer.append(ch);
 
1001   //      } else if (ch == openChar) {
 
1002   //        openString = false;
 
1004   //      } else if (ch == '\n') {
 
1006   //        columnCount = chIndx;
 
1008   //        sBuffer.append(ch);
 
1011   //    if (openString) {
 
1012   //      if (typeString == TokenNameStringConstant) {
 
1013   //        throwSyntaxError(errorMsg, startRow);
 
1015   //        throwSyntaxError(errorMsg);
 
1018   //    token = typeString;
 
1019   //    stringValue = sBuffer.toString();
 
1022   //    public void htmlParserTester(String input) {
 
1023   //            int lineNumber = 1;
 
1024   //            int startLineNumber = 1;
 
1025   //            int startIndex = 0;
 
1028   //            boolean phpMode = false;
 
1029   //            boolean phpFound = false;
 
1031   //            phpList = new ArrayList();
 
1032   //            currentPHPString = 0;
 
1036   //                    while (i < input.length()) {
 
1037   //                            ch = input.charAt(i++);
 
1038   //                            if (ch == '\n') {
 
1041   //                            if ((!phpMode) && ch == '<') {
 
1042   //                                    ch2 = input.charAt(i++);
 
1043   //                                    if (ch2 == '?') {
 
1044   //                                            ch2 = input.charAt(i++);
 
1045   //                                            if (Character.isWhitespace(ch2)) {
 
1050   //                                                    startLineNumber = lineNumber;
 
1052   //                                            } else if (ch2 == 'p') {
 
1053   //                                                    ch2 = input.charAt(i++);
 
1054   //                                                    if (ch2 == 'h') {
 
1055   //                                                            ch2 = input.charAt(i++);
 
1056   //                                                            if (ch2 == 'p') {
 
1060   //                                                                    startLineNumber = lineNumber;
 
1066   //                                            } else if (ch2 == 'P') {
 
1067   //                                                    ch2 = input.charAt(i++);
 
1068   //                                                    if (ch2 == 'H') {
 
1069   //                                                            ch2 = input.charAt(i++);
 
1070   //                                                            if (ch2 == 'P') {
 
1074   //                                                                    startLineNumber = lineNumber;
 
1087   //                                    if (ch == '/' && i < input.length()) {
 
1088   //                                            ch2 = input.charAt(i++);
 
1089   //                                            if (ch2 == '/') {
 
1090   //                                                    while (i < input.length()) {
 
1091   //                                                            ch = input.charAt(i++);
 
1092   //                                                            if (ch == '?' && i < input.length()) {
 
1093   //                                                                    ch2 = input.charAt(i++);
 
1094   //                                                                    if (ch2 == '>') {
 
1102   //                                                                                            startLineNumber));
 
1106   //                                                            } else if (ch == '\n') {
 
1112   //                                            } else if (ch2 == '*') {
 
1113   //                                                    // multi-line comment
 
1114   //                                                    while (i < input.length()) {
 
1115   //                                                            ch = input.charAt(i++);
 
1116   //                                                            if (ch == '\n') {
 
1118   //                                                            } else if (ch == '*' && i < input.length()) {
 
1119   //                                                                    ch2 = input.charAt(i++);
 
1120   //                                                                    if (ch2 == '/') {
 
1130   //                                    } else if (ch == '#') {
 
1131   //                                            while (i < input.length()) {
 
1132   //                                                    ch = input.charAt(i++);
 
1133   //                                                    if (ch == '?' && i < input.length()) {
 
1134   //                                                            ch2 = input.charAt(i++);
 
1135   //                                                            if (ch2 == '>') {
 
1140   //                                                                                    input.substring(startIndex, i - 2),
 
1141   //                                                                                    startLineNumber));
 
1145   //                                                    } else if (ch == '\n') {
 
1151   //                                    } else if (ch == '"') {
 
1153   //                                            while (i < input.length()) {
 
1154   //                                                    ch = input.charAt(i++);
 
1155   //                                                    if (ch == '\n') {
 
1158   //                                                            ch == '\\' && i < input.length()) { // escape
 
1160   //                                                    } else if (ch == '"') {
 
1165   //                                    } else if (ch == '\'') {
 
1167   //                                            while (i < input.length()) {
 
1168   //                                                    ch = input.charAt(i++);
 
1169   //                                                    if (ch == '\n') {
 
1172   //                                                            ch == '\\' && i < input.length()) { // escape
 
1174   //                                                    } else if (ch == '\'') {
 
1181   //                                    if (ch == '?' && i < input.length()) {
 
1182   //                                            ch2 = input.charAt(i++);
 
1183   //                                            if (ch2 == '>') {
 
1188   //                                                                    input.substring(startIndex, i - 2),
 
1189   //                                                                    startLineNumber));
 
1199   //                                    "No PHP source code found.",
 
1205   //                                            "Open PHP tag at end of file.",
 
1210   //                                                    input.substring(startIndex, i - 2),
 
1211   //                                                    startLineNumber));
 
1213   //                            //        for (int j=0;j<phpList.size();j++) {
 
1214   //                            //          String temp = ((PHPString)phpList.get(j)).getPHPString();
 
1215   //                            //          int startIndx = temp.length()-10;
 
1216   //                            //          if (startIndx<0) {
 
1217   //                            //            startIndx = 0;
 
1219   //                            //          System.out.println(temp.substring(startIndx)+"?>");
 
1221   //                            phpParserTester(null, 1);
 
1222   //                            //        PHPString temp;
 
1223   //                            //        for(int j=0;j<phpList.size();j++) {
 
1224   //                            //          temp = (PHPString) phpList.get(j);
 
1225   //                            //          parser.start(temp.getPHPString(), temp.getLineNumber());
 
1228   //            } catch (CoreException e) {
 
1232   public void phpParserTester(String s, int rowCount) throws CoreException {
 
1235       if (phpList.size() != 0) {
 
1236         this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
 
1239     this.token = TokenNameEOF;
 
1241     //    this.rowCount = rowCount;
 
1242     //    this.columnCount = 0;
 
1243     this.phpEnd = false;
 
1244     this.phpMode = true;
 
1245     scanner.setSource(s.toCharArray());
 
1246     scanner.setPHPMode(true);
 
1250         if (token != TokenNameEOF && token != TokenNameERROR) {
 
1253         if (token != TokenNameEOF) {
 
1254           if (token == TokenNameERROR) {
 
1256               "Scanner error (Found unknown token: "
 
1257                 + scanner.toStringAction(token)
 
1260           if (token == TokenNameRPAREN) {
 
1261             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
1263           if (token == TokenNameRBRACE) {
 
1264             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
1266           if (token == TokenNameRBRACKET) {
 
1267             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
1270           if (token == TokenNameLPAREN) {
 
1271             throwSyntaxError("Read character '('; end-of-file not reached.");
 
1273           if (token == TokenNameLBRACE) {
 
1274             throwSyntaxError("Read character '{';  end-of-file not reached.");
 
1276           if (token == TokenNameLBRACKET) {
 
1277             throwSyntaxError("Read character '[';  end-of-file not reached.");
 
1280           throwSyntaxError("End-of-file not reached.");
 
1283       } catch (SyntaxError err) {
 
1287           //   setMarker(err.getMessage(), err.getLine(), ERROR);
 
1290             scanner.getCurrentTokenStartPosition(),
 
1291             scanner.getCurrentTokenEndPosition(),
 
1294         // if an error occured,
 
1295         // try to find keywords 'class' or 'function'
 
1296         // to parse the rest of the string
 
1297         while (token != TokenNameEOF && token != TokenNameERROR) {
 
1298           if (token == TokenNameclass || token == TokenNamefunction) {
 
1303         if (token == TokenNameEOF || token == TokenNameERROR) {
 
1312    * Parses a string with php tags
 
1313    * i.e. '<body> <?php phpinfo() ?> </body>'
 
1315   public void parse(String s) throws CoreException {
 
1317     this.token = TokenNameEOF;
 
1319     //    this.rowCount = 1;
 
1320     //    this.columnCount = 0;
 
1321     this.phpEnd = false;
 
1322     this.phpMode = false;
 
1323     /* scanner initialization */
 
1324     scanner.setSource(s.toCharArray());
 
1325     scanner.setPHPMode(false);
 
1329         if (token != TokenNameEOF && token != TokenNameERROR) {
 
1332         if (token != TokenNameEOF) {
 
1333           if (token == TokenNameERROR) {
 
1335               "Scanner error (Found unknown token: "
 
1336                 + scanner.toStringAction(token)
 
1339           if (token == TokenNameRPAREN) {
 
1340             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
1342           if (token == TokenNameRBRACE) {
 
1343             throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
1345           if (token == TokenNameRBRACKET) {
 
1346             throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
1349           if (token == TokenNameLPAREN) {
 
1350             throwSyntaxError("Read character '('; end-of-file not reached.");
 
1352           if (token == TokenNameLBRACE) {
 
1353             throwSyntaxError("Read character '{';  end-of-file not reached.");
 
1355           if (token == TokenNameLBRACKET) {
 
1356             throwSyntaxError("Read character '[';  end-of-file not reached.");
 
1359           throwSyntaxError("End-of-file not reached.");
 
1362       } catch (SyntaxError sytaxErr1) {
 
1363         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
 
1365           sytaxErr1.getMessage(),
 
1366           scanner.getCurrentTokenStartPosition(),
 
1367           scanner.getCurrentTokenEndPosition(),
 
1370           // if an error occured,
 
1371           // try to find keywords 'class' or 'function'
 
1372           // to parse the rest of the string
 
1373           while (token != TokenNameEOF && token != TokenNameERROR) {
 
1374             if (token == TokenNameclass || token == TokenNamefunction) {
 
1379           if (token == TokenNameEOF || token == TokenNameERROR) {
 
1382         } catch (SyntaxError sytaxErr2) {
 
1383           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
 
1385             sytaxErr2.getMessage(),
 
1386             scanner.getCurrentTokenStartPosition(),
 
1387             scanner.getCurrentTokenEndPosition(),
 
1396   public PHPOutlineInfo parseInfo(Object parent, String s) {
 
1397     PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
 
1398     //    Stack stack = new Stack();
 
1399     //    stack.push(outlineInfo.getDeclarations());
 
1402     this.token = TokenNameEOF;
 
1404     //    this.rowCount = 1;
 
1405     //    this.columnCount = 0;
 
1406     this.phpEnd = false;
 
1407     this.phpMode = false;
 
1408     scanner.setSource(s.toCharArray());
 
1409     scanner.setPHPMode(false);
 
1413       parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
 
1414     } catch (CoreException e) {
 
1419   private void parseDeclarations(
 
1420     PHPOutlineInfo outlineInfo,
 
1421     PHPSegmentWithChildren current,
 
1424     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
 
1425     PHPSegmentWithChildren temp;
 
1428     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
 
1430       while (token != TokenNameEOF && token != TokenNameERROR) {
 
1431         if (token == TokenNameVariable) {
 
1432           ident = scanner.getCurrentIdentifierSource();
 
1433           outlineInfo.addVariable(new String(ident));
 
1435         } else if (token == TokenNamevar) {
 
1437           if (token == TokenNameVariable
 
1438             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
 
1439             ident = scanner.getCurrentIdentifierSource();
 
1440             String variableName = new String(ident);
 
1441             outlineInfo.addVariable(variableName);
 
1443             if (token != TokenNameSEMICOLON) {
 
1446               ident = scanner.getCurrentTokenSource();
 
1447               if (token > TokenNameKEYWORD) {
 
1448                 current.add(new PHPVarDeclaration(current, variableName,
 
1449                 //                      chIndx - ident.length,
 
1450                 scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1453                   case TokenNameVariable :
 
1454                     current.add(new PHPVarDeclaration(current, variableName,
 
1455                     //                      chIndx - ident.length,
 
1456                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1458                   case TokenNameIdentifier :
 
1459                     current.add(new PHPVarDeclaration(current, variableName,
 
1460                     //                    chIndx - ident.length,
 
1461                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1463                   case TokenNameDoubleLiteral :
 
1465                       .add(new PHPVarDeclaration(
 
1467                         variableName + doubleNumber,
 
1468                     //   chIndx - ident.length,
 
1469                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1471                   case TokenNameIntegerLiteral :
 
1472                     current.add(new PHPVarDeclaration(current, variableName,
 
1473                     //                 chIndx - ident.length,
 
1474                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1476                   case TokenNameStringInterpolated :
 
1477                   case TokenNameStringLiteral :
 
1478                     current.add(new PHPVarDeclaration(current, variableName,
 
1479                     //              chIndx - ident.length,
 
1480                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1482                   case TokenNameStringConstant :
 
1483                     current.add(new PHPVarDeclaration(current, variableName,
 
1484                     //   chIndx - ident.length,
 
1485                     scanner.getCurrentTokenStartPosition(), new String(ident)));
 
1488                     current.add(new PHPVarDeclaration(current, variableName,
 
1489                     //               chIndx - ident.length
 
1490                     scanner.getCurrentTokenStartPosition()));
 
1496               ident = scanner.getCurrentIdentifierSource();
 
1498               current.add(new PHPVarDeclaration(current, variableName,
 
1499               //          chIndx - ident.length
 
1500               scanner.getCurrentTokenStartPosition()));
 
1503         } else if (token == TokenNamefunction) {
 
1505           if (token == TokenNameAND) {
 
1508           if (token == TokenNameIdentifier
 
1509             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
 
1510             ident = scanner.getCurrentIdentifierSource();
 
1511             outlineInfo.addVariable(new String(ident));
 
1512             temp = new PHPFunctionDeclaration(current, new String(ident),
 
1513               // chIndx - ident.length
 
1514   scanner.getCurrentTokenStartPosition());
 
1517             parseDeclarations(outlineInfo, temp, true);
 
1519         } else if (token == TokenNameclass) {
 
1521           if (token == TokenNameIdentifier
 
1522             && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
 
1523             ident = scanner.getCurrentIdentifierSource();
 
1524             outlineInfo.addVariable(new String(ident));
 
1525             temp = new PHPClassDeclaration(current, new String(ident),
 
1526               //      chIndx - ident.len
 
1527   scanner.getCurrentTokenStartPosition());
 
1529             //        stack.push(temp);
 
1532             //skip tokens for classname, extends and others until we have the opening '{'
 
1533             while (token != TokenNameLBRACE
 
1534               && token != TokenNameEOF
 
1535               && token != TokenNameERROR) {
 
1538             parseDeclarations(outlineInfo, temp, true);
 
1541         } else if (token == TokenNameLBRACE) {
 
1544         } else if (token == TokenNameRBRACE) {
 
1547           if (counter == 0 && goBack) {
 
1551           token == TokenNamerequire
 
1552             || token == TokenNamerequire_once
 
1553             || token == TokenNameinclude
 
1554             || token == TokenNameinclude_once) {
 
1555           ident = scanner.getCurrentTokenSource();
 
1558           int startPosition = scanner.getCurrentTokenStartPosition();
 
1560           char[] expr = scanner.getCurrentTokenSource(startPosition);
 
1561           outlineInfo.addVariable(new String(ident));
 
1562           current.add(new PHPReqIncDeclaration(current, new String(ident),
 
1563           //    chIndx - ident.length,
 
1564           startPosition, new String(expr)));
 
1570     } catch (CoreException e) {
 
1571     } catch (SyntaxError sytaxErr) {
 
1573         //  setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
 
1575           sytaxErr.getMessage(),
 
1576           scanner.getCurrentTokenStartPosition(),
 
1577           scanner.getCurrentTokenEndPosition(),
 
1579       } catch (CoreException e) {
 
1584   private void statementList() throws CoreException {
 
1587       if ((token == TokenNameRBRACE)
 
1588         || (token == TokenNamecase)
 
1589         || (token == TokenNamedefault)
 
1590         || (token == TokenNameelseif)
 
1591         || (token == TokenNameendif)
 
1592         || (token == TokenNameendfor)
 
1593         || (token == TokenNameendforeach)
 
1594         || (token == TokenNameendwhile)
 
1595         || (token == TokenNameendswitch)
 
1596         || (token == TokenNameEOF)
 
1597         || (token == TokenNameERROR)) {
 
1603   private void compoundStatement() throws CoreException {
 
1604     // '{' [statement-list] '}'
 
1605     if (token == TokenNameLBRACE) {
 
1608       throwSyntaxError("'{' expected in compound-statement.");
 
1610     if (token != TokenNameRBRACE) {
 
1613     if (token == TokenNameRBRACE) {
 
1616       throwSyntaxError("'}' expected in compound-statement.");
 
1620   private void statement() throws CoreException {
 
1621     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
 
1622     //  char[] ident = scanner.getCurrentIdentifierSource();
 
1623     //  String keyword = new String(ident);
 
1624     if (token == TokenNameinclude || token == TokenNameinclude_once) {
 
1627       if (token == TokenNameSEMICOLON) {
 
1630         if (token != TokenNameStopPHP) {
 
1631           throwSyntaxError("';' character after 'include' or 'include_once' expected.");
 
1636     } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
 
1640       if (token == TokenNameSEMICOLON) {
 
1643         if (token != TokenNameStopPHP) {
 
1644           throwSyntaxError("';' character after 'require' or 'require_once' expected.");
 
1649     } else if (token == TokenNameif) {
 
1651       if (token == TokenNameLPAREN) {
 
1654         throwSyntaxError("'(' expected after 'if' keyword.");
 
1657       if (token == TokenNameRPAREN) {
 
1660         throwSyntaxError("')' expected after 'if' condition.");
 
1665     } else if (token == TokenNameswitch) {
 
1667       if (token == TokenNameLPAREN) {
 
1670         throwSyntaxError("'(' expected after 'switch' keyword.");
 
1673       if (token == TokenNameRPAREN) {
 
1676         throwSyntaxError("')' expected after 'switch' condition.");
 
1680     } else if (token == TokenNamefor) {
 
1682       if (token == TokenNameLPAREN) {
 
1685         throwSyntaxError("'(' expected after 'for' keyword.");
 
1687       if (token == TokenNameSEMICOLON) {
 
1691         if (token == TokenNameSEMICOLON) {
 
1694           throwSyntaxError("';' expected after 'for'.");
 
1697       if (token == TokenNameSEMICOLON) {
 
1701         if (token == TokenNameSEMICOLON) {
 
1704           throwSyntaxError("';' expected after 'for'.");
 
1707       if (token == TokenNameRPAREN) {
 
1711         if (token == TokenNameRPAREN) {
 
1714           throwSyntaxError("')' expected after 'for'.");
 
1719     } else if (token == TokenNamewhile) {
 
1721       if (token == TokenNameLPAREN) {
 
1724         throwSyntaxError("'(' expected after 'while' keyword.");
 
1727       if (token == TokenNameRPAREN) {
 
1730         throwSyntaxError("')' expected after 'while' condition.");
 
1734     } else if (token == TokenNamedo) {
 
1736       if (token == TokenNameLBRACE) {
 
1739         throwSyntaxError("'{' expected after 'do' keyword.");
 
1741       if (token != TokenNameRBRACE) {
 
1744       if (token == TokenNameRBRACE) {
 
1747         throwSyntaxError("'}' expected after 'do' keyword.");
 
1749       if (token == TokenNamewhile) {
 
1751         if (token == TokenNameLPAREN) {
 
1754           throwSyntaxError("'(' expected after 'while' keyword.");
 
1757         if (token == TokenNameRPAREN) {
 
1760           throwSyntaxError("')' expected after 'while' condition.");
 
1763         throwSyntaxError("'while' expected after 'do' keyword.");
 
1765       if (token == TokenNameSEMICOLON) {
 
1768         if (token != TokenNameStopPHP) {
 
1769           throwSyntaxError("';' expected after do-while statement.");
 
1774     } else if (token == TokenNameforeach) {
 
1776       if (token == TokenNameLPAREN) {
 
1779         throwSyntaxError("'(' expected after 'foreach' keyword.");
 
1782       if (token == TokenNameas) {
 
1785         throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
1788       if (token == TokenNameEQUAL_GREATER) {
 
1792       if (token == TokenNameRPAREN) {
 
1795         throwSyntaxError("')' expected after 'foreach' expression.");
 
1801       token == TokenNamecontinue
 
1802         || token == TokenNamebreak
 
1803         || token == TokenNamereturn) {
 
1805       if (token != TokenNameSEMICOLON) {
 
1808       if (token == TokenNameSEMICOLON) {
 
1811         if (token != TokenNameStopPHP) {
 
1812           throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
 
1818     } else if (token == TokenNameecho) {
 
1821       if (token == TokenNameSEMICOLON) {
 
1824         if (token != TokenNameStopPHP) {
 
1825           throwSyntaxError("';' expected after 'echo' statement.");
 
1830       //    } else if (token == TokenNameprint) {
 
1833       //      if (token == TokenNameSEMICOLON) {
 
1836       //        if (token != TokenNameStopPHP) {
 
1837       //          throwSyntaxError("';' expected after 'print' statement.");
 
1843     } else if (token == TokenNameglobal || token == TokenNamestatic) {
 
1846       if (token == TokenNameSEMICOLON) {
 
1849         if (token != TokenNameStopPHP) {
 
1850           throwSyntaxError("';' expected after 'global' or 'static' statement.");
 
1856       //      } else if (token == TokenNameunset) {
 
1858       //        if (token == TokenNameARGOPEN) {
 
1861       //          throwSyntaxError("'(' expected after 'unset' keyword.");
 
1864       //        if (token == TokenNameARGCLOSE) {
 
1867       //          throwSyntaxError("')' expected after 'unset' statement.");
 
1869       //        if (token == TokenNameSEMICOLON) {
 
1872       //          if (token != TokenNameStopPHP) {
 
1873       //            throwSyntaxError("';' expected after 'unset' statement.");
 
1879       //      } else if (token == TokenNameexit || token == TokenNamedie) {
 
1881       //        if (token != TokenNameSEMICOLON) {
 
1884       //        if (token == TokenNameSEMICOLON) {
 
1887       //          if (token != TokenNameStopPHP) {
 
1888       //            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
 
1894     } else if (token == TokenNamedefine) {
 
1896       if (token == TokenNameLPAREN) {
 
1899         throwSyntaxError("'(' expected after 'define' keyword.");
 
1902       if (token == TokenNameCOMMA) {
 
1905         throwSyntaxError("',' expected after first 'define' constant.");
 
1908       if (token == TokenNameCOMMA) {
 
1912       if (token == TokenNameRPAREN) {
 
1915         throwSyntaxError("')' expected after 'define' statement.");
 
1917       if (token == TokenNameSEMICOLON) {
 
1920         if (token != TokenNameStopPHP) {
 
1921           throwSyntaxError("';' expected after 'define' statement.");
 
1926     } else if (token == TokenNamefunction) {
 
1928       functionDefinition();
 
1930     } else if (token == TokenNameclass) {
 
1936       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
 
1937     } else if (token == TokenNameLBRACE) {
 
1938       // compoundStatement
 
1940       if (token != TokenNameRBRACE) {
 
1943       if (token == TokenNameRBRACE) {
 
1947         throwSyntaxError("'}' expected.");
 
1950       if (token != TokenNameSEMICOLON) {
 
1953       if (token == TokenNameSEMICOLON) {
 
1957         if (token != TokenNameStopPHP && token != TokenNameEOF) {
 
1959             "';' expected after expression (Found token: "
 
1960               + scanner.toStringAction(token)
 
1968   private void classDeclarator() throws CoreException {
 
1970     //identifier 'extends' identifier
 
1971     if (token == TokenNameIdentifier) {
 
1973       if (token == TokenNameextends) {
 
1975         if (token == TokenNameIdentifier) {
 
1978           throwSyntaxError("Class name expected after keyword 'extends'.");
 
1982       throwSyntaxError("Class name expected after keyword 'class'.");
 
1986   private void classBody() throws CoreException {
 
1987     //'{' [class-element-list] '}'
 
1988     if (token == TokenNameLBRACE) {
 
1990       if (token != TokenNameRBRACE) {
 
1993       if (token == TokenNameRBRACE) {
 
1996         throwSyntaxError("'}' expected at end of class body.");
 
1999       throwSyntaxError("'{' expected at start of class body.");
 
2003   private void classElementList() throws CoreException {
 
2006     } while (token == TokenNamefunction || token == TokenNamevar);
 
2009   private void classElement() throws CoreException {
 
2011     //function-definition
 
2012     if (token == TokenNamefunction) {
 
2014       functionDefinition();
 
2015     } else if (token == TokenNamevar) {
 
2019       throwSyntaxError("'function' or 'var' expected.");
 
2023   private void classProperty() throws CoreException {
 
2024     //'var' variable ';'
 
2025     //'var' variable '=' constant ';'
 
2027       if (token == TokenNameVariable) {
 
2029         if (token == TokenNameEQUAL) {
 
2034         throwSyntaxError("Variable expected after keyword 'var'.");
 
2036       if (token != TokenNameCOMMA) {
 
2041     if (token == TokenNameSEMICOLON) {
 
2044       throwSyntaxError("';' expected after variable declaration.");
 
2048   private void functionDefinition() throws CoreException {
 
2049     functionDeclarator();
 
2050     compoundStatement();
 
2053   private void functionDeclarator() throws CoreException {
 
2054     //identifier '(' [parameter-list] ')'
 
2055     if (token == TokenNameAND) {
 
2058     if (token == TokenNameIdentifier) {
 
2060       if (token == TokenNameLPAREN) {
 
2063         throwSyntaxError("'(' expected in function declaration.");
 
2065       if (token != TokenNameRPAREN) {
 
2068       if (token != TokenNameRPAREN) {
 
2069         throwSyntaxError("')' expected in function declaration.");
 
2076   private void parameterList() throws CoreException {
 
2077     //parameter-declaration
 
2078     //parameter-list ',' parameter-declaration
 
2080       parameterDeclaration();
 
2081       if (token != TokenNameCOMMA) {
 
2088   private void parameterDeclaration() throws CoreException {
 
2090     //variable-reference
 
2091     if (token == TokenNameAND) {
 
2093       if (token == TokenNameVariable) {
 
2096         throwSyntaxError("Variable expected after reference operator '&'.");
 
2099     //variable '=' constant
 
2100     if (token == TokenNameVariable) {
 
2102       if (token == TokenNameEQUAL) {
 
2110   private void labeledStatementList() throws CoreException {
 
2111     if (token != TokenNamecase && token != TokenNamedefault) {
 
2112       throwSyntaxError("'case' or 'default' expected.");
 
2115       if (token == TokenNamecase) {
 
2118         if (token == TokenNameCOLON) {
 
2120           if (token == TokenNamecase
 
2121             || token == TokenNamedefault) { // empty case statement ?
 
2125         } else if (token == TokenNameSEMICOLON) {
 
2127           //            "':' expected after 'case' keyword (Found token: "
 
2128           //              + scanner.toStringAction(token)
 
2133             "':' expected after 'case' keyword (Found token: "
 
2134               + scanner.toStringAction(token)
 
2136             scanner.getCurrentTokenStartPosition(),
 
2137             scanner.getCurrentTokenEndPosition(),
 
2140           if (token == TokenNamecase) { // empty case statement ?
 
2146             "':' character after 'case' constant expected (Found token: "
 
2147               + scanner.toStringAction(token)
 
2150       } else { // TokenNamedefault
 
2152         if (token == TokenNameCOLON) {
 
2156           throwSyntaxError("':' character after 'default' expected.");
 
2159     } while (token == TokenNamecase || token == TokenNamedefault);
 
2162   //  public void labeledStatement() {
 
2163   //    if (token == TokenNamecase) {
 
2166   //      if (token == TokenNameDDOT) {
 
2170   //        throwSyntaxError("':' character after 'case' constant expected.");
 
2173   //    } else if (token == TokenNamedefault) {
 
2175   //      if (token == TokenNameDDOT) {
 
2179   //        throwSyntaxError("':' character after 'default' expected.");
 
2185   //  public void expressionStatement() {
 
2188   //  private void inclusionStatement() {
 
2191   //  public void compoundStatement() {
 
2194   //  public void selectionStatement() {
 
2197   //  public void iterationStatement() {
 
2200   //  public void jumpStatement() {
 
2203   //  public void outputStatement() {
 
2206   //  public void scopeStatement() {
 
2209   //  public void flowStatement() {
 
2212   //  public void definitionStatement() {
 
2215   private void ifStatement() throws CoreException {
 
2216     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
 
2217     if (token == TokenNameCOLON) {
 
2221         case TokenNameelse :
 
2223           if (token == TokenNameCOLON) {
 
2227             if (token == TokenNameif) { //'else if'
 
2229               elseifStatementList();
 
2231               throwSyntaxError("':' expected after 'else'.");
 
2235         case TokenNameelseif :
 
2237           elseifStatementList();
 
2241       if (token != TokenNameendif) {
 
2242         throwSyntaxError("'endif' expected.");
 
2245       if (token != TokenNameSEMICOLON) {
 
2246         throwSyntaxError("';' expected after if-statement.");
 
2250       // statement [else-statement]
 
2252       if (token == TokenNameelseif) {
 
2254         if (token == TokenNameLPAREN) {
 
2257           throwSyntaxError("'(' expected after 'elseif' keyword.");
 
2260         if (token == TokenNameRPAREN) {
 
2263           throwSyntaxError("')' expected after 'elseif' condition.");
 
2266       } else if (token == TokenNameelse) {
 
2273   private void elseifStatementList() throws CoreException {
 
2277         case TokenNameelse :
 
2279           if (token == TokenNameCOLON) {
 
2284             if (token == TokenNameif) { //'else if'
 
2287               throwSyntaxError("':' expected after 'else'.");
 
2291         case TokenNameelseif :
 
2300   private void elseifStatement() throws CoreException {
 
2301     if (token == TokenNameLPAREN) {
 
2304       if (token != TokenNameLPAREN) {
 
2305         throwSyntaxError("')' expected in else-if-statement.");
 
2308       if (token != TokenNameCOLON) {
 
2309         throwSyntaxError("':' expected in else-if-statement.");
 
2316   private void switchStatement() throws CoreException {
 
2317     if (token == TokenNameCOLON) {
 
2318       // ':' [labeled-statement-list] 'endswitch' ';'
 
2320       labeledStatementList();
 
2321       if (token != TokenNameendswitch) {
 
2322         throwSyntaxError("'endswitch' expected.");
 
2325       if (token != TokenNameSEMICOLON) {
 
2326         throwSyntaxError("';' expected after switch-statement.");
 
2330       // '{' [labeled-statement-list] '}'
 
2331       if (token != TokenNameLBRACE) {
 
2332         throwSyntaxError("'{' expected in switch statement.");
 
2335       if (token != TokenNameRBRACE) {
 
2336         labeledStatementList();
 
2338       if (token != TokenNameRBRACE) {
 
2339         throwSyntaxError("'}' expected in switch statement.");
 
2346   private void forStatement() throws CoreException {
 
2347     if (token == TokenNameCOLON) {
 
2350       if (token != TokenNameendfor) {
 
2351         throwSyntaxError("'endfor' expected.");
 
2354       if (token != TokenNameSEMICOLON) {
 
2355         throwSyntaxError("';' expected after for-statement.");
 
2363   private void whileStatement() throws CoreException {
 
2364     // ':' statement-list 'endwhile' ';'
 
2365     if (token == TokenNameCOLON) {
 
2368       if (token != TokenNameendwhile) {
 
2369         throwSyntaxError("'endwhile' expected.");
 
2372       if (token != TokenNameSEMICOLON) {
 
2373         throwSyntaxError("';' expected after while-statement.");
 
2381   private void foreachStatement() throws CoreException {
 
2382     if (token == TokenNameCOLON) {
 
2385       if (token != TokenNameendforeach) {
 
2386         throwSyntaxError("'endforeach' expected.");
 
2389       if (token != TokenNameSEMICOLON) {
 
2390         throwSyntaxError("';' expected after foreach-statement.");
 
2398   private void exitStatus() throws CoreException {
 
2399     if (token == TokenNameLPAREN) {
 
2402       throwSyntaxError("'(' expected in 'exit-status'.");
 
2404     if (token != TokenNameRPAREN) {
 
2407     if (token == TokenNameRPAREN) {
 
2410       throwSyntaxError("')' expected after 'exit-status'.");
 
2414   private void expressionList() throws CoreException {
 
2417       if (token == TokenNameCOMMA) {
 
2425   private void expression() throws CoreException {
 
2426     //todo: find a better way to get the expression
 
2427     //    expression = new StringBuffer();
 
2428     //    for (int i = chIndx; i < str.length(); i++) {
 
2429     //      if (str.charAt(i) == ';') {
 
2432     //      expression.append(str.charAt(i));
 
2435     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
 
2438     logicalinclusiveorExpression();
 
2439     //      while (token != TokenNameSEMICOLON) {
 
2445   private void postfixExpression() throws CoreException {
 
2448     boolean castFlag = false;
 
2454       case TokenNamenull :
 
2457       case TokenNamefalse :
 
2460       case TokenNametrue :
 
2463       case TokenNameStringConstant :
 
2466       case TokenNameHEREDOC :
 
2467       case TokenNameStringInterpolated :
 
2468       case TokenNameStringLiteral :
 
2471       case TokenNameLPAREN :
 
2473         if (token == TokenNameIdentifier) {
 
2474           // check if identifier is a type:
 
2475           //    ident = identifier;
 
2476           ident = scanner.getCurrentIdentifierSource();
 
2477           String str = new String(ident).toLowerCase();
 
2478           for (int i = 0; i < PHP_TYPES.length; i++) {
 
2479             if (PHP_TYPES[i].equals(str)) {
 
2486             if (token != TokenNameRPAREN) {
 
2487               throwSyntaxError(") expected after cast-type '" + str + "'.");
 
2497         if (token != TokenNameRPAREN) {
 
2498           throwSyntaxError(") expected in postfix-expression.");
 
2502       case TokenNameDoubleLiteral :
 
2505       case TokenNameIntegerLiteral :
 
2508       case TokenNameDOLLAR_LBRACE :
 
2511         if (token != TokenNameRBRACE) {
 
2512           throwSyntaxError("'}' expected after indirect variable token '${'.");
 
2516       case TokenNameVariable :
 
2517         ident = scanner.getCurrentIdentifierSource();
 
2519         if (token == TokenNameLBRACE) {
 
2522           if (token != TokenNameRBRACE) {
 
2524               "'}' expected after variable '"
 
2526                 + "' in variable-expression.");
 
2529         } else if (token == TokenNameLPAREN) {
 
2531           if (token != TokenNameRPAREN) {
 
2533             if (token != TokenNameRPAREN) {
 
2535                 "')' expected after variable '"
 
2537                   + "' in postfix-expression.");
 
2543       case TokenNameIdentifier :
 
2544         ident = scanner.getCurrentIdentifierSource();
 
2546         if (token == TokenNameLPAREN) {
 
2548           if (token != TokenNameRPAREN) {
 
2550             if (token != TokenNameRPAREN) {
 
2552                 "')' expected after identifier '"
 
2554                   + "' in postfix-expression."
 
2556                   + scanner.toStringAction(token)
 
2563       case TokenNameprint :
 
2566         //        if (token == TokenNameSEMICOLON) {
 
2569         //          if (token != TokenNameStopPHP) {
 
2570         //            throwSyntaxError("';' expected after 'print' statement.");
 
2575       case TokenNamelist :
 
2577         if (token == TokenNameLPAREN) {
 
2579           if (token == TokenNameCOMMA) {
 
2583           if (token != TokenNameRPAREN) {
 
2584             throwSyntaxError("')' expected after 'list' keyword.");
 
2587           //          if (token == TokenNameSET) {
 
2589           //            logicalinclusiveorExpression();
 
2592           throwSyntaxError("'(' expected after 'list' keyword.");
 
2595         //      case TokenNameexit :
 
2597         //        if (token != TokenNameSEMICOLON) {
 
2600         //        if (token == TokenNameSEMICOLON) {
 
2603         //          if (token != TokenNameStopPHP) {
 
2604         //            throwSyntaxError("';' expected after 'exit' expression.");
 
2609         //      case TokenNamedie :
 
2611         //        if (token != TokenNameSEMICOLON) {
 
2614         //        if (token == TokenNameSEMICOLON) {
 
2617         //          if (token != TokenNameStopPHP) {
 
2618         //            throwSyntaxError("';' expected after 'die' expression.");
 
2623         //      case TokenNamearray :
 
2625         //        if (token == TokenNameARGOPEN) {
 
2627         //          if (token == TokenNameCOMMA) {
 
2630         //          expressionList();
 
2631         //          if (token != TokenNameARGCLOSE) {
 
2632         //            throwSyntaxError("')' expected after 'list' keyword.");
 
2635         //          if (token == TokenNameSET) {
 
2637         //            logicalinclusiveorExpression();
 
2640         //          throwSyntaxError("'(' expected after 'list' keyword.");
 
2644     boolean while_flag = true;
 
2647         case TokenNameLBRACKET :
 
2650           if (token != TokenNameRBRACKET) {
 
2651             throwSyntaxError("] expected in postfix-expression.");
 
2655         case TokenNameCOLON_COLON : // ::
 
2656         case TokenNameMINUS_GREATER : // ->
 
2658           if (token > TokenNameKEYWORD) {
 
2659             ident = scanner.getCurrentIdentifierSource();
 
2661             //              "Avoid using keyword '"
 
2662             //                + new String(ident)
 
2663             //                + "' as variable name.",
 
2667               "Avoid using keyword '"
 
2669                 + "' as variable name.",
 
2670               scanner.getCurrentTokenStartPosition(),
 
2671               scanner.getCurrentTokenEndPosition(),
 
2675             case TokenNameVariable :
 
2676               ident = scanner.getCurrentIdentifierSource();
 
2678               //              if (token == TokenNameARGOPEN) {
 
2680               //                expressionList();
 
2681               //                if (token != TokenNameARGCLOSE) {
 
2682               //                  throwSyntaxError(") expected after variable '" + ident + "'.");
 
2687             case TokenNameIdentifier :
 
2688               //ident = scanner.getCurrentIdentifierSource();
 
2691             case TokenNameLBRACE :
 
2694               if (token != TokenNameRBRACE) {
 
2695                 throwSyntaxError("} expected in postfix-expression.");
 
2700               throwSyntaxError("Syntax error after '->' token.");
 
2702             token == TokenNameLBRACKET
 
2703               || token == TokenNameLPAREN
 
2704               || token == TokenNameLBRACE) {
 
2705               if (token == TokenNameLBRACKET) {
 
2708                 if (token != TokenNameRBRACKET) {
 
2709                   throwSyntaxError("] expected after '->'.");
 
2713               if (token == TokenNameLPAREN) {
 
2716                 if (token != TokenNameRPAREN) {
 
2717                   throwSyntaxError(") expected after '->'.");
 
2721               if (token == TokenNameLBRACE) {
 
2724                 if (token != TokenNameRBRACE) {
 
2725                   throwSyntaxError("} expected after '->'.");
 
2731         case TokenNamePLUS_PLUS :
 
2734         case TokenNameMINUS_MINUS :
 
2745   private void unaryExpression() throws CoreException {
 
2747       case TokenNamePLUS_PLUS :
 
2751       case TokenNameMINUS_MINUS :
 
2755         // '@' '&' '*' '+' '-' '~' '!'
 
2764       case TokenNameMULTIPLY :
 
2768       case TokenNamePLUS :
 
2772       case TokenNameMINUS :
 
2776       case TokenNameTWIDDLE :
 
2785         postfixExpression();
 
2789   private void castExpression() throws CoreException {
 
2790     //    if (token == TokenNameARGOPEN) {
 
2793     //      if (token != TokenNameARGCLOSE) {
 
2794     //        throwSyntaxError(") expected after cast-expression.");
 
2801   //  private void typeName() throws CoreException {
 
2802   //    //'string' 'unset' 'array' 'object'
 
2803   //    //'bool' 'boolean'
 
2804   //    //'real' 'double' 'float'
 
2805   //    //'int' 'integer'
 
2806   //    String identifier = "";
 
2807   //    if (token == TokenNameIdentifier) {
 
2808   //      char[] ident = scanner.getCurrentIdentifierSource();
 
2809   //      identifier = new String(ident);
 
2810   //      String str = identifier.toLowerCase();
 
2812   //      for (int i = 0; i < PHP_TYPES.length; i++) {
 
2813   //        if (PHP_TYPES[i].equals(str)) {
 
2818   //    throwSyntaxError(
 
2819   //      "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
 
2822   private void assignExpression() throws CoreException {
 
2824     if (token == TokenNameEQUAL) { // =
 
2826       logicalinclusiveorExpression();
 
2827     } else if (token == TokenNameDOT_EQUAL) { // .=
 
2829       logicalinclusiveorExpression();
 
2830     } else if (token == TokenNameEQUAL_GREATER) { // =>
 
2832       logicalinclusiveorExpression();
 
2833     } else if (token == TokenNamePLUS_EQUAL) { // +=
 
2835       logicalinclusiveorExpression();
 
2836     } else if (token == TokenNameMINUS_EQUAL) { // -=
 
2838       logicalinclusiveorExpression();
 
2839     } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
 
2841       logicalinclusiveorExpression();
 
2842     } else if (token == TokenNameDIVIDE_EQUAL) { // *=
 
2844       logicalinclusiveorExpression();
 
2845     } else if (token == TokenNameREMAINDER_EQUAL) { // %=
 
2847       logicalinclusiveorExpression();
 
2848     } else if (token == TokenNameAND_EQUAL) { // &=
 
2850       logicalinclusiveorExpression();
 
2851     } else if (token == TokenNameOR_EQUAL) { // |=
 
2853       logicalinclusiveorExpression();
 
2854     } else if (token == TokenNameXOR_EQUAL) { // ^=
 
2856       logicalinclusiveorExpression();
 
2857     } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
 
2859       logicalinclusiveorExpression();
 
2860     } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
 
2862       logicalinclusiveorExpression();
 
2863     } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
 
2865       logicalinclusiveorExpression();
 
2869   private void multiplicativeExpression() throws CoreException {
 
2872       if (token != TokenNameMULTIPLY
 
2873         && token != TokenNameDIVIDE
 
2874         && token != TokenNameREMAINDER) {
 
2881   private void concatenationExpression() throws CoreException {
 
2883       multiplicativeExpression();
 
2884       if (token != TokenNameDOT) {
 
2891   private void additiveExpression() throws CoreException {
 
2893       concatenationExpression();
 
2894       if (token != TokenNamePLUS && token != TokenNameMINUS) {
 
2901   private void shiftExpression() throws CoreException {
 
2903       additiveExpression();
 
2904       if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
 
2911   private void relationalExpression() throws CoreException {
 
2914       if (token != TokenNameLESS
 
2915         && token != TokenNameGREATER
 
2916         && token != TokenNameLESS_EQUAL
 
2917         && token != TokenNameGREATER_EQUAL) {
 
2924   private void identicalExpression() throws CoreException {
 
2926       relationalExpression();
 
2927       if (token != TokenNameEQUAL_EQUAL_EQUAL
 
2928         && token != TokenNameNOT_EQUAL_EQUAL) {
 
2935   private void equalityExpression() throws CoreException {
 
2937       identicalExpression();
 
2938       if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
 
2945   private void ternaryExpression() throws CoreException {
 
2946     equalityExpression();
 
2947     if (token == TokenNameQUESTION) {
 
2950       if (token == TokenNameCOLON) {
 
2954         throwSyntaxError("':' expected in ternary operator '? :'.");
 
2959   private void andExpression() throws CoreException {
 
2961       ternaryExpression();
 
2962       if (token != TokenNameAND) {
 
2969   private void exclusiveorExpression() throws CoreException {
 
2972       if (token != TokenNameXOR) {
 
2979   private void inclusiveorExpression() throws CoreException {
 
2981       exclusiveorExpression();
 
2982       if (token != TokenNameOR) {
 
2989   private void booleanandExpression() throws CoreException {
 
2991       inclusiveorExpression();
 
2992       if (token != TokenNameAND_AND) {
 
2999   private void booleanorExpression() throws CoreException {
 
3001       booleanandExpression();
 
3002       if (token != TokenNameOR_OR) {
 
3009   private void logicalandExpression() throws CoreException {
 
3011       booleanorExpression();
 
3012       if (token != TokenNameAND) {
 
3019   private void logicalexclusiveorExpression() throws CoreException {
 
3021       logicalandExpression();
 
3022       if (token != TokenNameXOR) {
 
3029   private void logicalinclusiveorExpression() throws CoreException {
 
3031       logicalexclusiveorExpression();
 
3032       if (token != TokenNameOR) {
 
3039   //  public void assignmentExpression() {
 
3040   //    if (token == TokenNameVARIABLE) {
 
3042   //      if (token == TokenNameSET) {
 
3044   //        logicalinclusiveorExpression();
 
3047   //      logicalinclusiveorExpression();
 
3051   private void variableList() throws CoreException {
 
3054       if (token == TokenNameCOMMA) {
 
3062   private void variable() throws CoreException {
 
3063     if (token == TokenNameDOLLAR_LBRACE) {
 
3067       if (token != TokenNameRBRACE) {
 
3068         throwSyntaxError("'}' expected after indirect variable token '${'.");
 
3072       if (token == TokenNameVariable) {
 
3074         if (token == TokenNameLBRACKET) {
 
3077           if (token != TokenNameRBRACKET) {
 
3078             throwSyntaxError("']' expected in variable-list.");
 
3081         } else if (token == TokenNameEQUAL) {
 
3086         throwSyntaxError("$-variable expected in variable-list.");
 
3092    * It will look for a value (after a '=' for example)
 
3093    * @throws CoreException
 
3095   private void constant() throws CoreException {
 
3098       case TokenNamePLUS :
 
3101           case TokenNameDoubleLiteral :
 
3104           case TokenNameIntegerLiteral :
 
3108             throwSyntaxError("Constant expected after '+' presign.");
 
3111       case TokenNameMINUS :
 
3114           case TokenNameDoubleLiteral :
 
3117           case TokenNameIntegerLiteral :
 
3121             throwSyntaxError("Constant expected after '-' presign.");
 
3124       case TokenNamenull :
 
3127       case TokenNamefalse :
 
3130       case TokenNametrue :
 
3133       case TokenNameIdentifier :
 
3134         //   ident = identifier;
 
3135         char[] ident = scanner.getCurrentIdentifierSource();
 
3137         if (token == TokenNameLPAREN) {
 
3139           if (token != TokenNameRPAREN) {
 
3141             if (token != TokenNameRPAREN) {
 
3143                 "')' expected after identifier '"
 
3145                   + "' in postfix-expression.");
 
3151       case TokenNameStringLiteral :
 
3154       case TokenNameStringConstant :
 
3157       case TokenNameStringInterpolated :
 
3160       case TokenNameDoubleLiteral :
 
3163       case TokenNameIntegerLiteral :
 
3167         throwSyntaxError("Constant expected.");