improved/refactored php syntax parser
authorkhartlage <khartlage>
Tue, 10 Dec 2002 21:20:42 +0000 (21:20 +0000)
committerkhartlage <khartlage>
Tue, 10 Dec 2002 21:20:42 +0000 (21:20 +0000)
net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/PHPeclipsePlugin.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPExternalParserAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParserAction.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/PHPParser.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/SyntaxError.java [new file with mode: 0644]

index 7770048..5675731 100644 (file)
@@ -11,7 +11,7 @@ import org.eclipse.core.runtime.CoreException;
 
 import junit.framework.TestCase;
 
-import net.sourceforge.phpeclipse.phpeditor.PHPParser;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPParser;
 
 /**
  *  Tests the php parser
@@ -34,6 +34,15 @@ public class PHPParserTestCase extends TestCase {
     checkHTML("<?php phpinfo(); ?> foo <?php phpinfo(); ?>");
     checkHTML(" <?php //this is a line comment ?>");
     
+    checkPHP("($a==\"b\") || (c($this->x)==\"d\");");
+    checkPHP("(substr($this->file, 0, 2) == \"MM\");");
+    checkPHP("(substr($this->file, 0, 2) == \"MM\") || substr($this->file, 0, 2) == \"II\";");
+    checkPHP("return (substr($this->file, 0, 2) == \"MM\") || substr($this->file, 0, 2) == \"II\";");
+    checkPHP("$this->highlightfile->linkscripts{$category}");
+    checkPHP("$code = call_user_method($this->highlightfile->linkscripts{$category}, $this->highlightfile, $oldword, $this->output_module)");
+    checkPHP("$this->startmap[$startcurrtag]();");
+    checkPHP("new $this->startmap[$startcurrtag]();");
+    checkPHP("$this->highlightfile = new $this->startmap[$startcurrtag]();");
     checkPHP("echo \"Test\", \"me\";");
     checkPHP("print (\"Test me\");");
     checkPHP("$s = <<<HEREDOC \n dskjfhskj\n \n\nHEREDOC;"); 
@@ -98,13 +107,16 @@ public class PHPParserTestCase extends TestCase {
 
   private void checkPHP(String strEval) {
     try {
-      parser.phpParse(strEval, 1);
+      parser.phpParserTester(strEval, 1);
     } catch (CoreException e) {
     }
   }
 
   private void checkHTML(String strEval) {
-    parser.htmlParse(strEval);
+    try {
+      parser.parse(strEval);
+    } catch (CoreException e) {
+    }
   }
 
   /**
index dc81130..e120ce4 100644 (file)
@@ -259,9 +259,9 @@ public class PHPeclipsePlugin extends AbstractUIPlugin implements IPreferenceCon
  
     }
 
-    store.setDefault(PHP_PARSER_DEFAULT, PHP_INTERNAL_PARSER);
-    store.setDefault(PHP_INTERNAL_PARSER, "true");
-    store.setDefault(PHP_EXTERNAL_PARSER, "false");
+    store.setDefault(PHP_PARSER_DEFAULT, PHP_EXTERNAL_PARSER);
+    store.setDefault(PHP_INTERNAL_PARSER, "false");
+    store.setDefault(PHP_EXTERNAL_PARSER, "true");
     
     store.setDefault(PHP_PARSE_ON_SAVE, "true");
     // php syntax highlighting
index 1e1c770..e542441 100644 (file)
@@ -13,7 +13,8 @@ package net.sourceforge.phpeclipse.actions;
 
 import java.util.Iterator;
 
-import net.sourceforge.phpeclipse.phpeditor.PHPParser;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPParser;
+
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.jface.action.IAction;
index f4cc8a9..515f19f 100644 (file)
@@ -18,6 +18,8 @@ import java.util.ArrayList;
 import java.util.List;
 
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.phpparser.PHPParser;
+
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.CoreException;
@@ -141,9 +143,9 @@ public class PHPParserAction extends TextEditorAction {
 
   protected void parse(InputStream iStream) {
 
-    StringBuffer buf = new StringBuffer();
+    StringBuffer buf = new StringBuffer(); 
     int c0;
-    try {
+    try { 
       while ((c0 = iStream.read()) != (-1)) {
         buf.append((char) c0);
       }
@@ -153,6 +155,9 @@ public class PHPParserAction extends TextEditorAction {
     String input = buf.toString();
 
     PHPParser parser = new PHPParser(fileToParse);
-    parser.htmlParse(input);
+    try {
+      parser.parse(input);
+    } catch (CoreException e) {
+    }
   }
 }
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/PHPParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/PHPParser.java
new file mode 100644 (file)
index 0000000..981cd7f
--- /dev/null
@@ -0,0 +1,3347 @@
+/**********************************************************************
+Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+    Klaus Hartlage - www.eclipseproject.de
+**********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.phpparser;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.actions.PHPStartApacheAction;
+import net.sourceforge.phpeclipse.phpeditor.PHPString;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+
+public class PHPParser extends PHPKeywords {
+  // strings for external parser call
+  private static final String PARSE_ERROR_STRING = "Parse error"; //$NON-NLS-1$
+  private static final String PARSE_WARNING_STRING = "Warning"; //$NON-NLS-1$
+
+  public static final int ERROR = 2;
+  public static final int WARNING = 1;
+  public static final int INFO = 0;
+  private IFile fileToParse;
+  private ArrayList phpList;
+
+  private int currentPHPString;
+  private boolean phpEnd;
+
+  private static HashMap keywordMap = null;
+  private String str;
+
+  // current character
+  char ch;
+  // current token
+  int token;
+
+  // row counter for syntax errors:
+  int rowCount;
+  // column counter for syntax errors:
+  int columnCount;
+
+  int chIndx;
+
+  // current identifier
+  String identifier;
+
+  Long longNumber;
+  Double doubleNumber;
+  private boolean phpMode;
+
+  final static int TT_EOF = 0;
+  final static int TT_UNDEFINED = 1;
+  final static int TT_HTML = 2;
+
+  final static int TT_MOD = 30;
+  final static int TT_NOT = 31;
+  final static int TT_DOT = 32;
+  final static int TT_POW = 33;
+  final static int TT_DIV = 34;
+  final static int TT_MULTIPLY = 35;
+  final static int TT_SUBTRACT = 36;
+  final static int TT_ADD = 37;
+  final static int TT_EQUAL = 38;
+  final static int TT_UNEQUAL = 39;
+  final static int TT_GREATER = 40;
+  final static int TT_GREATEREQUAL = 41;
+  final static int TT_LESS = 42;
+  final static int TT_LESSEQUAL = 43;
+  final static int TT_AND = 44;
+  final static int TT_OR = 45;
+  final static int TT_HASH = 46;
+  final static int TT_DDOT = 47;
+  final static int TT_DOTASSIGN = 48;
+
+  final static int TT_ASSIGN = 49;
+  final static int TT_REF = 50;
+  final static int TT_FOREACH = 51;
+  final static int TT_AMPERSAND = 52;
+  final static int TT_DOLLARLISTOPEN = 53;
+  final static int TT_TILDE = 54;
+  final static int TT_TILDEASSIGN = 55;
+  final static int TT_MODASSIGN = 56;
+  final static int TT_POWASSIGN = 57;
+  final static int TT_RSHIFTASSIGN = 58;
+  final static int TT_LSHIFTASSIGN = 59;
+  final static int TT_ANDASSIGN = 60;
+  final static int TT_QUESTIONMARK = 61;
+  final static int TT_DDOT2 = 62;
+  final static int TT_AT = 63;
+  // final static int TT_HEREDOC = 64;
+
+  final static int TT_DOLLAROPEN = 127;
+  final static int TT_ARGOPEN = 128;
+  final static int TT_ARGCLOSE = 129;
+  final static int TT_LISTOPEN = 130;
+  final static int TT_LISTCLOSE = 131;
+  final static int TT_PARTOPEN = 132;
+  final static int TT_PARTCLOSE = 133;
+  final static int TT_COMMA = 134;
+
+  final static int TT_STRING = 136;
+  final static int TT_IDENTIFIER = 138;
+  final static int TT_DIGIT = 139;
+  final static int TT_SEMICOLON = 140;
+  final static int TT_SLOT = 141;
+  final static int TT_SLOTSEQUENCE = 142;
+  final static int TT_DECREMENT = 144;
+  final static int TT_INCREMENT = 145;
+  final static int TT_ADDTO = 146;
+  final static int TT_DIVIDEBY = 147;
+  final static int TT_SUBTRACTFROM = 148;
+  final static int TT_TIMESBY = 149;
+  final static int TT_VARIABLE = 150;
+  final static int TT_INT_NUMBER = 151;
+  final static int TT_DOUBLE_NUMBER = 152;
+  final static int TT_INTERPOLATED_STRING = 153;
+  final static int TT_STRING_CONSTANT = 154;
+
+  final static int TT_LSHIFT = 155;
+  final static int TT_RSHIFT = 156;
+  final static int TT_EX_EQUAL = 157;
+  final static int TT_EX_UNEQUAL = 158;
+  final static int TT_LINE = 159;
+  //  final static int TT_AT = 153; // @
+  /**
+   *  Class Constructor.
+   *
+   *@param  s
+   *@param  sess  Description of Parameter
+   *@see
+   */
+  public PHPParser(IFile fileToParse) {
+    if (keywordMap == null) {
+      keywordMap = new HashMap();
+      for (int i = 0; i < PHP_KEYWORS.length; i++) {
+        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
+      }
+    }
+    this.currentPHPString = 0;
+    this.fileToParse = fileToParse;
+    this.phpList = null;
+    this.str = "";
+    this.token = TT_EOF;
+    this.chIndx = 0;
+    this.rowCount = 1;
+    this.columnCount = 0;
+    this.phpEnd = false;
+
+    //   getNextToken();
+  }
+
+  /**
+   * Create marker for the parse error
+   */
+  private void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
+    setMarker(fileToParse, message, lineNumber, errorLevel);
+  }
+
+  public static void setMarker(IFile file, String message, int lineNumber, int errorLevel) throws CoreException {
+
+    Hashtable attributes = new Hashtable();
+    MarkerUtilities.setMessage(attributes, message);
+    switch (errorLevel) {
+      case ERROR :
+        attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
+        break;
+      case WARNING :
+        attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
+        break;
+      case INFO :
+        attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
+        break;
+    }
+    MarkerUtilities.setLineNumber(attributes, lineNumber);
+    MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
+  }
+
+  private void throwSyntaxError(String error) {
+
+    if (str.length() < chIndx) {
+      chIndx--;
+    }
+    // read until end-of-line
+    int eol = chIndx;
+    while (str.length() > eol) {
+      ch = str.charAt(eol++);
+      if (ch == '\n') {
+        eol--;
+        break;
+      }
+    }
+    throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error);
+  }
+
+  private void throwSyntaxError(String error, int startRow) {
+
+    throw new SyntaxError(startRow, 0, " ", error);
+  }
+
+  /**
+   *  Method Declaration.
+   *
+   *@see
+   */
+  private void getChar() {
+    if (str.length() > chIndx) {
+      ch = str.charAt(chIndx++);
+
+      return;
+    }
+
+    chIndx = str.length() + 1;
+    ch = ' ';
+    //  token = TT_EOF;
+    phpEnd = true;
+  }
+
+  private void getNextToken_OldVersion() throws CoreException {
+    phpEnd = false;
+
+    while (str.length() > chIndx) {
+      ch = str.charAt(chIndx++);
+      token = TT_UNDEFINED;
+      if (ch == '\n') {
+        rowCount++;
+        columnCount = chIndx;
+        continue; // while loop
+      }
+      if (str.length() == chIndx) {
+        phpEnd = true;
+      }
+      if (!Character.isWhitespace(ch)) {
+        if (ch == '$') {
+          if (str.length() > chIndx) {
+            if (str.charAt(chIndx) == '{') {
+              chIndx++;
+              token = TT_DOLLAROPEN;
+              return;
+            }
+          }
+          getIdentifier();
+          return;
+        }
+        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$')) {
+          getIdentifier();
+          return;
+        }
+        if (ch >= '0' && ch <= '9') {
+          getNumber();
+          return;
+        }
+        if (ch == '/') {
+          if (str.length() > chIndx) {
+            if (str.charAt(chIndx) == '/') {
+              chIndx++;
+              // read comment until end of line:
+              while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
+                chIndx++;
+              }
+              continue;
+            } else if (str.charAt(chIndx) == '*') {
+              chIndx++;
+              // multi line comment:
+              while (str.length() > chIndx) {
+                if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') {
+                  chIndx += 2;
+                  break;
+                }
+                ch = str.charAt(chIndx++);
+                if (ch == '\n') {
+                  rowCount++;
+                  columnCount = chIndx;
+                }
+              }
+              continue;
+            }
+          }
+        } else if (ch == '#') {
+          // read comment until end of line:
+          while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
+            chIndx++;
+          }
+          continue;
+        } else if (ch == '"') {
+          // read string until end
+          boolean openString = true;
+          while (str.length() > chIndx) {
+            ch = str.charAt(chIndx++);
+            if (ch == '\\') {
+              if (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+              }
+            } else if (ch == '"') {
+              openString = false;
+              break;
+            } else if (ch == '\n') {
+              rowCount++;
+              columnCount = chIndx;
+            }
+          }
+          if (openString) {
+            throwSyntaxError("Open string character '\"' at end of file.");
+          }
+          token = TT_INTERPOLATED_STRING;
+          return;
+        } else if (ch == '\'') {
+          // read string until end
+          boolean openString = true;
+          int startRow = rowCount;
+          while (str.length() > chIndx) {
+            ch = str.charAt(chIndx++);
+            if (ch == '\\') {
+              if (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+              }
+            } else if (ch == '\'') {
+              openString = false;
+              break;
+            } else if (ch == '\n') {
+              rowCount++;
+              columnCount = chIndx;
+            }
+          }
+          if (openString) {
+            throwSyntaxError("Open string character \"'\" at end of file.", startRow);
+          }
+          token = TT_STRING_CONSTANT;
+          return;
+        } else if (ch == '`') {
+          // read string until end
+          boolean openString = true;
+          int startRow = rowCount;
+          while (str.length() > chIndx) {
+            ch = str.charAt(chIndx++);
+            if (ch == '\\') {
+              if (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+              }
+            } else if (ch == '`') {
+              openString = false;
+              break;
+            } else if (ch == '\n') {
+              rowCount++;
+              columnCount = chIndx;
+            }
+          }
+          if (openString) {
+            throwSyntaxError("Open string character \"`\" at end of file.", startRow);
+          }
+          setMarker("Other string delimiters prefered (found \"`\").", rowCount, PHPParser.INFO);
+          token = TT_STRING_CONSTANT;
+          return;
+        }
+
+        switch (ch) {
+
+          case '(' :
+            token = TT_ARGOPEN;
+
+            break;
+          case ')' :
+            token = TT_ARGCLOSE;
+
+            break;
+          case '{' :
+            token = TT_LISTOPEN;
+
+            break;
+          case '}' :
+            token = TT_LISTCLOSE;
+
+            break;
+          case '[' :
+            token = TT_PARTOPEN;
+
+            break;
+          case ']' :
+            token = TT_PARTCLOSE;
+
+            break;
+          case ',' :
+            token = TT_COMMA;
+
+            break;
+          case '?' :
+            token = TT_QUESTIONMARK;
+            break;
+          case '@' :
+            token = TT_AT;
+            break;
+          case '~' :
+            token = TT_TILDE;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_TILDEASSIGN;
+
+                break;
+              }
+            }
+            break;
+          case '.' :
+            token = TT_DOT;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_DOTASSIGN;
+
+                break;
+              }
+            }
+
+            break;
+          case '"' :
+            token = TT_STRING;
+
+            break;
+          case '%' :
+            token = TT_MOD;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_MODASSIGN;
+
+                break;
+              }
+            }
+            break;
+          case ';' :
+            token = TT_SEMICOLON;
+
+            break;
+          case '^' :
+            token = TT_POW;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_POWASSIGN;
+
+                break;
+              }
+            }
+            break;
+          case '/' :
+            token = TT_DIV;
+
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_DIVIDEBY;
+
+                break;
+              }
+            }
+
+            break;
+          case '*' :
+            token = TT_MULTIPLY;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '*') {
+                chIndx++;
+                token = TT_POW;
+
+                break;
+              }
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_TIMESBY;
+
+                break;
+              }
+            }
+
+            break;
+          case '+' :
+            token = TT_ADD;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '+') {
+                chIndx++;
+                token = TT_INCREMENT;
+
+                break;
+              }
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_ADDTO;
+
+                break;
+              }
+            }
+            break;
+          case '-' :
+            token = TT_SUBTRACT;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '-') {
+                chIndx++;
+                token = TT_DECREMENT;
+
+                break;
+              }
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_SUBTRACTFROM;
+
+                break;
+              }
+              if (str.charAt(chIndx) == '>') {
+                chIndx++;
+                token = TT_REF;
+
+                break;
+              }
+            }
+
+            break;
+          case '=' :
+            token = TT_ASSIGN;
+
+            if (str.length() > chIndx) {
+              ch = str.charAt(chIndx);
+
+              if (ch == '=') {
+                chIndx++;
+                token = TT_EQUAL;
+                if (str.length() > chIndx) {
+                  ch = str.charAt(chIndx);
+
+                  if (ch == '=') {
+                    chIndx++;
+                    token = TT_EX_EQUAL;
+                  }
+                }
+                break;
+              }
+              if (ch == '>') {
+                chIndx++;
+                token = TT_FOREACH;
+
+                break;
+              }
+            }
+
+            break;
+          case '!' :
+            token = TT_NOT;
+
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_UNEQUAL;
+                if (str.length() > chIndx) {
+                  ch = str.charAt(chIndx);
+
+                  if (ch == '=') {
+                    chIndx++;
+                    token = TT_EX_UNEQUAL;
+                  }
+                }
+                break;
+              }
+            }
+
+            break;
+          case '>' :
+            token = TT_GREATER;
+
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_GREATEREQUAL;
+                break;
+              }
+              if (str.charAt(chIndx) == '>') {
+                chIndx++;
+                token = TT_RSHIFT;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_RSHIFTASSIGN;
+                    break;
+                  }
+                }
+                break;
+              }
+            }
+
+            break;
+          case '<' :
+            token = TT_LESS;
+
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_LESSEQUAL;
+
+                break;
+              }
+              if (str.charAt(chIndx) == '<') {
+                chIndx++;
+                token = TT_LSHIFT;
+                if (str.charAt(chIndx) == '<') {
+                  // heredoc
+                  int startRow = rowCount;
+                  if (str.length() > chIndx) {
+
+                    ch = str.charAt(++chIndx);
+                    if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_')) {
+                      chIndx++;
+                      getIdentifier();
+                      token = TT_STRING_CONSTANT;
+                      while (str.length() > chIndx) {
+                        ch = str.charAt(chIndx++);
+                        if (ch == '\n') {
+                          if (str.length() >= chIndx + identifier.length()) {
+                            if (str.substring(chIndx, chIndx + identifier.length()).equals(identifier)) {
+                              chIndx += identifier.length();
+                              return;
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                  throwSyntaxError("Open heredoc syntax after operator '<<<'.", startRow);
+                } else if (str.charAt(chIndx) == '=') {
+                  chIndx++;
+                  token = TT_LSHIFTASSIGN;
+                  break;
+                }
+                break;
+              }
+            }
+
+            break;
+
+          case '|' :
+            token = TT_LINE;
+
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '|') {
+                chIndx++;
+                token = TT_OR;
+
+                break;
+              }
+            }
+
+            break;
+          case '&' :
+            token = TT_AMPERSAND;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == '&') {
+                chIndx++;
+                token = TT_AND;
+                break;
+              }
+              if (str.charAt(chIndx) == '=') {
+                chIndx++;
+                token = TT_ANDASSIGN;
+                break;
+              }
+              break;
+            }
+
+            break;
+          case ':' :
+            token = TT_DDOT;
+            if (str.length() > chIndx) {
+              if (str.charAt(chIndx) == ':') {
+                chIndx++;
+                token = TT_DDOT2;
+              }
+            }
+            break;
+          case '#' :
+            token = TT_HASH;
+
+            break;
+            //          case '@' :
+            //            token = TT_AT;
+            //
+            //            break;
+          default :
+            throwSyntaxError("unexpected character: '" + ch + "'");
+        }
+
+        if (token == TT_UNDEFINED) {
+          throwSyntaxError("token not found");
+        }
+
+        return;
+      }
+    }
+
+    chIndx = str.length() + 1;
+    ch = ' ';
+    token = TT_EOF;
+    phpEnd = true;
+    PHPString temp;
+    if (phpList != null) {
+      if (currentPHPString < phpList.size()) {
+        token = TT_UNDEFINED;
+        temp = (PHPString) phpList.get(currentPHPString++);
+        this.str = temp.getPHPString();
+        this.token = TT_EOF;
+        this.chIndx = 0;
+        this.rowCount = temp.getLineNumber();
+        this.columnCount = 0;
+        getNextToken();
+        phpEnd = true;
+      } else {
+        token = TT_UNDEFINED;
+        return;
+      }
+    }
+  }
+  /**
+   * gets the next token from input
+   */
+  private void getNextToken() throws CoreException {
+    boolean phpFound = false;
+    char ch2;
+
+    phpEnd = false;
+    try {
+      if (!phpMode) {
+
+        while (str.length() > chIndx) {
+          token = TT_UNDEFINED;
+          ch = str.charAt(chIndx++);
+
+          if (ch == '\n') {
+            rowCount++;
+          }
+          if (ch == '<') {
+            ch2 = str.charAt(chIndx++);
+            if (ch2 == '?') {
+              ch2 = str.charAt(chIndx++);
+              if (Character.isWhitespace(ch2)) {
+                // php start 
+                phpMode = true;
+                phpFound = true;
+                break;
+              } else if (ch2 == 'p') {
+                ch2 = str.charAt(chIndx++);
+                if (ch2 == 'h') {
+                  ch2 = str.charAt(chIndx++);
+                  if (ch2 == 'p') {
+                    phpMode = true;
+                    phpFound = true;
+                    break;
+                  }
+                  chIndx--;
+                }
+                chIndx--;
+              } else if (ch2 == 'P') {
+                ch2 = str.charAt(chIndx++);
+                if (ch2 == 'H') {
+                  ch2 = str.charAt(chIndx++);
+                  if (ch2 == 'P') {
+                    phpMode = true;
+                    phpFound = true;
+                    break;
+                  }
+                  chIndx--;
+                }
+                chIndx--;
+              }
+              chIndx--;
+            }
+            chIndx--;
+          }
+        }
+
+      }
+
+      if (phpMode) {
+        while (str.length() > chIndx) {
+          ch = str.charAt(chIndx++);
+          token = TT_UNDEFINED;
+          if (ch == '\n') {
+            rowCount++;
+            columnCount = chIndx;
+            continue; // while loop
+          }
+          if (str.length() == chIndx) {
+            phpEnd = true;
+          }
+          if (!Character.isWhitespace(ch)) {
+            if (ch == '$') {
+              if (str.length() > chIndx) {
+                if (str.charAt(chIndx) == '{') {
+                  chIndx++;
+                  token = TT_DOLLAROPEN;
+                  return;
+                }
+              }
+              getIdentifier();
+              return;
+            }
+            if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$')) {
+              getIdentifier();
+              return;
+            }
+            if (ch >= '0' && ch <= '9') {
+              getNumber();
+              return;
+            }
+            if (ch == '/') {
+              if (str.length() > chIndx) {
+                if (str.charAt(chIndx) == '/') {
+                  ch = '/';
+                  chIndx++;
+                  // read comment until end of line:
+                  while ((str.length() > chIndx) && (ch != '\n')) {
+                    ch = str.charAt(chIndx++);
+                    if (ch == '?') {
+                      ch2 = str.charAt(chIndx);
+                      if (ch2 == '>') {
+                        chIndx++;
+                        token = TT_HTML;
+                        // php end
+                        phpMode = false;
+                        phpEnd = true;
+                        return;
+                      }
+                    }
+                  }
+                  rowCount++;
+                  continue;
+
+                } else if (str.charAt(chIndx) == '*') {
+                  chIndx++;
+                  // multi line comment:
+                  while (str.length() > chIndx) {
+                    if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') {
+                      chIndx += 2;
+                      break;
+                    }
+                    ch = str.charAt(chIndx++);
+                    if (ch == '\n') {
+                      rowCount++;
+                      columnCount = chIndx;
+                    }
+                  }
+                  continue;
+                }
+              }
+            } else if (ch == '#') {
+              // read comment until end of line:
+              while ((str.length() > chIndx) && (ch != '\n')) {
+                ch = str.charAt(chIndx++);
+                if (ch == '?') {
+                  ch2 = str.charAt(chIndx);
+                  if (ch2 == '>') {
+                    chIndx++;
+                    token = TT_HTML;
+                    // php end
+                    phpMode = false;
+                    phpEnd = true;
+                    return;
+                  }
+                }
+              }
+              rowCount++;
+              continue;
+
+            } else if (ch == '"') {
+              // read string until end
+              boolean openString = true;
+              while (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+                if (ch == '\\') {
+                  if (str.length() > chIndx) {
+                    ch = str.charAt(chIndx++);
+                  }
+                } else if (ch == '"') {
+                  openString = false;
+                  break;
+                } else if (ch == '\n') {
+                  rowCount++;
+                  columnCount = chIndx;
+                }
+              }
+              if (openString) {
+                throwSyntaxError("Open string character '\"' at end of file.");
+              }
+              token = TT_INTERPOLATED_STRING;
+              return;
+            } else if (ch == '\'') {
+              // read string until end
+              boolean openString = true;
+              int startRow = rowCount;
+              while (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+                if (ch == '\\') {
+                  if (str.length() > chIndx) {
+                    ch = str.charAt(chIndx++);
+                  }
+                } else if (ch == '\'') {
+                  openString = false;
+                  break;
+                } else if (ch == '\n') {
+                  rowCount++;
+                  columnCount = chIndx;
+                }
+              }
+              if (openString) {
+                throwSyntaxError("Open string character \"'\" at end of file.", startRow);
+              }
+              token = TT_STRING_CONSTANT;
+              return;
+            } else if (ch == '`') {
+              // read string until end
+              boolean openString = true;
+              int startRow = rowCount;
+              while (str.length() > chIndx) {
+                ch = str.charAt(chIndx++);
+                if (ch == '\\') {
+                  if (str.length() > chIndx) {
+                    ch = str.charAt(chIndx++);
+                  }
+                } else if (ch == '`') {
+                  openString = false;
+                  break;
+                } else if (ch == '\n') {
+                  rowCount++;
+                  columnCount = chIndx;
+                }
+              }
+              if (openString) {
+                throwSyntaxError("Open string character \"`\" at end of file.", startRow);
+              }
+              setMarker("Other string delimiters prefered (found \"`\").", rowCount, PHPParser.INFO);
+              token = TT_STRING_CONSTANT;
+              return;
+            }
+
+            switch (ch) {
+
+              case '(' :
+                token = TT_ARGOPEN;
+
+                break;
+              case ')' :
+                token = TT_ARGCLOSE;
+
+                break;
+              case '{' :
+                token = TT_LISTOPEN;
+
+                break;
+              case '}' :
+                token = TT_LISTCLOSE;
+
+                break;
+              case '[' :
+                token = TT_PARTOPEN;
+
+                break;
+              case ']' :
+                token = TT_PARTCLOSE;
+
+                break;
+              case ',' :
+                token = TT_COMMA;
+
+                break;
+              case '?' :
+                token = TT_QUESTIONMARK;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '>') {
+                    chIndx++;
+                    token = TT_HTML;
+                    // php end
+                    phpMode = false;
+                    phpEnd = true;
+                    break;
+                  }
+                }
+
+                break;
+              case '@' :
+                token = TT_AT;
+                break;
+              case '~' :
+                token = TT_TILDE;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_TILDEASSIGN;
+
+                    break;
+                  }
+                }
+                break;
+              case '.' :
+                token = TT_DOT;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_DOTASSIGN;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '"' :
+                token = TT_STRING;
+
+                break;
+              case '%' :
+                token = TT_MOD;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_MODASSIGN;
+
+                    break;
+                  }
+                }
+                break;
+              case ';' :
+                token = TT_SEMICOLON;
+
+                break;
+              case '^' :
+                token = TT_POW;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_POWASSIGN;
+
+                    break;
+                  }
+                }
+                break;
+              case '/' :
+                token = TT_DIV;
+
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_DIVIDEBY;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '*' :
+                token = TT_MULTIPLY;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '*') {
+                    chIndx++;
+                    token = TT_POW;
+
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_TIMESBY;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '+' :
+                token = TT_ADD;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '+') {
+                    chIndx++;
+                    token = TT_INCREMENT;
+
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_ADDTO;
+
+                    break;
+                  }
+                }
+                break;
+              case '-' :
+                token = TT_SUBTRACT;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '-') {
+                    chIndx++;
+                    token = TT_DECREMENT;
+
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_SUBTRACTFROM;
+
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '>') {
+                    chIndx++;
+                    token = TT_REF;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '=' :
+                token = TT_ASSIGN;
+
+                if (str.length() > chIndx) {
+                  ch = str.charAt(chIndx);
+
+                  if (ch == '=') {
+                    chIndx++;
+                    token = TT_EQUAL;
+                    if (str.length() > chIndx) {
+                      ch = str.charAt(chIndx);
+
+                      if (ch == '=') {
+                        chIndx++;
+                        token = TT_EX_EQUAL;
+                      }
+                    }
+                    break;
+                  }
+                  if (ch == '>') {
+                    chIndx++;
+                    token = TT_FOREACH;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '!' :
+                token = TT_NOT;
+
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_UNEQUAL;
+                    if (str.length() > chIndx) {
+                      ch = str.charAt(chIndx);
+
+                      if (ch == '=') {
+                        chIndx++;
+                        token = TT_EX_UNEQUAL;
+                      }
+                    }
+                    break;
+                  }
+                }
+
+                break;
+              case '>' :
+                token = TT_GREATER;
+
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_GREATEREQUAL;
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '>') {
+                    chIndx++;
+                    token = TT_RSHIFT;
+                    if (str.length() > chIndx) {
+                      if (str.charAt(chIndx) == '=') {
+                        chIndx++;
+                        token = TT_RSHIFTASSIGN;
+                        break;
+                      }
+                    }
+                    break;
+                  }
+                }
+
+                break;
+              case '<' :
+                token = TT_LESS;
+
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_LESSEQUAL;
+
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '<') {
+                    chIndx++;
+                    token = TT_LSHIFT;
+                    if (str.charAt(chIndx) == '<') {
+                      // heredoc
+                      int startRow = rowCount;
+                      if (str.length() > chIndx) {
+
+                        ch = str.charAt(++chIndx);
+                        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_')) {
+                          chIndx++;
+                          getIdentifier();
+                          token = TT_STRING_CONSTANT;
+                          while (str.length() > chIndx) {
+                            ch = str.charAt(chIndx++);
+                            if (ch == '\n') {
+                              if (str.length() >= chIndx + identifier.length()) {
+                                if (str.substring(chIndx, chIndx + identifier.length()).equals(identifier)) {
+                                  chIndx += identifier.length();
+                                  return;
+                                }
+                              }
+                            }
+                          }
+                        }
+                      }
+                      throwSyntaxError("Open heredoc syntax after operator '<<<'.", startRow);
+                    } else if (str.charAt(chIndx) == '=') {
+                      chIndx++;
+                      token = TT_LSHIFTASSIGN;
+                      break;
+                    }
+                    break;
+                  }
+                }
+
+                break;
+
+              case '|' :
+                token = TT_LINE;
+
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '|') {
+                    chIndx++;
+                    token = TT_OR;
+
+                    break;
+                  }
+                }
+
+                break;
+              case '&' :
+                token = TT_AMPERSAND;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == '&') {
+                    chIndx++;
+                    token = TT_AND;
+                    break;
+                  }
+                  if (str.charAt(chIndx) == '=') {
+                    chIndx++;
+                    token = TT_ANDASSIGN;
+                    break;
+                  }
+                  break;
+                }
+
+                break;
+              case ':' :
+                token = TT_DDOT;
+                if (str.length() > chIndx) {
+                  if (str.charAt(chIndx) == ':') {
+                    chIndx++;
+                    token = TT_DDOT2;
+                  }
+                }
+                break;
+              case '#' :
+                token = TT_HASH;
+
+                break;
+                //          case '@' :
+                //            token = TT_AT;
+                //
+                //            break;
+              default :
+                throwSyntaxError("unexpected character: '" + ch + "'");
+            }
+
+            if (token == TT_UNDEFINED) {
+              throwSyntaxError("token not found");
+            }
+
+            return;
+          }
+        }
+      }
+    } catch (StringIndexOutOfBoundsException e) {
+      // catched from charAt
+    }
+
+    chIndx = str.length() + 1;
+    ch = ' ';
+    token = TT_EOF;
+    phpEnd = true;
+    //PHPString temp;
+    //    if (phpList != null) {
+    //      if (currentPHPString < phpList.size()) {
+    //        token = TT_UNDEFINED;
+    //        temp = (PHPString) phpList.get(currentPHPString++);
+    //        this.str = temp.getPHPString();
+    //        this.token = TT_EOF;
+    //        this.chIndx = 0;
+    //        this.rowCount = temp.getLineNumber();
+    //        this.columnCount = 0;
+    //        getNextToken();
+    //        phpEnd = true;
+    //      } else {
+    //        token = TT_UNDEFINED;
+    //        return;
+    //      }
+    //    }
+  }
+
+  private void getIdentifier() {
+    StringBuffer ident = new StringBuffer();
+
+    ident.append(ch);
+    if (ch == '$') {
+      token = TT_VARIABLE;
+    } else {
+      token = TT_IDENTIFIER;
+    }
+    getChar();
+    while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
+      ident.append(ch);
+      getChar();
+    }
+    identifier = ident.toString();
+    chIndx--;
+
+    Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
+    if (i != null) {
+      token = i.intValue();
+    }
+  }
+
+  private void getNumber() {
+    StringBuffer inum = new StringBuffer();
+    char dFlag = ' ';
+    int numFormat = 10;
+
+    // save first digit
+    char firstCh = ch;
+    inum.append(ch);
+
+    getChar();
+    // determine number conversions:
+    if (firstCh == '0') {
+      switch (ch) {
+        case 'b' :
+          numFormat = 2;
+          getChar();
+          break;
+        case 'B' :
+          numFormat = 2;
+          getChar();
+          break;
+        case 'o' :
+          numFormat = 8;
+          getChar();
+          break;
+        case 'O' :
+          numFormat = 8;
+          getChar();
+          break;
+        case 'x' :
+          numFormat = 16;
+          getChar();
+          break;
+        case 'X' :
+          numFormat = 16;
+          getChar();
+          break;
+      }
+    }
+
+    if (numFormat == 16) {
+      while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
+        inum.append(ch);
+        getChar();
+      }
+    } else {
+      while ((ch >= '0' && ch <= '9') || (ch == '.') || (ch == 'E') || (ch == 'e')) {
+        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
+          if (ch == '.' && dFlag != ' ') {
+            break;
+          }
+          if ((dFlag == 'E') || (dFlag == 'e')) {
+            break;
+          }
+          dFlag = ch;
+          inum.append(ch);
+          getChar();
+          if ((ch == '-') || (ch == '+')) {
+            inum.append(ch);
+            getChar();
+          }
+        } else {
+          inum.append(ch);
+          getChar();
+        }
+      }
+    }
+    chIndx--;
+
+    try {
+      if (dFlag != ' ') {
+        doubleNumber = new Double(inum.toString());
+        token = TT_DOUBLE_NUMBER;
+        return;
+      } else {
+        longNumber = Long.valueOf(inum.toString(), numFormat);
+        token = TT_INT_NUMBER;
+        return;
+      }
+
+    } catch (Throwable e) {
+      throwSyntaxError("Number format error: " + inum.toString());
+    }
+  }
+
+  public void htmlParserTester(String input) {
+    int lineNumber = 1;
+    int startLineNumber = 1;
+    int startIndex = 0;
+    char ch;
+    char ch2;
+    boolean phpMode = false;
+    boolean phpFound = false;
+
+    phpList = new ArrayList();
+    currentPHPString = 0;
+
+    try {
+      int i = 0;
+      while (i < input.length()) {
+        ch = input.charAt(i++);
+        if (ch == '\n') {
+          lineNumber++;
+        }
+        if ((!phpMode) && ch == '<') {
+          ch2 = input.charAt(i++);
+          if (ch2 == '?') {
+            ch2 = input.charAt(i++);
+            if (Character.isWhitespace(ch2)) {
+              // php start 
+              phpMode = true;
+              phpFound = true;
+              startIndex = i;
+              startLineNumber = lineNumber;
+              continue;
+            } else if (ch2 == 'p') {
+              ch2 = input.charAt(i++);
+              if (ch2 == 'h') {
+                ch2 = input.charAt(i++);
+                if (ch2 == 'p') {
+                  phpMode = true;
+                  phpFound = true;
+                  startIndex = i;
+                  startLineNumber = lineNumber;
+                  continue;
+                }
+                i--;
+              }
+              i--;
+            } else if (ch2 == 'P') {
+              ch2 = input.charAt(i++);
+              if (ch2 == 'H') {
+                ch2 = input.charAt(i++);
+                if (ch2 == 'P') {
+                  phpMode = true;
+                  phpFound = true;
+                  startIndex = i;
+                  startLineNumber = lineNumber;
+                  continue;
+                }
+                i--;
+              }
+              i--;
+            }
+            i--;
+          }
+          i--;
+        }
+
+        if (phpMode) {
+          if (ch == '/' && i < input.length()) {
+            ch2 = input.charAt(i++);
+            if (ch2 == '/') {
+              while (i < input.length()) {
+                ch = input.charAt(i++);
+                if (ch == '?' && i < input.length()) {
+                  ch2 = input.charAt(i++);
+                  if (ch2 == '>') {
+                    // php end
+                    phpMode = false;
+                    phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
+                    continue;
+                  }
+                  i--;
+                } else if (ch == '\n') {
+                  lineNumber++;
+                  break;
+                }
+              }
+              continue;
+            } else if (ch2 == '*') {
+              // multi-line comment
+              while (i < input.length()) {
+                ch = input.charAt(i++);
+                if (ch == '\n') {
+                  lineNumber++;
+                } else if (ch == '*' && i < input.length()) {
+                  ch2 = input.charAt(i++);
+                  if (ch2 == '/') {
+                    break;
+                  }
+                  i--;
+                }
+              }
+              continue;
+            } else {
+              i--;
+            }
+          } else if (ch == '#') {
+            while (i < input.length()) {
+              ch = input.charAt(i++);
+              if (ch == '?' && i < input.length()) {
+                ch2 = input.charAt(i++);
+                if (ch2 == '>') {
+                  // php end
+                  phpMode = false;
+                  phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
+                  continue;
+                }
+                i--;
+              } else if (ch == '\n') {
+                lineNumber++;
+                break;
+              }
+            }
+            continue;
+          } else if (ch == '"') {
+            ch = ' ';
+            while (i < input.length()) {
+              ch = input.charAt(i++);
+              if (ch == '\n') {
+                lineNumber++;
+              } else if (ch == '\\' && i < input.length()) { // escape
+                i++;
+              } else if (ch == '"') {
+                break;
+              }
+            }
+            continue;
+          } else if (ch == '\'') {
+            ch = ' ';
+            while (i < input.length()) {
+              ch = input.charAt(i++);
+              if (ch == '\n') {
+                lineNumber++;
+              } else if (ch == '\\' && i < input.length()) { // escape
+                i++;
+              } else if (ch == '\'') {
+                break;
+              }
+            }
+            continue;
+          }
+
+          if (ch == '?' && i < input.length()) {
+            ch2 = input.charAt(i++);
+            if (ch2 == '>') {
+              // php end
+              phpMode = false;
+              phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
+              continue;
+            }
+            i--;
+          }
+        }
+      }
+
+      if (!phpFound) {
+        setMarker("No PHP source code found.", lineNumber, PHPParser.INFO);
+      } else {
+        if (phpMode) {
+          setMarker("Open PHP tag at end of file.", lineNumber, PHPParser.INFO);
+          phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
+        }
+        //        for (int j=0;j<phpList.size();j++) {
+        //          String temp = ((PHPString)phpList.get(j)).getPHPString();
+        //          int startIndx = temp.length()-10;
+        //          if (startIndx<0) {
+        //            startIndx = 0; 
+        //          }
+        //          System.out.println(temp.substring(startIndx)+"?>");
+        //        }
+        phpParserTester(null, 1);
+        //        PHPString temp;
+        //        for(int j=0;j<phpList.size();j++) {
+        //          temp = (PHPString) phpList.get(j);
+        //          parser.start(temp.getPHPString(), temp.getLineNumber());
+        //        } 
+      }
+    } catch (CoreException e) {
+    }
+  }
+
+  public void phpParserTester(String s, int rowCount) throws CoreException {
+    this.str = s;
+    if (s == null) {
+      if (phpList.size() != 0) {
+        this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
+      }
+    }
+    this.token = TT_EOF;
+    this.chIndx = 0;
+    this.rowCount = rowCount;
+    this.columnCount = 0;
+    this.phpEnd = false;
+    this.phpMode = true;
+    getNextToken();
+    do {
+      try {
+        if (token != TT_EOF && token != TT_UNDEFINED) {
+          statementList();
+        }
+        if (token != TT_EOF && token != TT_UNDEFINED) {
+          if (token == TT_ARGCLOSE) {
+            throwSyntaxError("Too many closing ')'; end-of-file not reached.");
+          }
+          if (token == TT_LISTCLOSE) {
+            throwSyntaxError("Too many closing '}'; end-of-file not reached.");
+          }
+          if (token == TT_PARTCLOSE) {
+            throwSyntaxError("Too many closing ']'; end-of-file not reached.");
+          }
+
+          if (token == TT_ARGOPEN) {
+            throwSyntaxError("Read character '('; end-of-file not reached.");
+          }
+          if (token == TT_LISTOPEN) {
+            throwSyntaxError("Read character '{';  end-of-file not reached.");
+          }
+          if (token == TT_PARTOPEN) {
+            throwSyntaxError("Read character '[';  end-of-file not reached.");
+          }
+
+          throwSyntaxError("End-of-file not reached.");
+        }
+        return;
+      } catch (SyntaxError err) {
+        if (s != null) {
+          throw err;
+        } else {
+          setMarker(err.getMessage(), err.getLine(), ERROR);
+        }
+        // if an error occured, 
+        // try to find keywords 'class' or 'function'
+        // to parse the rest of the string
+        while (token != TT_EOF && token != TT_UNDEFINED) {
+          if (token == TT_class || token == TT_function) {
+            break;
+          }
+          getNextToken();
+        }
+        if (token == TT_EOF || token == TT_UNDEFINED) {
+          return;
+        }
+      }
+    }
+    while (true);
+  }
+
+  /**
+   * Parses a string with php tAGS
+   * i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt; &lt;/body&gt;'
+   */
+  public void parse(String s) throws CoreException {
+    this.str = s;
+    this.token = TT_EOF;
+    this.chIndx = 0;
+    this.rowCount = 1;
+    this.columnCount = 0;
+    this.phpEnd = false;
+    this.phpMode = false;
+    getNextToken();
+    do {
+      try {
+        if (token != TT_EOF && token != TT_UNDEFINED) {
+          statementList();
+        }
+        if (token != TT_EOF && token != TT_UNDEFINED) {
+          if (token == TT_ARGCLOSE) {
+            throwSyntaxError("Too many closing ')'; end-of-file not reached.");
+          }
+          if (token == TT_LISTCLOSE) {
+            throwSyntaxError("Too many closing '}'; end-of-file not reached.");
+          }
+          if (token == TT_PARTCLOSE) {
+            throwSyntaxError("Too many closing ']'; end-of-file not reached.");
+          }
+
+          if (token == TT_ARGOPEN) {
+            throwSyntaxError("Read character '('; end-of-file not reached.");
+          }
+          if (token == TT_LISTOPEN) {
+            throwSyntaxError("Read character '{';  end-of-file not reached.");
+          }
+          if (token == TT_PARTOPEN) {
+            throwSyntaxError("Read character '[';  end-of-file not reached.");
+          }
+
+          throwSyntaxError("End-of-file not reached.");
+        }
+        return;
+      } catch (SyntaxError sytaxErr1) {
+        setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
+        try {
+          // if an error occured, 
+          // try to find keywords 'class' or 'function'
+          // to parse the rest of the string
+          while (token != TT_EOF && token != TT_UNDEFINED) {
+            if (token == TT_class || token == TT_function) {
+              break;
+            }
+            getNextToken();
+          }
+          if (token == TT_EOF || token == TT_UNDEFINED) {
+            return;
+          }
+        } catch (SyntaxError sytaxErr2) {
+          setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
+          return;
+        }
+      }
+    }
+    while (true);
+  }
+
+  private void statementList() throws CoreException {
+    do {
+      statement();
+      if ((token == TT_LISTCLOSE)
+        || (token == TT_case)
+        || (token == TT_default)
+        || (token == TT_elseif)
+        || (token == TT_endif)
+        || (token == TT_endfor)
+        || (token == TT_endforeach)
+        || (token == TT_endwhile)
+        || (token == TT_endswitch)
+        || (token == TT_EOF)
+        || (token == TT_UNDEFINED)) {
+        return;
+      }
+    } while (true);
+  }
+
+  private void compoundStatement() throws CoreException {
+    // '{' [statement-list] '}'
+    if (token == TT_LISTOPEN) {
+      getNextToken();
+    } else {
+      throwSyntaxError("'{' expected in compound-statement.");
+    }
+    if (token != TT_LISTCLOSE) {
+      statementList();
+    }
+    if (token == TT_LISTCLOSE) {
+      getNextToken();
+    } else {
+      throwSyntaxError("'}' expected in compound-statement.");
+    }
+  }
+
+  private void statement() throws CoreException {
+    //   if (token > TT_KEYWORD && token != TT_list && token != TT_new) {
+    String keyword = identifier;
+    if (token == TT_include || token == TT_include_once) {
+      getNextToken();
+      expression();
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+        }
+        getNextToken();
+      }
+      return;
+    } else if (token == TT_require || token == TT_require_once) {
+      getNextToken();
+      //constant();
+      expression();
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+        }
+        getNextToken();
+      }
+      return;
+    } else if (token == TT_if) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'if' keyword.");
+      }
+      expression();
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("')' expected after 'if' condition.");
+      }
+      ifStatement();
+      return;
+
+    } else if (token == TT_switch) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'switch' keyword.");
+      }
+      expression();
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("')' expected after 'switch' condition.");
+      }
+      switchStatement();
+      return;
+    } else if (token == TT_for) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'for' keyword.");
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        expressionList();
+        if (token == TT_SEMICOLON) {
+          getNextToken();
+        } else {
+          throwSyntaxError("';' expected after 'for'.");
+        }
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        expressionList();
+        if (token == TT_SEMICOLON) {
+          getNextToken();
+        } else {
+          throwSyntaxError("';' expected after 'for'.");
+        }
+      }
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        expressionList();
+        if (token == TT_ARGCLOSE) {
+          getNextToken();
+        } else {
+          throwSyntaxError("')' expected after 'for'.");
+        }
+      }
+      forStatement();
+      return;
+    } else if (token == TT_while) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'while' keyword.");
+      }
+      expression();
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("')' expected after 'while' condition.");
+      }
+      whileStatement();
+      return;
+    } else if (token == TT_do) {
+      getNextToken();
+      if (token == TT_LISTOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'{' expected after 'do' keyword.");
+      }
+      if (token != TT_LISTCLOSE) {
+        statementList();
+      }
+      if (token == TT_LISTCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'}' expected after 'do' keyword.");
+      }
+      if (token == TT_while) {
+        getNextToken();
+        if (token == TT_ARGOPEN) {
+          getNextToken();
+        } else {
+          throwSyntaxError("'(' expected after 'while' keyword.");
+        }
+        expression();
+        if (token == TT_ARGCLOSE) {
+          getNextToken();
+        } else {
+          throwSyntaxError("')' expected after 'while' condition.");
+        }
+      } else {
+        throwSyntaxError("'while' expected after 'do' keyword.");
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after do-while statement.");
+        }
+        getNextToken();
+      }
+      return;
+    } else if (token == TT_foreach) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'foreach' keyword.");
+      }
+      expression();
+      if (token == TT_as) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'as' expected after 'foreach' exxpression.");
+      }
+      variable();
+      if (token == TT_FOREACH) {
+        getNextToken();
+        variable();
+      }
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("')' expected after 'foreach' expression.");
+      }
+      foreachStatement();
+      return;
+
+    } else if (token == TT_continue || token == TT_break || token == TT_return) {
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        expression();
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+        }
+        getNextToken();
+      }
+      return;
+
+    } else if (token == TT_echo) {
+      getNextToken();
+      expressionList();
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after 'echo' statement.");
+        }
+        getNextToken();
+      }
+      return;
+      //    } else if (token == TT_print) {
+      //      getNextToken();
+      //      expression();
+      //      if (token == TT_SEMICOLON) {
+      //        getNextToken();
+      //      } else {
+      //        if (!phpEnd) {
+      //          throwSyntaxError("';' expected after 'print' statement.");
+      //        }
+      //        getNextToken();
+      //      }
+      //      return;
+
+    } else if (token == TT_global || token == TT_static) {
+      getNextToken();
+      variableList();
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after 'global' or 'static' statement.");
+        }
+        getNextToken();
+      }
+      return;
+
+      //      } else if (token == TT_unset) {
+      //        getNextToken();
+      //        if (token == TT_ARGOPEN) {
+      //          getNextToken();
+      //        } else {
+      //          throwSyntaxError("'(' expected after 'unset' keyword.");
+      //        }
+      //        variableList();
+      //        if (token == TT_ARGCLOSE) {
+      //          getNextToken();
+      //        } else {
+      //          throwSyntaxError("')' expected after 'unset' statement.");
+      //        }
+      //        if (token == TT_SEMICOLON) {
+      //          getNextToken();
+      //        } else {
+      //          if (!phpEnd) {
+      //            throwSyntaxError("';' expected after 'unset' statement.");
+      //          }
+      //          getNextToken();
+      //        }
+      //        return;
+
+      //      } else if (token == TT_exit || token == TT_die) {
+      //        getNextToken();
+      //        if (token != TT_SEMICOLON) {
+      //          exitStatus();
+      //        }
+      //        if (token == TT_SEMICOLON) {
+      //          getNextToken();
+      //        } else {
+      //          if (!phpEnd) {
+      //            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+      //          }
+      //          getNextToken();
+      //        }
+      //        return;
+
+    } else if (token == TT_define) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected after 'define' keyword.");
+      }
+      expression();
+      if (token == TT_COMMA) {
+        getNextToken();
+      } else {
+        throwSyntaxError("',' expected after first 'define' constant.");
+      }
+      expression();
+      if (token == TT_COMMA) {
+        getNextToken();
+        expression();
+      }
+      if (token == TT_ARGCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("')' expected after 'define' statement.");
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after 'define' statement.");
+        }
+        getNextToken();
+      }
+      return;
+    } else if (token == TT_function) {
+      getNextToken();
+      functionDefinition();
+      return;
+    } else if (token == TT_class) {
+      getNextToken();
+      classDeclarator();
+      classBody();
+      return;
+      //      } else {
+      //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
+    } else if (token == TT_LISTOPEN) {
+      // compoundStatement
+      getNextToken();
+      if (token != TT_LISTCLOSE) {
+        statementList();
+      }
+      if (token == TT_LISTCLOSE) {
+        getNextToken();
+        return;
+      } else {
+        throwSyntaxError("'}' expected.");
+      }
+    } else {
+      if (token != TT_SEMICOLON) {
+        expression();
+      }
+      if (token == TT_SEMICOLON) {
+        getNextToken();
+        return;
+      } else {
+        if (!phpEnd) {
+          throwSyntaxError("';' expected after expression.");
+        }
+        getNextToken();
+      }
+    }
+  }
+
+  private void classDeclarator() throws CoreException {
+    //identifier
+    //identifier 'extends' identifier
+    if (token == TT_IDENTIFIER) {
+      getNextToken();
+      if (token == TT_extends) {
+        getNextToken();
+        if (token == TT_IDENTIFIER) {
+          getNextToken();
+        } else {
+          throwSyntaxError("Class name expected after keyword 'extends'.");
+        }
+      }
+    } else {
+      throwSyntaxError("Class name expected after keyword 'class'.");
+    }
+  }
+
+  private void classBody() throws CoreException {
+    //'{' [class-element-list] '}'
+    if (token == TT_LISTOPEN) {
+      getNextToken();
+      if (token != TT_LISTCLOSE) {
+        classElementList();
+      }
+      if (token == TT_LISTCLOSE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'}' expected at end of class body.");
+      }
+    } else {
+      throwSyntaxError("'{' expected at start of class body.");
+    }
+  }
+
+  private void classElementList() throws CoreException {
+    do {
+      classElement();
+    } while (token == TT_function || token == TT_var);
+  }
+
+  private void classElement() throws CoreException {
+    //class-property
+    //function-definition
+    if (token == TT_function) {
+      getNextToken();
+      functionDefinition();
+    } else if (token == TT_var) {
+      getNextToken();
+      classProperty();
+    } else {
+      throwSyntaxError("'function' or 'var' expected.");
+    }
+  }
+
+  private void classProperty() throws CoreException {
+    //'var' variable ';'
+    //'var' variable '=' constant ';'
+    do {
+      if (token == TT_VARIABLE) {
+        getNextToken();
+        if (token == TT_ASSIGN) {
+          getNextToken();
+          constant();
+        }
+      } else {
+        throwSyntaxError("Variable expected after keyword 'var'.");
+      }
+      if (token != TT_COMMA) {
+        break;
+      }
+      getNextToken();
+    } while (true);
+    if (token == TT_SEMICOLON) {
+      getNextToken();
+    } else {
+      throwSyntaxError("';' expected after variable declaration.");
+    }
+  }
+
+  private void functionDefinition() throws CoreException {
+    functionDeclarator();
+    compoundStatement();
+  }
+
+  private void functionDeclarator() throws CoreException {
+    //identifier '(' [parameter-list] ')'
+    if (token == TT_AMPERSAND) {
+      getNextToken();
+    }
+    if (token == TT_IDENTIFIER) {
+      getNextToken();
+      if (token == TT_ARGOPEN) {
+        getNextToken();
+      } else {
+        throwSyntaxError("'(' expected in function declaration.");
+      }
+      if (token != TT_ARGCLOSE) {
+        parameterList();
+      }
+      if (token != TT_ARGCLOSE) {
+        throwSyntaxError("')' expected in function declaration.");
+      } else {
+        getNextToken();
+      }
+    }
+  }
+  //
+  private void parameterList() throws CoreException {
+    //parameter-declaration
+    //parameter-list ',' parameter-declaration
+    do {
+      parameterDeclaration();
+      if (token != TT_COMMA) {
+        break;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void parameterDeclaration() throws CoreException {
+    //variable
+    //variable-reference
+    if (token == TT_AMPERSAND) {
+      getNextToken();
+      if (token == TT_VARIABLE) {
+        getNextToken();
+      } else {
+        throwSyntaxError("Variable expected after reference operator '&'.");
+      }
+    }
+    //variable '=' constant
+    if (token == TT_VARIABLE) {
+      getNextToken();
+      if (token == TT_ASSIGN) {
+        getNextToken();
+        constant();
+      }
+      return;
+    }
+  }
+
+  private void labeledStatementList() throws CoreException {
+    if (token != TT_case && token != TT_default) {
+      throwSyntaxError("'case' or 'default' expected.");
+    }
+    do {
+      if (token == TT_case) {
+        getNextToken();
+        constant();
+        if (token == TT_DDOT) {
+          getNextToken();
+          if (token == TT_case || token == TT_default) { // empty case statement ?
+            continue;
+          }
+          statementList();
+        } else if (token == TT_SEMICOLON) {
+          setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
+          getNextToken();
+          if (token == TT_case) { // empty case statement ?
+            continue;
+          }
+          statementList();
+        } else {
+          throwSyntaxError("':' character after 'case' constant expected.");
+        }
+      } else { // TT_default 
+        getNextToken();
+        if (token == TT_DDOT) {
+          getNextToken();
+          statementList();
+        } else {
+          throwSyntaxError("':' character after 'default' expected.");
+        }
+      }
+    } while (token == TT_case || token == TT_default);
+  }
+
+  //  public void labeledStatement() {
+  //    if (token == TT_case) {
+  //      getNextToken();
+  //      constant();
+  //      if (token == TT_DDOT) {
+  //        getNextToken();
+  //        statement();
+  //      } else {
+  //        throwSyntaxError("':' character after 'case' constant expected.");
+  //      }
+  //      return;
+  //    } else if (token == TT_default) {
+  //      getNextToken();
+  //      if (token == TT_DDOT) {
+  //        getNextToken();
+  //        statement();
+  //      } else {
+  //        throwSyntaxError("':' character after 'default' expected.");
+  //      }
+  //      return;
+  //    }
+  //  }
+
+  //  public void expressionStatement() {
+  //  }
+
+  //  private void inclusionStatement() {
+  //  }
+
+  //  public void compoundStatement() {
+  //  }
+
+  //  public void selectionStatement() {
+  //  }
+  //
+  //  public void iterationStatement() {
+  //  }
+  //
+  //  public void jumpStatement() {
+  //  }
+  //
+  //  public void outputStatement() {
+  //  }
+  //
+  //  public void scopeStatement() {
+  //  }
+  //
+  //  public void flowStatement() {
+  //  }
+  //
+  //  public void definitionStatement() {
+  //  }
+
+  private void ifStatement() throws CoreException {
+    // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
+    if (token == TT_DDOT) {
+      getNextToken();
+      statementList();
+      switch (token) {
+        case TT_else :
+          getNextToken();
+          if (token == TT_DDOT) {
+            getNextToken();
+            statementList();
+          } else {
+            if (token == TT_if) { //'else if'
+              getNextToken();
+              elseifStatementList();
+            } else {
+              throwSyntaxError("':' expected after 'else'.");
+            }
+          }
+          break;
+        case TT_elseif :
+          getNextToken();
+          elseifStatementList();
+          break;
+      }
+
+      if (token != TT_endif) {
+        throwSyntaxError("'endif' expected.");
+      }
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        throwSyntaxError("';' expected after if-statement.");
+      }
+      getNextToken();
+    } else {
+      // statement [else-statement]
+      statement();
+      if (token == TT_elseif) {
+        getNextToken();
+        if (token == TT_ARGOPEN) {
+          getNextToken();
+        } else {
+          throwSyntaxError("'(' expected after 'elseif' keyword.");
+        }
+        expression();
+        if (token == TT_ARGCLOSE) {
+          getNextToken();
+        } else {
+          throwSyntaxError("')' expected after 'elseif' condition.");
+        }
+        ifStatement();
+      } else if (token == TT_else) {
+        getNextToken();
+        statement();
+      }
+    }
+  }
+
+  private void elseifStatementList() throws CoreException {
+    do {
+      elseifStatement();
+      switch (token) {
+        case TT_else :
+          getNextToken();
+          if (token == TT_DDOT) {
+            getNextToken();
+            statementList();
+            return;
+          } else {
+            if (token == TT_if) { //'else if'
+              getNextToken();
+            } else {
+              throwSyntaxError("':' expected after 'else'.");
+            }
+          }
+          break;
+        case TT_elseif :
+          getNextToken();
+          break;
+        default :
+          return;
+      }
+    } while (true);
+  }
+
+  private void elseifStatement() throws CoreException {
+    if (token == TT_ARGOPEN) {
+      getNextToken();
+      expression();
+      if (token != TT_ARGOPEN) {
+        throwSyntaxError("')' expected in else-if-statement.");
+      }
+      getNextToken();
+      if (token != TT_DDOT) {
+        throwSyntaxError("':' expected in else-if-statement.");
+      }
+      getNextToken();
+      statementList();
+    }
+  }
+
+  private void switchStatement() throws CoreException {
+    if (token == TT_DDOT) {
+      // ':' [labeled-statement-list] 'endswitch' ';'
+      getNextToken();
+      labeledStatementList();
+      if (token != TT_endswitch) {
+        throwSyntaxError("'endswitch' expected.");
+      }
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        throwSyntaxError("';' expected after switch-statement.");
+      }
+      getNextToken();
+    } else {
+      // '{' [labeled-statement-list] '}'
+      if (token != TT_LISTOPEN) {
+        throwSyntaxError("'{' expected in switch statement.");
+      }
+      getNextToken();
+      if (token != TT_LISTCLOSE) {
+        labeledStatementList();
+      }
+      if (token != TT_LISTCLOSE) {
+        throwSyntaxError("'}' expected in switch statement.");
+      }
+      getNextToken();
+
+    }
+  }
+
+  private void forStatement() throws CoreException {
+    if (token == TT_DDOT) {
+      getNextToken();
+      statementList();
+      if (token != TT_endfor) {
+        throwSyntaxError("'endfor' expected.");
+      }
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        throwSyntaxError("';' expected after for-statement.");
+      }
+      getNextToken();
+    } else {
+      statement();
+    }
+  }
+
+  private void whileStatement() throws CoreException {
+    // ':' statement-list 'endwhile' ';'
+    if (token == TT_DDOT) {
+      getNextToken();
+      statementList();
+      if (token != TT_endwhile) {
+        throwSyntaxError("'endwhile' expected.");
+      }
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        throwSyntaxError("';' expected after while-statement.");
+      }
+      getNextToken();
+    } else {
+      statement();
+    }
+  }
+
+  private void foreachStatement() throws CoreException {
+    if (token == TT_DDOT) {
+      getNextToken();
+      statementList();
+      if (token != TT_endforeach) {
+        throwSyntaxError("'endforeach' expected.");
+      }
+      getNextToken();
+      if (token != TT_SEMICOLON) {
+        throwSyntaxError("';' expected after foreach-statement.");
+      }
+      getNextToken();
+    } else {
+      statement();
+    }
+  }
+
+  private void exitStatus() throws CoreException {
+    if (token == TT_ARGOPEN) {
+      getNextToken();
+    } else {
+      throwSyntaxError("'(' expected in 'exit-status'.");
+    }
+    if (token != TT_ARGCLOSE) {
+      expression();
+    }
+    if (token == TT_ARGCLOSE) {
+      getNextToken();
+    } else {
+      throwSyntaxError("')' expected after 'exit-status'.");
+    }
+  }
+
+  private void expressionList() throws CoreException {
+    do {
+      expression();
+      if (token == TT_COMMA) {
+        getNextToken();
+      } else {
+        break;
+      }
+    } while (true);
+  }
+
+  private void expression() throws CoreException {
+    //    if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
+    //      getNextToken();
+    //    } else {
+    logicalinclusiveorExpression();
+    //      while (token != TT_SEMICOLON) {
+    //        getNextToken();
+    //      //      }
+    //    }
+  }
+
+  private void postfixExpression() throws CoreException {
+    String ident;
+    boolean castFlag = false;
+    switch (token) {
+      case TT_new :
+        getNextToken();
+        expression();
+        break;
+      case TT_null :
+        getNextToken();
+        break;
+      case TT_false :
+        getNextToken();
+        break;
+      case TT_true :
+        getNextToken();
+        break;
+      case TT_STRING_CONSTANT :
+        getNextToken();
+        break;
+      case TT_INTERPOLATED_STRING :
+        getNextToken();
+        break;
+      case TT_ARGOPEN :
+        getNextToken();
+        if (token == TT_IDENTIFIER) {
+          // check if identifier is a type:
+          ident = identifier;
+          String str = identifier.toLowerCase();
+          for (int i = 0; i < PHP_TYPES.length; i++) {
+            if (PHP_TYPES[i].equals(str)) {
+              castFlag = true;
+              break;
+            }
+          }
+          if (castFlag) {
+            getNextToken();
+            if (token != TT_ARGCLOSE) {
+              throwSyntaxError(") expected after cast-type '" + ident + "'.");
+            }
+            getNextToken();
+            expression();
+            break;
+          }
+        }
+        if (!castFlag) {
+          expression();
+        }
+        if (token != TT_ARGCLOSE) {
+          throwSyntaxError(") expected in postfix-expression.");
+        }
+        getNextToken();
+        break;
+      case TT_DOUBLE_NUMBER :
+        getNextToken();
+        break;
+      case TT_INT_NUMBER :
+        getNextToken();
+        break;
+      case TT_DOLLAROPEN :
+        getNextToken();
+        expression();
+        if (token != TT_LISTCLOSE) {
+          throwSyntaxError("'}' expected after indirect variable token '${'.");
+        }
+        getNextToken();
+        break;
+      case TT_VARIABLE :
+        ident = identifier;
+        getNextToken();
+        if (token == TT_LISTOPEN) {
+          getNextToken();
+          expression();
+          if (token != TT_LISTCLOSE) {
+            throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
+          }
+          getNextToken();
+        } else if (token == TT_ARGOPEN) {
+          getNextToken();
+          if (token != TT_ARGCLOSE) {
+            expressionList();
+            if (token != TT_ARGCLOSE) {
+              throwSyntaxError("')' expected after variable '" + ident + "' in postfix-expression.");
+            }
+          }
+          getNextToken();
+        }
+        break;
+      case TT_IDENTIFIER :
+        ident = identifier;
+        getNextToken();
+        if (token == TT_ARGOPEN) {
+          getNextToken();
+          if (token != TT_ARGCLOSE) {
+            expressionList();
+            if (token != TT_ARGCLOSE) {
+              throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
+            }
+          }
+          getNextToken();
+        }
+        break;
+      case TT_print :
+        getNextToken();
+        expression();
+        //        if (token == TT_SEMICOLON) {
+        //          getNextToken();
+        //        } else {
+        //          if (!phpEnd) {
+        //            throwSyntaxError("';' expected after 'print' statement.");
+        //          }
+        //          getNextToken();
+        //        }
+        break;
+      case TT_list :
+        getNextToken();
+        if (token == TT_ARGOPEN) {
+          getNextToken();
+          if (token == TT_COMMA) {
+            getNextToken();
+          }
+          expressionList();
+          if (token != TT_ARGCLOSE) {
+            throwSyntaxError("')' expected after 'list' keyword.");
+          }
+          getNextToken();
+          //          if (token == TT_SET) {
+          //            getNextToken();
+          //            logicalinclusiveorExpression();
+          //          }
+        } else {
+          throwSyntaxError("'(' expected after 'list' keyword.");
+        }
+        break;
+        //      case TT_exit :
+        //        getNextToken();
+        //        if (token != TT_SEMICOLON) {
+        //          exitStatus();
+        //        }
+        //        if (token == TT_SEMICOLON) {
+        //          getNextToken();
+        //        } else {
+        //          if (!phpEnd) {
+        //            throwSyntaxError("';' expected after 'exit' expression.");
+        //          }
+        //          getNextToken();
+        //        }
+        //        break;
+        //      case TT_die :
+        //        getNextToken();
+        //        if (token != TT_SEMICOLON) {
+        //          exitStatus();
+        //        }
+        //        if (token == TT_SEMICOLON) {
+        //          getNextToken();
+        //        } else {
+        //          if (!phpEnd) {
+        //            throwSyntaxError("';' expected after 'die' expression.");
+        //          }
+        //        }
+        //        break;
+
+        //      case TT_array :
+        //        getNextToken();
+        //        if (token == TT_ARGOPEN) {
+        //          getNextToken();
+        //          if (token == TT_COMMA) {
+        //            getNextToken();
+        //          }
+        //          expressionList();
+        //          if (token != TT_ARGCLOSE) {
+        //            throwSyntaxError("')' expected after 'list' keyword.");
+        //          }
+        //          getNextToken();
+        //          if (token == TT_SET) {
+        //            getNextToken();
+        //            logicalinclusiveorExpression();
+        //          }
+        //        } else {
+        //          throwSyntaxError("'(' expected after 'list' keyword.");
+        //        }
+        //        break;
+    }
+    boolean while_flag = true;
+    do {
+      switch (token) {
+        case TT_PARTOPEN :
+          getNextToken();
+          expression();
+          if (token != TT_PARTCLOSE) {
+            throwSyntaxError("] expected in postfix-expression.");
+          }
+          getNextToken();
+          break;
+        case TT_DDOT2 : // ::
+        case TT_REF : // ->
+          getNextToken();
+          if (token > TT_KEYWORD) {
+            ident = identifier;
+            setMarker("Avoid using keyword '" + ident + "' as variable name.", rowCount, PHPParser.INFO);
+          }
+          switch (token) {
+            case TT_VARIABLE :
+              ident = identifier;
+              getNextToken();
+              //              if (token == TT_ARGOPEN) {
+              //                getNextToken();
+              //                expressionList();
+              //                if (token != TT_ARGCLOSE) {
+              //                  throwSyntaxError(") expected after variable '" + ident + "'.");
+              //                }
+              //                getNextToken();
+              //              }
+              break;
+            case TT_IDENTIFIER :
+              ident = identifier;
+              getNextToken();
+              break;
+            case TT_LISTOPEN :
+              getNextToken();
+              expression();
+              if (token != TT_LISTCLOSE) {
+                throwSyntaxError("} expected in postfix-expression.");
+              }
+              getNextToken();
+              break;
+            default :
+              throwSyntaxError("Syntax error after '->' token.");
+          } while (token == TT_PARTOPEN || token == TT_ARGOPEN || token == TT_LISTOPEN) {
+              if (token == TT_PARTOPEN) {
+                getNextToken();
+                expressionList();
+                if (token != TT_PARTCLOSE) {
+                  throwSyntaxError("] expected after '->'.");
+                }
+                getNextToken();
+              }
+              if (token == TT_ARGOPEN) {
+                getNextToken();
+                expressionList();
+                if (token != TT_ARGCLOSE) {
+                  throwSyntaxError(") expected after '->'.");
+                }
+                getNextToken();
+              }
+              if (token == TT_LISTOPEN) {
+                getNextToken();
+                expression();
+                if (token != TT_LISTCLOSE) {
+                  throwSyntaxError("} expected after '->'.");
+                }
+                getNextToken();
+              }
+            }
+          break;
+        case TT_INCREMENT :
+          getNextToken();
+          break;
+        case TT_DECREMENT :
+          getNextToken();
+          break;
+        default :
+          while_flag = false;
+      }
+
+    }
+    while (while_flag);
+  }
+
+  private void unaryExpression() throws CoreException {
+    switch (token) {
+      case TT_INCREMENT :
+        getNextToken();
+        unaryExpression();
+        break;
+      case TT_DECREMENT :
+        getNextToken();
+        unaryExpression();
+        break;
+        // '@' '&' '*' '+' '-' '~' '!' 
+      case TT_AT :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_AMPERSAND :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_MULTIPLY :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_ADD :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_SUBTRACT :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_TILDE :
+        getNextToken();
+        castExpression();
+        break;
+      case TT_NOT :
+        getNextToken();
+        castExpression();
+        break;
+      default :
+        postfixExpression();
+    }
+  }
+
+  private void castExpression() throws CoreException {
+    //    if (token == TT_ARGOPEN) {
+    //      getNextToken();
+    //      typeName();
+    //      if (token != TT_ARGCLOSE) {
+    //        throwSyntaxError(") expected after cast-expression.");
+    //      }
+    //      getNextToken();
+    //    }
+    unaryExpression();
+  }
+
+  private void typeName() throws CoreException {
+    //'string' 'unset' 'array' 'object'
+    //'bool' 'boolean'
+    //'real' 'double' 'float'
+    //'int' 'integer'
+    String ident = "";
+    if (token == TT_IDENTIFIER) {
+      ident = identifier;
+      String str = identifier.toLowerCase();
+      getNextToken();
+      for (int i = 0; i < PHP_TYPES.length; i++) {
+        if (PHP_TYPES[i].equals(str)) {
+          return;
+        }
+      }
+    }
+    throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
+  }
+
+  private void assignExpression() throws CoreException {
+    castExpression();
+    if (token == TT_ASSIGN) { // =
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_DOTASSIGN) { // .=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_FOREACH) { // =>
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_ADDTO) { // +=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_SUBTRACTFROM) { // -=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_TIMESBY) { // *=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_DIVIDEBY) { // *=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_MODASSIGN) { // %=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_ANDASSIGN) { // &=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_POWASSIGN) { // ^=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_LSHIFTASSIGN) { // <<=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_RSHIFTASSIGN) { // >>=
+      getNextToken();
+      logicalinclusiveorExpression();
+    } else if (token == TT_TILDEASSIGN) { // ~=
+      getNextToken();
+      logicalinclusiveorExpression();
+    }
+  }
+
+  private void multiplicativeExpression() throws CoreException {
+    do {
+      assignExpression();
+      if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void concatenationExpression() throws CoreException {
+    do {
+      multiplicativeExpression();
+      if (token != TT_DOT) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void additiveExpression() throws CoreException {
+    do {
+      concatenationExpression();
+      if (token != TT_ADD && token != TT_SUBTRACT) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void shiftExpression() throws CoreException {
+    do {
+      additiveExpression();
+      if (token != TT_LSHIFT && token != TT_RSHIFT) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void relationalExpression() throws CoreException {
+    do {
+      shiftExpression();
+      if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void identicalExpression() throws CoreException {
+    do {
+      relationalExpression();
+      if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void equalityExpression() throws CoreException {
+    do {
+      identicalExpression();
+      if (token != TT_EQUAL && token != TT_UNEQUAL) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void ternaryExpression() throws CoreException {
+    equalityExpression();
+    if (token == TT_QUESTIONMARK) {
+      getNextToken();
+      expression();
+      if (token == TT_DDOT) {
+        getNextToken();
+        expression();
+      } else {
+        throwSyntaxError("':' expected in ternary operator '? :'.");
+      }
+    }
+  }
+
+  private void andExpression() throws CoreException {
+    do {
+      ternaryExpression();
+      if (token != TT_AMPERSAND) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void exclusiveorExpression() throws CoreException {
+    do {
+      andExpression();
+      if (token != TT_POW) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void inclusiveorExpression() throws CoreException {
+    do {
+      exclusiveorExpression();
+      if (token != TT_LINE) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void booleanandExpression() throws CoreException {
+    do {
+      inclusiveorExpression();
+      if (token != TT_AND) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void booleanorExpression() throws CoreException {
+    do {
+      booleanandExpression();
+      if (token != TT_OR) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void logicalandExpression() throws CoreException {
+    do {
+      booleanorExpression();
+      if (token != TT_and) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void logicalexclusiveorExpression() throws CoreException {
+    do {
+      logicalandExpression();
+      if (token != TT_xor) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  private void logicalinclusiveorExpression() throws CoreException {
+    do {
+      logicalexclusiveorExpression();
+      if (token != TT_or) {
+        return;
+      }
+      getNextToken();
+    } while (true);
+  }
+
+  //  public void assignmentExpression() {
+  //    if (token == TT_VARIABLE) {
+  //      getNextToken();
+  //      if (token == TT_SET) {
+  //        getNextToken();
+  //        logicalinclusiveorExpression();
+  //      }
+  //    } else {
+  //      logicalinclusiveorExpression();
+  //    }
+  //  }
+
+  private void variableList() throws CoreException {
+    do {
+      variable();
+      if (token == TT_COMMA) {
+        getNextToken();
+      } else {
+        break;
+      }
+    } while (true);
+  }
+
+  private void variable() throws CoreException {
+    if (token == TT_DOLLAROPEN) {
+      getNextToken();
+      expression();
+      ;
+      if (token != TT_LISTCLOSE) {
+        throwSyntaxError("'}' expected after indirect variable token '${'.");
+      }
+      getNextToken();
+    } else {
+      if (token == TT_VARIABLE) {
+        getNextToken();
+        if (token == TT_PARTOPEN) {
+          getNextToken();
+          expression();
+          if (token != TT_PARTCLOSE) {
+            throwSyntaxError("']' expected in variable-list.");
+          }
+          getNextToken();
+        } else if (token == TT_ASSIGN) {
+          getNextToken();
+          constant();
+        }
+      } else {
+        throwSyntaxError("$-variable expected in variable-list.");
+      }
+    }
+  }
+
+  private void constant() throws CoreException {
+    String ident;
+    switch (token) {
+      case TT_ADD :
+        getNextToken();
+        switch (token) {
+          case TT_DOUBLE_NUMBER :
+            getNextToken();
+            break;
+          case TT_INT_NUMBER :
+            getNextToken();
+            break;
+          default :
+            throwSyntaxError("Constant expected after '+' presign.");
+        }
+        break;
+      case TT_SUBTRACT :
+        getNextToken();
+        switch (token) {
+          case TT_DOUBLE_NUMBER :
+            getNextToken();
+            break;
+          case TT_INT_NUMBER :
+            getNextToken();
+            break;
+          default :
+            throwSyntaxError("Constant expected after '-' presign.");
+        }
+        break;
+      case TT_null :
+        getNextToken();
+        break;
+      case TT_false :
+        getNextToken();
+        break;
+      case TT_true :
+        getNextToken();
+        break;
+      case TT_IDENTIFIER :
+        ident = identifier;
+        getNextToken();
+        if (token == TT_ARGOPEN) {
+          getNextToken();
+          if (token != TT_ARGCLOSE) {
+            expressionList();
+            if (token != TT_ARGCLOSE) {
+              throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
+            }
+          }
+          getNextToken();
+        }
+        break;
+      case TT_STRING_CONSTANT :
+        getNextToken();
+        break;
+      case TT_INTERPOLATED_STRING :
+        getNextToken();
+        break;
+      case TT_DOUBLE_NUMBER :
+        getNextToken();
+        break;
+      case TT_INT_NUMBER :
+        getNextToken();
+        break;
+      default :
+        throwSyntaxError("Constant expected.");
+    }
+  }
+
+  /**
+   * Call the php parse command ( php -l -f &lt;filename&gt; )
+   * and create markers according to the external parser output
+   */
+  public static void phpExternalParse(IFile file) {
+    //IFile file = (IFile) resource;
+    IPath path = file.getFullPath();
+    IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
+    String filename = file.getLocation().toString();
+
+    String[] arguments = { filename };
+    MessageFormat form = new MessageFormat(store.getString(PHPeclipsePlugin.EXTERNAL_PARSER_PREF));
+    String command = form.format(arguments);
+
+    String parserResult = PHPStartApacheAction.execute(command, "External parser: ");
+
+    try {
+      // parse the buffer to find the errors and warnings
+      createMarkers(parserResult, file);
+    } catch (CoreException e) {
+    }
+  }
+
+  /**
+   * Create markers according to the external parser output
+   */
+  private static void createMarkers(String output, IFile file) throws CoreException {
+    // delete all markers
+    file.deleteMarkers(IMarker.PROBLEM, false, 0);
+
+    int indx = 0;
+    int brIndx = 0;
+    boolean flag = true;
+    while ((brIndx = output.indexOf("<br />", indx)) != -1) {
+      // newer php error output (tested with 4.2.3)
+      scanLine(output, file, indx, brIndx);
+      indx = brIndx + 6;
+      flag = false;
+    }
+    if (flag) {
+      while ((brIndx = output.indexOf("<br>", indx)) != -1) {
+        // older php error output (tested with 4.2.3)
+        scanLine(output, file, indx, brIndx);
+        indx = brIndx + 4;
+      }
+    }
+  }
+
+  private static void scanLine(String output, IFile file, int indx, int brIndx) throws CoreException {
+    String current;
+    String outLineNumberString;
+    StringBuffer lineNumberBuffer = new StringBuffer(10);
+    char ch;
+    current = output.substring(indx, brIndx);
+
+    if (current.indexOf(PARSE_WARNING_STRING) != -1 || current.indexOf(PARSE_ERROR_STRING) != -1) {
+      int onLine = current.indexOf("on line <b>");
+      if (onLine != -1) {
+        lineNumberBuffer.delete(0, lineNumberBuffer.length());
+        for (int i = onLine; i < current.length(); i++) {
+          ch = current.charAt(i);
+          if ('0' <= ch && '9' >= ch) {
+            lineNumberBuffer.append(ch);
+          }
+        }
+
+        int lineNumber = Integer.parseInt(lineNumberBuffer.toString());
+
+        Hashtable attributes = new Hashtable();
+
+        current = current.replaceAll("\n", "");
+        current = current.replaceAll("<b>", "");
+        current = current.replaceAll("</b>", "");
+        MarkerUtilities.setMessage(attributes, current);
+
+        if (current.indexOf(PARSE_ERROR_STRING) != -1)
+          attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
+        else if (current.indexOf(PARSE_WARNING_STRING) != -1)
+          attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
+        else
+          attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
+        MarkerUtilities.setLineNumber(attributes, lineNumber);
+        MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/SyntaxError.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/phpparser/SyntaxError.java
new file mode 100644 (file)
index 0000000..5da81e8
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SyntaxError.java
+ * Copyright (C) 2000 Klaus Hartlage
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+package net.sourceforge.phpeclipse.phpeditor.phpparser;
+
+/**
+ * Exception for a syntax error detected by the HartMath parser
+ * 
+ */
+public class SyntaxError extends Error {
+
+  int lineNumber;
+  int columnNumber;
+  String currentLine;
+  String error;
+  /**
+   * SyntaxError exception
+   * 
+   *
+   * @see
+   */
+  public SyntaxError(int lineNumber, int columnNumber, String currentLine, String error) {
+    this.lineNumber = lineNumber;
+    this.columnNumber = columnNumber;
+    this.currentLine = currentLine;
+    this.error = error;
+  }
+
+  public String getMessage() {
+    //    StringBuffer buf = new StringBuffer(256);
+    //    buf.append("Syntax error in line:");
+    //    buf.append(lineNumber+1);
+    //    buf.append(": "+ error + "\n");
+    //    buf.append( currentLine + "\n");
+    //    for (int i=0; i<(columnNumber-1); i++) {
+    //      buf.append(' ');
+    //    }
+    //    buf.append('^');
+    //    return buf.toString();
+    
+    
+    // System.err.println(currentLine);
+    //System.err.println(columnNumber);
+    return error;
+  }
+
+  public int getLine() {
+    return lineNumber;
+  }
+}