1 package net.sourceforge.phpeclipse.phpeditor;
 
   3 import java.util.ArrayList;
 
   4 import java.util.HashMap;
 
   5 import java.util.Hashtable;
 
   7 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
 
   8 import org.eclipse.core.resources.IFile;
 
   9 import org.eclipse.core.resources.IMarker;
 
  10 import org.eclipse.core.runtime.CoreException;
 
  11 import org.eclipse.ui.texteditor.MarkerUtilities;
 
  13 /**********************************************************************
 
  14 Copyright (c) 2000, 2002 IBM Corp. and others.
 
  15 All rights reserved. This program and the accompanying materials
 
  16 are made available under the terms of the Common Public License v1.0
 
  17 which accompanies this distribution, and is available at
 
  18 http://www.eclipse.org/legal/cpl-v10.html
 
  21     IBM Corporation - Initial implementation
 
  22     Klaus Hartlage - www.eclipseproject.de
 
  23 **********************************************************************/
 
  25 public class PHPParser extends PHPKeywords {
 
  27   public static final int ERROR = 2;
 
  28   public static final int WARNING = 1;
 
  29   public static final int INFO = 0;
 
  30   private IFile fileToParse;
 
  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:
 
  57   final static int TT_EOF = 0;
 
  58   final static int TT_UNDEFINED = 1;
 
  60   final static int TT_MOD = 30;
 
  61   final static int TT_NOT = 31;
 
  62   final static int TT_DOT = 32;
 
  63   final static int TT_POW = 33;
 
  64   final static int TT_DIV = 34;
 
  65   final static int TT_MULTIPLY = 35;
 
  66   final static int TT_SUBTRACT = 36;
 
  67   final static int TT_ADD = 37;
 
  68   final static int TT_EQUAL = 38;
 
  69   final static int TT_UNEQUAL = 39;
 
  70   final static int TT_GREATER = 40;
 
  71   final static int TT_GREATEREQUAL = 41;
 
  72   final static int TT_LESS = 42;
 
  73   final static int TT_LESSEQUAL = 43;
 
  74   final static int TT_AND = 44;
 
  75   final static int TT_OR = 45;
 
  76   final static int TT_HASH = 46;
 
  77   final static int TT_DDOT = 47;
 
  78   final static int TT_DOTASSIGN = 48;
 
  80   final static int TT_ASSIGN = 49;
 
  81   final static int TT_REF = 50;
 
  82   final static int TT_FOREACH = 51;
 
  83   final static int TT_AMPERSAND = 52;
 
  84   final static int TT_DOLLARLISTOPEN = 53;
 
  85   final static int TT_TILDE = 54;
 
  86   final static int TT_TILDEASSIGN = 55;
 
  87   final static int TT_MODASSIGN = 56;
 
  88   final static int TT_POWASSIGN = 57;
 
  89   final static int TT_RSHIFTASSIGN = 58;
 
  90   final static int TT_LSHIFTASSIGN = 59;
 
  91   final static int TT_ANDASSIGN = 60;
 
  92   final static int TT_QUESTIONMARK = 61;
 
  94   final static int TT_ARGOPEN = 128;
 
  95   final static int TT_ARGCLOSE = 129;
 
  96   final static int TT_LISTOPEN = 130;
 
  97   final static int TT_LISTCLOSE = 131;
 
  98   final static int TT_PARTOPEN = 132;
 
  99   final static int TT_PARTCLOSE = 133;
 
 100   final static int TT_COMMA = 134;
 
 102   final static int TT_STRING = 136;
 
 103   final static int TT_IDENTIFIER = 138;
 
 104   final static int TT_DIGIT = 139;
 
 105   final static int TT_SEMICOLON = 140;
 
 106   final static int TT_SLOT = 141;
 
 107   final static int TT_SLOTSEQUENCE = 142;
 
 108   final static int TT_DECREMENT = 144;
 
 109   final static int TT_INCREMENT = 145;
 
 110   final static int TT_ADDTO = 146;
 
 111   final static int TT_DIVIDEBY = 147;
 
 112   final static int TT_SUBTRACTFROM = 148;
 
 113   final static int TT_TIMESBY = 149;
 
 114   final static int TT_VARIABLE = 150;
 
 115   final static int TT_INT_NUMBER = 151;
 
 116   final static int TT_DOUBLE_NUMBER = 152;
 
 117   final static int TT_INTERPOLATED_STRING = 153;
 
 118   final static int TT_STRING_CONSTANT = 154;
 
 120   final static int TT_LSHIFT = 155;
 
 121   final static int TT_RSHIFT = 156;
 
 122   final static int TT_EX_EQUAL = 157;
 
 123   final static int TT_EX_UNEQUAL = 158;
 
 124   final static int TT_LINE = 159;
 
 125   //  final static int TT_AT = 153; // @
 
 130    *@param  sess  Description of Parameter
 
 133   public PHPParser(IFile fileToParse) {
 
 134     if (keywordMap == null) {
 
 135       keywordMap = new HashMap();
 
 136       for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 137         keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 140     this.currentPHPString = 0;
 
 141     this.fileToParse = fileToParse;
 
 147     this.columnCount = 0;
 
 154    * Create marker for the parse error
 
 156   protected void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
 
 157     setMarker(fileToParse, message, lineNumber, errorLevel);
 
 160   public static void setMarker(IFile file, String message, int lineNumber, int errorLevel) throws CoreException {
 
 162     Hashtable attributes = new Hashtable();
 
 163     MarkerUtilities.setMessage(attributes, message);
 
 164     switch (errorLevel) {
 
 166         attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
 
 169         attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
 
 172         attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
 
 175     MarkerUtilities.setLineNumber(attributes, lineNumber);
 
 176     MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
 
 179   private void throwSyntaxError(String error) {
 
 181     if (str.length() < chIndx) {
 
 184     // read until end-of-line
 
 186     while (str.length() > eol) {
 
 187       ch = str.charAt(eol++);
 
 193     throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error);
 
 197    *  Method Declaration.
 
 202     if (str.length() > chIndx) {
 
 203       ch = str.charAt(chIndx++);
 
 208     chIndx = str.length() + 1;
 
 215    * gets the next token from input
 
 217   void getNextToken() {
 
 220     while (str.length() > chIndx) {
 
 221       ch = str.charAt(chIndx++);
 
 222       token = TT_UNDEFINED;
 
 225         columnCount = chIndx;
 
 226         continue; // while loop
 
 228       if (str.length() == chIndx) {
 
 231       if (!Character.isWhitespace(ch)) {
 
 232         if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$') || (ch == '@')) {
 
 236         if (ch >= '0' && ch <= '9') {
 
 241           if (str.length() > chIndx) {
 
 242             if (str.charAt(chIndx) == '/') {
 
 244               // read comment until end of line:
 
 245               while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
 
 249             } else if (str.charAt(chIndx) == '*') {
 
 251               // multi line comment:
 
 252               while (str.length() > chIndx) {
 
 253                 if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') {
 
 257                 ch = str.charAt(chIndx++);
 
 260                   columnCount = chIndx;
 
 266         } else if (ch == '#') {
 
 267           // read comment until end of line:
 
 268           while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
 
 272         } else if (ch == '"') {
 
 273           // read string until end
 
 274           boolean openString = true;
 
 275           while (str.length() > chIndx) {
 
 276             ch = str.charAt(chIndx++);
 
 278               if (str.length() > chIndx) {
 
 279                 ch = str.charAt(chIndx++);
 
 281             } else if (ch == '"') {
 
 284             } else if (ch == '\n') {
 
 286               columnCount = chIndx;
 
 290             throwSyntaxError("Open string character '\"' at end of file.");
 
 292           token = TT_INTERPOLATED_STRING;
 
 294         } else if (ch == '\'') {
 
 295           // read string until end
 
 296           boolean openString = true;
 
 297           while (str.length() > chIndx) {
 
 298             ch = str.charAt(chIndx++);
 
 300               if (str.length() > chIndx) {
 
 301                 ch = str.charAt(chIndx++);
 
 303             } else if (ch == '\'') {
 
 306             } else if (ch == '\n') {
 
 308               columnCount = chIndx;
 
 312             throwSyntaxError("Open string character \"'\" at end of file.");
 
 314           token = TT_STRING_CONSTANT;
 
 333             token = TT_LISTCLOSE;
 
 341             token = TT_PARTCLOSE;
 
 349             token = TT_QUESTIONMARK;
 
 353             if (str.length() > chIndx) {
 
 354               if (str.charAt(chIndx) == '=') {
 
 356                 token = TT_TILDEASSIGN;
 
 364             if (str.length() > chIndx) {
 
 365               if (str.charAt(chIndx) == '=') {
 
 367                 token = TT_DOTASSIGN;
 
 380             if (str.length() > chIndx) {
 
 381               if (str.charAt(chIndx) == '=') {
 
 383                 token = TT_MODASSIGN;
 
 390             token = TT_SEMICOLON;
 
 395             if (str.length() > chIndx) {
 
 396               if (str.charAt(chIndx) == '=') {
 
 398                 token = TT_POWASSIGN;
 
 407             if (str.length() > chIndx) {
 
 408               if (str.charAt(chIndx) == '=') {
 
 419             if (str.length() > chIndx) {
 
 420               if (str.charAt(chIndx) == '*') {
 
 426               if (str.charAt(chIndx) == '=') {
 
 437             if (str.length() > chIndx) {
 
 438               if (str.charAt(chIndx) == '+') {
 
 440                 token = TT_INCREMENT;
 
 444               if (str.charAt(chIndx) == '=') {
 
 454             if (str.length() > chIndx) {
 
 455               if (str.charAt(chIndx) == '-') {
 
 457                 token = TT_DECREMENT;
 
 461               if (str.charAt(chIndx) == '=') {
 
 463                 token = TT_SUBTRACTFROM;
 
 467               if (str.charAt(chIndx) == '>') {
 
 479             if (str.length() > chIndx) {
 
 480               ch = str.charAt(chIndx);
 
 485                 if (str.length() > chIndx) {
 
 486                   ch = str.charAt(chIndx);
 
 507             if (str.length() > chIndx) {
 
 508               if (str.charAt(chIndx) == '=') {
 
 511                 if (str.length() > chIndx) {
 
 512                   ch = str.charAt(chIndx);
 
 516                     token = TT_EX_UNEQUAL;
 
 527             if (str.length() > chIndx) {
 
 528               if (str.charAt(chIndx) == '=') {
 
 530                 token = TT_GREATEREQUAL;
 
 533               if (str.charAt(chIndx) == '>') {
 
 536                 if (str.length() > chIndx) {
 
 537                   if (str.charAt(chIndx) == '=') {
 
 539                     token = TT_RSHIFTASSIGN;
 
 551             if (str.length() > chIndx) {
 
 552               if (str.charAt(chIndx) == '=') {
 
 554                 token = TT_LESSEQUAL;
 
 558               if (str.charAt(chIndx) == '<') {
 
 561                 if (str.length() > chIndx) {
 
 562                   if (str.charAt(chIndx) == '=') {
 
 564                     token = TT_LSHIFTASSIGN;
 
 577             if (str.length() > chIndx) {
 
 578               if (str.charAt(chIndx) == '|') {
 
 588             token = TT_AMPERSAND;
 
 589             if (str.length() > chIndx) {
 
 590               if (str.charAt(chIndx) == '&') {
 
 595               if (str.charAt(chIndx) == '=') {
 
 597                 token = TT_ANDASSIGN;
 
 617             throwSyntaxError("unexpected character: '" + ch + "'");
 
 620         if (token == TT_UNDEFINED) {
 
 621           throwSyntaxError("token not found");
 
 628     chIndx = str.length() + 1;
 
 633     if (phpList != null) {
 
 634       if (currentPHPString < phpList.size()) {
 
 635         token = TT_UNDEFINED;
 
 636         temp = (PHPString) phpList.get(currentPHPString++);
 
 637         this.str = temp.getPHPString();
 
 640         this.rowCount = temp.getLineNumber();
 
 641         this.columnCount = 0;
 
 645         token = TT_UNDEFINED;
 
 651   void getIdentifier() {
 
 652     StringBuffer ident = new StringBuffer();
 
 658       token = TT_IDENTIFIER;
 
 661     while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
 
 665     identifier = ident.toString();
 
 668     Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
 
 670       token = i.intValue();
 
 675     StringBuffer inum = new StringBuffer();
 
 684     // determine number conversions:
 
 685     if (firstCh == '0') {
 
 714     if (numFormat == 16) {
 
 715       while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
 
 720       while ((ch >= '0' && ch <= '9') || (ch == '.') || (ch == 'E') || (ch == 'e')) {
 
 721         if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
 
 722           if (ch == '.' && dFlag != ' ') {
 
 725           if ((dFlag == 'E') || (dFlag == 'e')) {
 
 731           if ((ch == '-') || (ch == '+')) {
 
 745         doubleNumber = new Double(inum.toString());
 
 746         token = TT_DOUBLE_NUMBER;
 
 749         longNumber = Long.valueOf(inum.toString(), numFormat);
 
 750         token = TT_INT_NUMBER;
 
 754     } catch (Throwable e) {
 
 755       throwSyntaxError("Number format error: " + inum.toString());
 
 759   public void htmlParse(String input) {
 
 760     boolean lineCommentMode = false;
 
 761     boolean multiLineCommentMode = false;
 
 762     boolean stringMode = false;
 
 764     StringBuffer buf = new StringBuffer();
 
 766     int startLineNumber = 1;
 
 770     boolean phpMode = false;
 
 771     boolean phpFound = false;
 
 773     phpList = new ArrayList();
 
 777       while (i < input.length()) {
 
 778         ch = input.charAt(i++);
 
 782         if ((!phpMode) && ch == '<') {
 
 783           ch2 = input.charAt(i++);
 
 785             ch2 = input.charAt(i++);
 
 786             if (Character.isWhitespace(ch2)) {
 
 791               startLineNumber = lineNumber;
 
 793             } else if (ch2 == 'p') {
 
 794               ch2 = input.charAt(i++);
 
 796                 ch2 = input.charAt(i++);
 
 801                   startLineNumber = lineNumber;
 
 807             } else if (ch2 == 'P') {
 
 808               ch2 = input.charAt(i++);
 
 810                 ch2 = input.charAt(i++);
 
 815                   startLineNumber = lineNumber;
 
 829           if (lineCommentMode && (ch == '\n')) {
 
 830             lineCommentMode = false;
 
 831             // read until end of line
 
 832           } else if ((!stringMode) && (ch == '#')) {
 
 833             // read until end of line
 
 834             lineCommentMode = true;
 
 836           } else if ((!stringMode) && (!multiLineCommentMode) && (ch == '/')) {
 
 837             ch2 = input.charAt(i++);
 
 839               lineCommentMode = true;
 
 841             } else if (ch2 == '*') {
 
 842               multiLineCommentMode = true;
 
 847           } else if (ch == '*' && multiLineCommentMode) {
 
 848             ch2 = input.charAt(i++);
 
 850               multiLineCommentMode = false;
 
 855           } else if (ch == '\\' && stringMode) {
 
 856             ch2 = input.charAt(i++);
 
 862           } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
 
 870           if (lineCommentMode || multiLineCommentMode || stringMode) {
 
 875             ch2 = input.charAt(i++);
 
 879               phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
 
 888         setMarker("No PHP source code found.", lineNumber, PHPParser.INFO);
 
 890         //        for (int j=0;j<phpList.size();j++) {
 
 891         //          String temp = ((PHPString)phpList.get(j)).getPHPString();
 
 892         //          int startIndx = temp.length()-10;
 
 893         //          if (startIndx<0) {
 
 896         //          System.out.println(temp.substring(startIndx)+"?>");
 
 900         //        for(int j=0;j<phpList.size();j++) {
 
 901         //          temp = (PHPString) phpList.get(j);
 
 902         //          parser.start(temp.getPHPString(), temp.getLineNumber());
 
 905     } catch (CoreException e) {
 
 909   public void phpParse(String s, int rowCount) throws CoreException {
 
 914         if (phpList.size() != 0) {
 
 915           this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
 
 920       this.rowCount = rowCount;
 
 921       this.columnCount = 0;
 
 924       if (token != TT_EOF && token != TT_UNDEFINED) {
 
 927       if (token != TT_EOF && token != TT_UNDEFINED) {
 
 928         if (token == TT_ARGCLOSE) {
 
 929           throwSyntaxError("too many closing ')'; end-of-file not reached");
 
 931         if (token == TT_LISTCLOSE) {
 
 932           throwSyntaxError("too many closing '}'; end-of-file not reached");
 
 934         if (token == TT_PARTCLOSE) {
 
 935           throwSyntaxError("too many closing ']'; end-of-file not reached");
 
 938         if (token == TT_ARGOPEN) {
 
 939           throwSyntaxError("read character '('; end-of-file not reached");
 
 941         if (token == TT_LISTOPEN) {
 
 942           throwSyntaxError("read character '{';  end-of-file not reached");
 
 944         if (token == TT_PARTOPEN) {
 
 945           throwSyntaxError("read character '[';  end-of-file not reached");
 
 948         throwSyntaxError("end-of-file not reached");
 
 950     } catch (SyntaxError err) {
 
 954         setMarker(err.getMessage(), err.getLine(), ERROR);
 
 959   public void statementList() throws CoreException {
 
 962       if ((token == TT_LISTCLOSE)
 
 963         || (token == TT_case)
 
 964         || (token == TT_default)
 
 965         || (token == TT_elseif)
 
 966         || (token == TT_endif)
 
 967         || (token == TT_endfor)
 
 968         || (token == TT_endforeach)
 
 969         || (token == TT_endwhile)
 
 970         || (token == TT_endswitch)
 
 972         || (token == TT_UNDEFINED)) {
 
 978   public void compoundStatement() throws CoreException {
 
 979     // '{' [statement-list] '}'
 
 980     if (token == TT_LISTOPEN) {
 
 983       throwSyntaxError("'{' expected in compound-statement.");
 
 985     if (token != TT_LISTCLOSE) {
 
 988     if (token == TT_LISTCLOSE) {
 
 991       throwSyntaxError("'}' expected in compound-statement.");
 
 995   public void statement() throws CoreException {
 
 996     if (token > TT_KEYWORD && token != TT_list) {
 
 997       String keyword = identifier;
 
 998       if (token == TT_include || token == TT_include_once) {
 
1001         if (token == TT_SEMICOLON) {
 
1005             throwSyntaxError("';' character after 'include' or 'include_once' expected.");
 
1009       } else if (token == TT_require || token == TT_require_once) {
 
1013         if (token == TT_SEMICOLON) {
 
1017             throwSyntaxError("';' character after 'require' or 'require_once' expected.");
 
1021       } else if (token == TT_if) {
 
1023         if (token == TT_ARGOPEN) {
 
1026           throwSyntaxError("'(' expected after 'if' keyword.");
 
1029         if (token == TT_ARGCLOSE) {
 
1032           throwSyntaxError("')' expected after 'if' condition.");
 
1037       } else if (token == TT_switch) {
 
1039         if (token == TT_ARGOPEN) {
 
1042           throwSyntaxError("'(' expected after 'switch' keyword.");
 
1045         if (token == TT_ARGCLOSE) {
 
1048           throwSyntaxError("')' expected after 'switch' condition.");
 
1052       } else if (token == TT_for) {
 
1054         if (token == TT_ARGOPEN) {
 
1057           throwSyntaxError("'(' expected after 'for' keyword.");
 
1059         if (token == TT_SEMICOLON) {
 
1063           if (token == TT_SEMICOLON) {
 
1066             throwSyntaxError("';' character after 'for' expected.");
 
1069         if (token == TT_SEMICOLON) {
 
1073           if (token == TT_SEMICOLON) {
 
1076             throwSyntaxError("';' character after 'for' expected.");
 
1079         if (token == TT_ARGCLOSE) {
 
1083           if (token == TT_ARGCLOSE) {
 
1086             throwSyntaxError("')' expected after 'for' condition.");
 
1091       } else if (token == TT_while) {
 
1093         if (token == TT_ARGOPEN) {
 
1096           throwSyntaxError("'(' expected after 'while' keyword.");
 
1099         if (token == TT_ARGCLOSE) {
 
1102           throwSyntaxError("')' expected after 'while' condition.");
 
1106       } else if (token == TT_do) {
 
1108         if (token == TT_LISTOPEN) {
 
1111           throwSyntaxError("'{' expected after 'do' keyword.");
 
1113         if (token != TT_LISTCLOSE) {
 
1116         if (token == TT_LISTCLOSE) {
 
1119           throwSyntaxError("'}' expected after 'do' keyword.");
 
1121         if (token == TT_while) {
 
1123           if (token == TT_ARGOPEN) {
 
1126             throwSyntaxError("'(' expected after 'while' keyword.");
 
1129           if (token == TT_ARGCLOSE) {
 
1132             throwSyntaxError("')' expected after 'while' condition.");
 
1135           throwSyntaxError("'while' expected after 'do' keyword.");
 
1137         if (token == TT_SEMICOLON) {
 
1141             throwSyntaxError("';' expected after do-while statement.");
 
1145       } else if (token == TT_foreach) {
 
1147         if (token == TT_ARGOPEN) {
 
1150           throwSyntaxError("'(' expected after 'foreach' keyword.");
 
1153         if (token == TT_as) {
 
1156           throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
1159         if (token == TT_FOREACH) {
 
1163         if (token == TT_ARGCLOSE) {
 
1166           throwSyntaxError("')' expected after 'foreach' expression.");
 
1171       } else if (token == TT_continue || token == TT_break || token == TT_return) {
 
1173         if (token != TT_SEMICOLON) {
 
1176         if (token == TT_SEMICOLON) {
 
1180             throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
 
1185       } else if (token == TT_echo) {
 
1188         if (token == TT_SEMICOLON) {
 
1192             throwSyntaxError("';' expected after 'echo' statement.");
 
1196       } else if (token == TT_print) {
 
1199         if (token == TT_SEMICOLON) {
 
1203             throwSyntaxError("';' expected after 'print' statement.");
 
1208       } else if (token == TT_global || token == TT_static) {
 
1211         if (token == TT_SEMICOLON) {
 
1215             throwSyntaxError("';' expected after 'global' or 'static' statement.");
 
1220       } else if (token == TT_unset) {
 
1222         if (token == TT_ARGOPEN) {
 
1225           throwSyntaxError("'(' expected after 'unset' keyword.");
 
1228         if (token == TT_ARGCLOSE) {
 
1231           throwSyntaxError("')' expected after 'unset' statement.");
 
1233         if (token == TT_SEMICOLON) {
 
1237             throwSyntaxError("';' expected after 'unset' statement.");
 
1242         //      } else if (token == TT_exit || token == TT_die) {
 
1244         //        if (token != TT_SEMICOLON) {
 
1247         //        if (token == TT_SEMICOLON) {
 
1251         //            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
 
1256       } else if (token == TT_define) {
 
1258         if (token == TT_ARGOPEN) {
 
1261           throwSyntaxError("'(' expected after 'define' keyword.");
 
1264         if (token == TT_COMMA) {
 
1267           throwSyntaxError("',' expected after first 'define' constant.");
 
1270         if (token == TT_ARGCLOSE) {
 
1273           throwSyntaxError("')' expected after 'define' statement.");
 
1275         if (token == TT_SEMICOLON) {
 
1279             throwSyntaxError("';' expected after 'define' statement.");
 
1283       } else if (token == TT_function) {
 
1285         functionDefinition();
 
1287       } else if (token == TT_class) {
 
1293         throwSyntaxError("Unexpected keyword '" + keyword + "'");
 
1296     } else if (token == TT_LISTOPEN) {
 
1297       // compoundStatement
 
1299       if (token != TT_LISTCLOSE) {
 
1302       if (token == TT_LISTCLOSE) {
 
1306         throwSyntaxError("'}' expected.");
 
1309       if (token != TT_SEMICOLON) {
 
1312       if (token == TT_SEMICOLON) {
 
1317           throwSyntaxError("';' expected after expression.");
 
1324   public void classDeclarator() {
 
1326     //identifier 'extends' identifier
 
1327     if (token == TT_IDENTIFIER) {
 
1329       if (token == TT_extends) {
 
1331         if (token == TT_IDENTIFIER) {
 
1334           throwSyntaxError("Class name expected after keyword 'extends'.");
 
1338       throwSyntaxError("Class name expected after keyword 'class'.");
 
1342   public void classBody() throws CoreException {
 
1343     //'{' [class-element-list] '}'
 
1344     if (token == TT_LISTOPEN) {
 
1346       if (token != TT_LISTCLOSE) {
 
1349       if (token == TT_LISTCLOSE) {
 
1352         throwSyntaxError("'}' expected at end of class body.");
 
1355       throwSyntaxError("'{' expected at start of class body.");
 
1359   public void classElementList() throws CoreException {
 
1362     } while (token == TT_function || token == TT_var);
 
1365   public void classElement() throws CoreException {
 
1367     //function-definition
 
1368     if (token == TT_function) {
 
1370       functionDefinition();
 
1371     } else if (token == TT_var) {
 
1375       throwSyntaxError("'function' or 'var' expected.");
 
1379   public void classProperty() {
 
1380     //'var' variable ';'
 
1381     //'var' variable '=' constant ';'
 
1382     if (token == TT_VARIABLE) {
 
1384       if (token == TT_ASSIGN) {
 
1387         if (token == TT_SEMICOLON) {
 
1390           throwSyntaxError("';' expected after variable declaration.");
 
1392       } else if (token == TT_SEMICOLON) {
 
1395         throwSyntaxError("';' or '=' expected after variable declaration.");
 
1398       throwSyntaxError("Variable expected after keyword 'var'.");
 
1402   public void functionDefinition() throws CoreException {
 
1403     functionDeclarator();
 
1404     compoundStatement();
 
1407   public void functionDeclarator() {
 
1408     //identifier '(' [parameter-list] ')'
 
1409     if (token == TT_IDENTIFIER) {
 
1411       if (token == TT_ARGOPEN) {
 
1414         throwSyntaxError("'(' expected in function declaration.");
 
1416       if (token != TT_ARGCLOSE) {
 
1419       if (token != TT_ARGCLOSE) {
 
1420         throwSyntaxError("')' expected in function declaration.");
 
1427   public void parameterList() {
 
1428     //parameter-declaration
 
1429     //parameter-list ',' parameter-declaration
 
1431       parameterDeclaration();
 
1432       if (token != TT_COMMA) {
 
1439   public void parameterDeclaration() {
 
1441     //variable-reference
 
1442     //variable '=' constant
 
1443     if (token == TT_VARIABLE) {
 
1445       if (token == TT_ASSIGN) {
 
1453   public void labeledStatementList() throws CoreException {
 
1454     if (token != TT_case && token != TT_default) {
 
1455       throwSyntaxError("'case' or 'default' expected.");
 
1458       if (token == TT_case) {
 
1461         if (token == TT_DDOT) {
 
1464         } else if (token == TT_SEMICOLON) {
 
1465           setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
 
1469           throwSyntaxError("':' character after 'case' constant expected.");
 
1471       } else { // TT_default 
 
1473         if (token == TT_DDOT) {
 
1477           throwSyntaxError("':' character after 'default' expected.");
 
1480     } while (token == TT_case || token == TT_default);
 
1483   //  public void labeledStatement() {
 
1484   //    if (token == TT_case) {
 
1487   //      if (token == TT_DDOT) {
 
1491   //        throwSyntaxError("':' character after 'case' constant expected.");
 
1494   //    } else if (token == TT_default) {
 
1496   //      if (token == TT_DDOT) {
 
1500   //        throwSyntaxError("':' character after 'default' expected.");
 
1506   public void expressionStatement() {
 
1509   public void inclusionStatement() {
 
1512   //  public void compoundStatement() {
 
1515   //  public void selectionStatement() {
 
1518   //  public void iterationStatement() {
 
1521   //  public void jumpStatement() {
 
1524   //  public void outputStatement() {
 
1527   //  public void scopeStatement() {
 
1530   //  public void flowStatement() {
 
1533   //  public void definitionStatement() {
 
1536   public void ifStatement() throws CoreException {
 
1537     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
 
1538     if (token == TT_DDOT) {
 
1544           if (token == TT_DDOT) {
 
1548             if (token == TT_if) { //'else if'
 
1550               elseifStatementList();
 
1552               throwSyntaxError("':' expected after 'else'.");
 
1558           elseifStatementList();
 
1562       if (token != TT_endif) {
 
1563         throwSyntaxError("'endif' expected.");
 
1566       if (token != TT_SEMICOLON) {
 
1567         throwSyntaxError("';' expected after if-statement.");
 
1571       // statement [else-statement]
 
1573       if (token == TT_elseif) {
 
1575         if (token == TT_ARGOPEN) {
 
1578           throwSyntaxError("'(' expected after 'elseif' keyword.");
 
1581         if (token == TT_ARGCLOSE) {
 
1584           throwSyntaxError("')' expected after 'elseif' condition.");
 
1587       } else if (token == TT_else) {
 
1593   public void elseifStatementList() throws CoreException {
 
1599           if (token == TT_DDOT) {
 
1604             if (token == TT_if) { //'else if'
 
1607               throwSyntaxError("':' expected after 'else'.");
 
1620   public void elseifStatement() throws CoreException {
 
1621     if (token == TT_ARGOPEN) {
 
1624       if (token != TT_ARGOPEN) {
 
1625         throwSyntaxError("')' expected in else-if-statement.");
 
1628       if (token != TT_DDOT) {
 
1629         throwSyntaxError("':' expected in else-if-statement.");
 
1636   public void switchStatement() throws CoreException {
 
1637     if (token == TT_DDOT) {
 
1638       // ':' [labeled-statement-list] 'endswitch' ';'
 
1640       labeledStatementList();
 
1641       if (token != TT_endswitch) {
 
1642         throwSyntaxError("'endswitch' expected.");
 
1645       if (token != TT_SEMICOLON) {
 
1646         throwSyntaxError("';' expected after switch-statement.");
 
1650       // '{' [labeled-statement-list] '}'
 
1651       if (token != TT_LISTOPEN) {
 
1652         throwSyntaxError("'{' expected in switch statement.");
 
1655       if (token != TT_LISTCLOSE) {
 
1656         labeledStatementList();
 
1658       if (token != TT_LISTCLOSE) {
 
1659         throwSyntaxError("'}' expected in switch statement.");
 
1666   public void forStatement() throws CoreException {
 
1667     if (token == TT_DDOT) {
 
1670       if (token != TT_endfor) {
 
1671         throwSyntaxError("'endfor' expected.");
 
1674       if (token != TT_SEMICOLON) {
 
1675         throwSyntaxError("';' expected after for-statement.");
 
1683   public void whileStatement() throws CoreException {
 
1684     // ':' statement-list 'endwhile' ';'
 
1685     if (token == TT_DDOT) {
 
1688       if (token != TT_endwhile) {
 
1689         throwSyntaxError("'endwhile' expected.");
 
1692       if (token != TT_SEMICOLON) {
 
1693         throwSyntaxError("';' expected after while-statement.");
 
1701   public void foreachStatement() throws CoreException {
 
1702     if (token == TT_DDOT) {
 
1705       if (token != TT_endforeach) {
 
1706         throwSyntaxError("'endforeach' expected.");
 
1709       if (token != TT_SEMICOLON) {
 
1710         throwSyntaxError("';' expected after foreach-statement.");
 
1718   public void exitStatus() {
 
1719     if (token == TT_ARGOPEN) {
 
1722       throwSyntaxError("'(' expected in 'exit-status'.");
 
1724     if (token != TT_ARGCLOSE) {
 
1727     if (token == TT_ARGCLOSE) {
 
1730       throwSyntaxError("')' expected after 'exit-status'.");
 
1734   public void expressionList() {
 
1737       if (token == TT_COMMA) {
 
1745   public void expression() {
 
1746     //    if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
 
1749     logicalinclusiveorExpression();
 
1750     //      while (token != TT_SEMICOLON) {
 
1756   public void postfixExpression() {
 
1758     boolean castFlag = false;
 
1773       case TT_STRING_CONSTANT :
 
1776       case TT_INTERPOLATED_STRING :
 
1781         if (token == TT_IDENTIFIER) {
 
1782           // check if identifier is a type:
 
1784           String str = identifier.toLowerCase();
 
1785           for (int i = 0; i < PHP_TYPES.length; i++) {
 
1786             if (PHP_TYPES[i].equals(str)) {
 
1793             if (token != TT_ARGCLOSE) {
 
1794               throwSyntaxError(") expected after cast-type '" + ident + "'.");
 
1804         if (token != TT_ARGCLOSE) {
 
1805           throwSyntaxError(") expected in postfix-expression.");
 
1809       case TT_DOUBLE_NUMBER :
 
1812       case TT_INT_NUMBER :
 
1818         if (token == TT_LISTOPEN) {
 
1821           if (token != TT_LISTCLOSE) {
 
1822             throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
 
1827       case TT_IDENTIFIER :
 
1830         if (token == TT_ARGOPEN) {
 
1832           if (token != TT_ARGCLOSE) {
 
1834             if (token != TT_ARGCLOSE) {
 
1835               throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
 
1843         if (token == TT_ARGOPEN) {
 
1845           if (token == TT_COMMA) {
 
1849           if (token != TT_ARGCLOSE) {
 
1850             throwSyntaxError("')' expected after 'list' keyword.");
 
1853           //          if (token == TT_SET) {
 
1855           //            logicalinclusiveorExpression();
 
1858           throwSyntaxError("'(' expected after 'list' keyword.");
 
1863         //        if (token != TT_SEMICOLON) {
 
1866         //        if (token == TT_SEMICOLON) {
 
1870         //            throwSyntaxError("';' expected after 'exit' expression.");
 
1876         //        if (token != TT_SEMICOLON) {
 
1879         //        if (token == TT_SEMICOLON) {
 
1883         //            throwSyntaxError("';' expected after 'die' expression.");
 
1890         //        if (token == TT_ARGOPEN) {
 
1892         //          if (token == TT_COMMA) {
 
1895         //          expressionList();
 
1896         //          if (token != TT_ARGCLOSE) {
 
1897         //            throwSyntaxError("')' expected after 'list' keyword.");
 
1900         //          if (token == TT_SET) {
 
1902         //            logicalinclusiveorExpression();
 
1905         //          throwSyntaxError("'(' expected after 'list' keyword.");
 
1909     boolean while_flag = true;
 
1915           if (token != TT_PARTCLOSE) {
 
1916             throwSyntaxError("] expected in postfix-expression.");
 
1926               //              if (token == TT_ARGOPEN) {
 
1928               //                expressionList();
 
1929               //                if (token != TT_ARGCLOSE) {
 
1930               //                  throwSyntaxError(") expected after variable '" + ident + "'.");
 
1935             case TT_IDENTIFIER :
 
1938               if (token == TT_ARGOPEN) {
 
1941                 if (token != TT_ARGCLOSE) {
 
1942                   throwSyntaxError(") expected after identifier '" + ident + "'.");
 
1950               if (token != TT_LISTCLOSE) {
 
1951                 throwSyntaxError("} expected in postfix-expression.");
 
1956               throwSyntaxError("Syntax error after '->' token.");
 
1968     } while (while_flag);
 
1971   public void unaryExpression() {
 
1981         //'&' '*' '+' '-' '~' '!' 
 
2007         postfixExpression();
 
2011   public void castExpression() {
 
2012     //    if (token == TT_ARGOPEN) {
 
2015     //      if (token != TT_ARGCLOSE) {
 
2016     //        throwSyntaxError(") expected after cast-expression.");
 
2023   public void typeName() {
 
2024     //'string' 'unset' 'array' 'object'
 
2026     //'real' 'double' 'float'
 
2029     if (token == TT_IDENTIFIER) {
 
2031       String str = identifier.toLowerCase();
 
2033       for (int i = 0; i < PHP_TYPES.length; i++) {
 
2034         if (PHP_TYPES[i].equals(str)) {
 
2039     throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
 
2042   public void assignExpression() {
 
2044     if (token == TT_ASSIGN) { // =
 
2046       logicalinclusiveorExpression();
 
2047     } else if (token == TT_DOTASSIGN) { // .=
 
2049       logicalinclusiveorExpression();
 
2050     } else if (token == TT_FOREACH) { // =>
 
2052       logicalinclusiveorExpression();
 
2053     } else if (token == TT_ADDTO) { // +=
 
2055       logicalinclusiveorExpression();
 
2056     } else if (token == TT_SUBTRACTFROM) { // -=
 
2058       logicalinclusiveorExpression();
 
2059     } else if (token == TT_TIMESBY) { // *=
 
2061       logicalinclusiveorExpression();
 
2062     } else if (token == TT_DIVIDEBY) { // *=
 
2064       logicalinclusiveorExpression();
 
2065     } else if (token == TT_MODASSIGN) { // %=
 
2067       logicalinclusiveorExpression();
 
2068     } else if (token == TT_ANDASSIGN) { // &=
 
2070       logicalinclusiveorExpression();
 
2071     } else if (token == TT_POWASSIGN) { // ^=
 
2073       logicalinclusiveorExpression();
 
2074     } else if (token == TT_LSHIFTASSIGN) { // <<=
 
2076       logicalinclusiveorExpression();
 
2077     } else if (token == TT_RSHIFTASSIGN) { // >>=
 
2079       logicalinclusiveorExpression();
 
2080     } else if (token == TT_TILDEASSIGN) { // ~=
 
2082       logicalinclusiveorExpression();
 
2086   public void multiplicativeExpression() {
 
2089       if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
 
2096   public void concatenationExpression() {
 
2098       multiplicativeExpression();
 
2099       if (token != TT_DOT) {
 
2106   public void additiveExpression() {
 
2108       concatenationExpression();
 
2109       if (token != TT_ADD && token != TT_SUBTRACT) {
 
2116   public void shiftExpression() {
 
2118       additiveExpression();
 
2119       if (token != TT_LSHIFT && token != TT_RSHIFT) {
 
2126   public void relationalExpression() {
 
2129       if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
 
2136   public void identicalExpression() {
 
2138       relationalExpression();
 
2139       if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
 
2146   public void equalityExpression() {
 
2148       identicalExpression();
 
2149       if (token != TT_EQUAL && token != TT_UNEQUAL) {
 
2156   public void ternaryExpression() {
 
2157     equalityExpression();
 
2158     if (token == TT_QUESTIONMARK) {
 
2161       if (token == TT_DDOT) {
 
2165         throwSyntaxError("':' expected in ternary operator '? :'.");
 
2170   public void andExpression() {
 
2172       ternaryExpression();
 
2173       if (token != TT_AMPERSAND) {
 
2180   public void exclusiveorExpression() {
 
2183       if (token != TT_POW) {
 
2190   public void inclusiveorExpression() {
 
2192       exclusiveorExpression();
 
2193       if (token != TT_LINE) {
 
2200   public void booleanandExpression() {
 
2202       inclusiveorExpression();
 
2203       if (token != TT_AND) {
 
2210   public void booleanorExpression() {
 
2212       booleanandExpression();
 
2213       if (token != TT_OR) {
 
2220   public void logicalandExpression() {
 
2222       booleanorExpression();
 
2223       if (token != TT_and) {
 
2230   public void logicalexclusiveorExpression() {
 
2232       logicalandExpression();
 
2233       if (token != TT_xor) {
 
2240   public void logicalinclusiveorExpression() {
 
2242       logicalexclusiveorExpression();
 
2243       if (token != TT_or) {
 
2250   //  public void assignmentExpression() {
 
2251   //    if (token == TT_VARIABLE) {
 
2253   //      if (token == TT_SET) {
 
2255   //        logicalinclusiveorExpression();
 
2258   //      logicalinclusiveorExpression();
 
2262   public void variableList() {
 
2265       if (token == TT_COMMA) {
 
2273   public void variable() {
 
2274     if (token == TT_VARIABLE) {
 
2277       throwSyntaxError("$-variable expected in variable-list.");
 
2281   public void constant() {
 
2286           case TT_DOUBLE_NUMBER :
 
2289           case TT_INT_NUMBER :
 
2293             throwSyntaxError("Constant expected after '+' presign.");
 
2299           case TT_DOUBLE_NUMBER :
 
2302           case TT_INT_NUMBER :
 
2306             throwSyntaxError("Constant expected after '-' presign.");
 
2318       case TT_STRING_CONSTANT :
 
2321       case TT_INTERPOLATED_STRING :
 
2324       case TT_DOUBLE_NUMBER :
 
2327       case TT_INT_NUMBER :
 
2331         throwSyntaxError("Constant expected.");