improved PHP Scanner
authorkhartlage <khartlage>
Sun, 2 Mar 2003 12:16:58 +0000 (12:16 +0000)
committerkhartlage <khartlage>
Sun, 2 Mar 2003 12:16:58 +0000 (12:16 +0000)
net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPManualTestCase.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPConstant.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPFunctionNames.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java

diff --git a/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPManualTestCase.java b/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPManualTestCase.java
new file mode 100644 (file)
index 0000000..bb7fcf0
--- /dev/null
@@ -0,0 +1,316 @@
+package junit.sourceforge.phpeclipse;
+/**********************************************************************
+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
+**********************************************************************/
+
+import net.sourceforge.phpdt.internal.compiler.parser.Parser;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.core.runtime.CoreException;
+import junit.framework.TestCase;
+
+/**
+ *  Tests the php parser
+ */
+public class PHPManualTestCase extends TestCase {
+
+  Parser parser;
+
+  public PHPManualTestCase(String name) {
+    super(name);
+  }
+
+  /**
+   *  Test the PHP Parser with different PHP snippets
+   */
+  public void testPHPParser() {
+    // Bugs item #690938
+    checkPHP(
+      "    echo \"This is a test\"; // This is a one-line c++ style comment\n"
+        + "    /* This is a multi line comment\n"
+        + "       yet another line of comment */\n"
+        + "    echo \"This is yet another test\";\n"
+        + "    echo \"One Final Test\"; # This is shell-style style comment \n");
+    checkPHP(
+      "$bool = TRUE;   // a boolean\n"
+        + "$str  = \"foo\";  // a string\n"
+        + "$int  = 12;     // an integer\n"
+        + "\n"
+        + "echo gettype($bool); // prints out \"boolean\"\n"
+        + "echo gettype($str);  // prints out \"string\"\n"
+        + ""
+        + "// If this is an integer, increment it by four\n"
+        + "if (is_int($int)) {\n"
+        + "    $int += 4;\n"
+        + "}\n"
+        + "\n"
+        + "// If $bool is a string, print it out\n"
+        + "// (does not print out anything)\n"
+        + "if (is_string($bool)) {\n"
+        + "    echo \"String: $bool\";\n"
+        + "}\n");
+
+    checkPHP("$foo = True; // assign the value TRUE to $foo");
+
+    checkPHP(
+      "// == is an operator which test\n"
+        + "// equality and returns a boolean\n"
+        + "if ($action == \"show_version\") {\n"
+        + "    echo \"The version is 1.23\";\n"
+        + "}\n"
+        + "\n"
+        + "// this is not necessary...\n"
+        + "if ($show_separators == TRUE) {\n"
+        + "    echo \"<hr>\\n\";\n"
+        + "}\n"
+        + "\n"
+        + "// ...because you can simply type\n"
+        + "if ($show_separators) {\n"
+        + "    echo \"<hr>\\n\";\n"
+        + "}");
+
+    checkPHP(
+      "echo gettype((bool) \"\");        // bool(false)\n"
+        + "echo gettype((bool) 1);         // bool(true)\n"
+        + "echo gettype((bool) -2);        // bool(true)\n"
+        + "echo gettype((bool) \"foo\");     // bool(true)\n"
+        + "echo gettype((bool) 2.3e5);     // bool(true)\n"
+        + "echo gettype((bool) array(12)); // bool(true)\n"
+        + "echo gettype((bool) array());   // bool(false)\n");
+
+    checkPHP(
+      "$a = 1234; # decimal number\n"
+        + "$a = -123; # a negative number\n"
+        + "$a = 0123; # octal number (equivalent to 83 decimal)\n"
+        + "$a = 0x1A; # hexadecimal number (equivalent to 26 decimal)\n");
+
+    checkPHP(
+      "$large_number =  2147483647;\n"
+        + "var_dump($large_number);\n"
+        + "// output: int(2147483647)\n"
+        + "\n"
+        + "$large_number =  2147483648;\n"
+        + "var_dump($large_number);\n"
+        + "// output: float(2147483648)\n"
+        + ""
+        + "// this goes also for hexadecimal specified integers:\n"
+        + "var_dump( 0x80000000 );\n"
+        + "// output: float(2147483648)\n"
+        + "\n"
+        + "$million = 1000000;\n"
+        + "$large_number =  50000 * $million;\n"
+        + "var_dump($large_number);\n"
+        + "// output: float(50000000000)\n");
+
+    checkPHP(
+      "var_dump(25/7);         // float(3.5714285714286)\n"
+        + "var_dump((int) (25/7)); // int(3)\n"
+        + "var_dump(round(25/7));  // float(4)");
+
+    checkPHP("echo (int) ( (0.1+0.7) * 10 ); // echoes 7!");
+
+    checkPHP("$a = 1.234; " + "$b = 1.2e3; " + "$c = 7E-10;");
+
+    checkPHP(
+      "echo 'this is a simple string';\n"
+        + "\n"
+        + "echo 'You can also have embedded newlines in \n"
+        + "strings this way as it is\n"
+        + "okay to do';\n"
+        + "\n"
+        + "// Outputs: \"I'll be back\"\n"
+        + "echo 'Arnold once said: \"I\\'ll be back\"';\n"
+        + "\n"
+        + "// Outputs: You deleted C:\\*.*?\n"
+        + "echo 'You deleted C:\\\\*.*?';\n"
+        + "\n"
+        + "// Outputs: You deleted C:\\*.*?\n"
+        + "echo 'You deleted C:\\\\*.*?';\n"
+        + "\n"
+        + "// Outputs: This will not expand: \\n a newline\n"
+        + "echo 'This will not expand: \\n a newline';\n"
+        + "\n"
+        + "// Outputs: Variables do not $expand $either\n"
+        + "echo 'Variables do not $expand $either';\n");
+
+    checkPHP(
+      "$str = <<<EOD\n"
+        + "Example of string\n"
+        + "spanning multiple lines\n"
+        + "using heredoc syntax.\n"
+        + "EOD;\n"
+        + "\n"
+        + "/* More complex example, with variables. */\n"
+        + "class foo\n"
+        + "{\n"
+        + "    var $foo;\n"
+        + "    var $bar;\n"
+        + "\n"
+        + "    function foo()\n"
+        + "    {\n"
+        + "        $this->foo = 'Foo';\n"
+        + "        $this->bar = array('Bar1', 'Bar2', 'Bar3');\n"
+        + "    }\n"
+        + "}\n"
+        + "\n"
+        + "$foo = new foo();\n"
+        + "$name = 'MyName';\n"
+        + "\n"
+        + "echo <<<EOT\n"
+        + "My name is \"$name\". I am printing some $foo->foo.\n"
+        + "Now, I am printing some {$foo->bar[1]}.\n"
+        + "This should print a capital 'A': \\x41\n"
+        + "EOT;\n");
+
+    checkPHP("echo \"This works: \" . $arr['foo'][3];");
+
+    checkPHP("echo \"\\$foo==$foo; type is \" . gettype ($foo) . \"<br />\\n\";");
+
+    checkPHP(
+      "$arr = array(\"foo\" => \"bar\", 12 => true);\n"
+        + "\n"
+        + "echo $arr[\"foo\"]; // bar\n"
+        + "echo $arr[12];    // 1\n");
+
+    checkPHP(
+      "// This array is the same as ...\n"
+        + "array(5 => 43, 32, 56, \"b\" => 12);\n"
+        + "\n"
+        + "// ...this array\n"
+        + "array(5 => 43, 6 => 32, 7 => 56, \"b\" => 12);\n");
+
+    checkPHP(
+      "$arr = array(5 => 1, 12 => 2);\n"
+        + "\n"
+        + "$arr[] = 56;    // This is the same as $arr[13] = 56;\n"
+        + "                // at this point of the script\n"
+        + "\n"
+        + "$arr[\"x\"] = 42; // This adds a new element to\n"
+        + "                // the array with key \"x\"\n"
+        + "                \n"
+        + "unset($arr[5]); // This removes the element from the array\n"
+        + "\n"
+        + "unset($arr);    // This deletes the whole array\n");
+
+    checkPHP("$foo[bar] = 'enemy';\n" + "echo $foo[bar];");
+
+    checkPHP(
+      "$a = array( 'color' => 'red',\n"
+        + "            'taste' => 'sweet',\n"
+        + "            'shape' => 'round',\n"
+        + "            'name'  => 'apple',\n"
+        + "                       4        // key will be 0\n"
+        + "          );\n"
+        + "\n"
+        + "// is completely equivalent with\n"
+        + "$a['color'] = 'red';\n"
+        + "$a['taste'] = 'sweet';\n"
+        + "$a['shape'] = 'round';\n"
+        + "$a['name']  = 'apple';\n"
+        + "$a[]        = 4;        // key will be 0\n"
+        + "\n"
+        + "$b[] = 'a';\n"
+        + "$b[] = 'b';\n"
+        + "$b[] = 'c';\n"
+        + "// will result in the array array(0 => 'a' , 1 => 'b' , 2 => 'c'),\n"
+        + "// or simply array('a', 'b', 'c')\n");
+
+    checkPHP(
+      "foreach ($colors as $key => $color) {\n"
+        + "    // won't work:\n"
+        + "    //$color = strtoupper($color);\n"
+        + "    \n"
+        + "    // works:\n"
+        + "    $colors[$key] = strtoupper($color);\n"
+        + "}\n"
+        + "print_r($colors);\n");
+
+    checkPHP(
+      "$fruits = array ( \"fruits\"  => array ( \"a\" => \"orange\",\n"
+        + "                                       \"b\" => \"banana\",\n"
+        + "                                       \"c\" => \"apple\"\n"
+        + "                                     ),\n"
+        + "                  \"numbers\" => array ( 1,\n"
+        + "                                       2,\n"
+        + "                                       3,\n"
+        + "                                       4,\n"
+        + "                                       5,\n"
+        + "                                       6,\n"
+        + "                                     ),\n"
+        + "                  \"holes\"   => array (      \"first\",\n"
+        + "                                       5 => \"second\",\n"
+        + "                                            \"third\"\n"
+        + "                                     )\n"
+        + "                );\n"
+        + "\n"
+        + "// Some examples to address values in the array above \n"
+        + "echo $fruits[\"holes\"][5];    // prints \"second\"\n"
+        + "echo $fruits[\"fruits\"][\"a\"]; // prints \"orange\"\n"
+        + "unset($fruits[\"holes\"][0]);  // remove \"first\"\n"
+        + "\n"
+        + "// Create a new multi-dimensional array\n"
+        + "$juices[\"apple\"][\"green\"] = \"good\"; \n");
+
+    checkPHP("$arr3 = &$arr1;");
+
+    checkPHP(
+      "class foo\n"
+        + "{\n"
+        + "    function do_foo()\n"
+        + "    {\n"
+        + "        echo \"Doing foo.\"; \n"
+        + "    }\n"
+        + "}\n"
+        + "\n"
+        + "$bar = new foo;\n"
+        + "$bar->do_foo();\n");
+
+    checkPHP(
+      "$obj = (object) 'ciao';\n" + 
+      "echo $obj->scalar;  // outputs 'ciao'");
+
+    checkPHP("$var = NULL;");
+
+    checkPHP("$var = \"Bob\";\n" +\r            "$Var = \"Joe\";\n" +\r          "echo \"$var, $Var\";      // outputs \"Bob, Joe\"\n" +\r        "\n" +\r   //    "$4site = 'not yet';     // invalid; starts with a number\n" +\r         "$_4site = 'not yet';    // valid; starts with an underscore\n" +\r      "$täyte = 'mansikka';  \n");
+
+    checkPHP("");
+
+    checkPHP("");
+
+    checkPHP("");
+  }
+
+  private void checkPHP(String strEval) {
+    try {
+      if (Scanner.DEBUG) {
+        System.out.println("\n------------------------------------");
+        System.out.println(strEval);
+      }
+      parser.phpParserTester(strEval, 1);
+    } catch (CoreException e) {
+    }
+  }
+
+  private void checkHTML(String strEval) {
+    try {
+      if (Scanner.DEBUG) {
+        System.out.println("\n------------------------------------");
+        System.out.println(strEval);
+      }
+      parser.parse(strEval);
+    } catch (CoreException e) {
+    }
+  }
+
+  /**
+   *  The JUnit setup method
+   */
+  protected void setUp() {
+    parser = new Parser(null);
+  }
+
+}
index 9e6855d..adf4c17 100644 (file)
@@ -8,6 +8,7 @@ http://www.eclipse.org/legal/cpl-v10.html
 **********************************************************************/
 
 import net.sourceforge.phpdt.internal.compiler.parser.Parser;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 
 import org.eclipse.core.runtime.CoreException;
 import junit.framework.TestCase;
@@ -134,7 +135,7 @@ public class PHPParserTestCase extends TestCase {
 
   private void checkPHP(String strEval) {
     try {
-      if (Parser.DEBUG) {
+      if (Scanner.DEBUG) {
         System.out.println("\n------------------------------------");
         System.out.println(strEval);
       }
@@ -145,7 +146,7 @@ public class PHPParserTestCase extends TestCase {
 
   private void checkHTML(String strEval) {
     try {
-      if (Parser.DEBUG) {
+      if (Scanner.DEBUG) {
         System.out.println("\n------------------------------------");
         System.out.println(strEval);
       }
index e3bea19..ea3cd80 100644 (file)
@@ -14,7 +14,6 @@ import java.util.ArrayList;
 import java.util.Hashtable;
 
 import net.sourceforge.phpdt.core.compiler.*;
-import net.sourceforge.phpdt.internal.compiler.parser.*;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.PHPString;
 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
@@ -26,13 +25,14 @@ import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.ui.texteditor.MarkerUtilities;
 import test.PHPParserSuperclass;
 
-public class Parser extends PHPParserSuperclass implements PHPKeywords, ITerminalSymbols {
+public class Parser
+  extends PHPParserSuperclass
+  implements PHPKeywords, ITerminalSymbols {
 
   public static final int ERROR = 2;
   public static final int WARNING = 1;
   public static final int INFO = 0;
 
-  public static final boolean DEBUG = false;
   //scanner token 
   public Scanner scanner;
 
@@ -46,7 +46,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private String str;
 
   // current character
-//  char ch;
+  //  char ch;
   // current token
   int token;
 
@@ -66,7 +66,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private String stringValue;
 
   /** Contains the current expression. */
- // private StringBuffer expression;
+  // private StringBuffer expression;
 
   private boolean phpMode;
 
@@ -166,20 +166,20 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    *@see
    */
   public Parser(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]));
-//      }
-//    }
+    //    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 = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     //   getNextToken();
 
@@ -239,28 +239,24 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    */
   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);
-    throw new SyntaxError(
-      1,
-      1,
-      "",
-      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);
+    throw new SyntaxError(1, 1, "", error);
   }
 
   /**
@@ -278,18 +274,18 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    *
    *@see
    */
-//  private void getChar() {
-//    if (str.length() > chIndx) {
-//      ch = str.charAt(chIndx++);
-//
-//      return;
-//    }
-//
-//    chIndx = str.length() + 1;
-//    ch = ' ';
-//    //  token = TokenNameEOF;
-//    phpEnd = true;
-//  }
+  //  private void getChar() {
+  //    if (str.length() > chIndx) {
+  //      ch = str.charAt(chIndx++);
+  //
+  //      return;
+  //    }
+  //
+  //    chIndx = str.length() + 1;
+  //    ch = ' ';
+  //    //  token = TokenNameEOF;
+  //    phpEnd = true;
+  //  }
 
   /**
    * gets the next token from input
@@ -297,7 +293,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private void getNextToken() throws CoreException {
     try {
       token = scanner.getNextToken();
-      if (DEBUG) {
+      if (Scanner.DEBUG) {
         int currentEndPosition = scanner.getCurrentTokenEndPosition();
         int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
@@ -928,137 +924,137 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
    * value {@link Parser#TokenNameINT_NUMBER}
    */
-//  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 = TokenNameDoubleLiteral;
-//        return;
-//      } else {
-//        longNumber = Long.valueOf(inum.toString(), numFormat);
-//        token = TokenNameIntegerLiteral;
-//        return;
-//      }
-//
-//    } catch (Throwable e) {
-//      throwSyntaxError("Number format error: " + inum.toString());
-//    }
-//  }
-//
-//  /**
-//   * Get a String.
-//   * @param openChar the opening char ('\'', '"', '`')
-//   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
-//   * @param errorMsg the error message in case of parse error in the string
-//   */
-//  private void getString(
-//    final char openChar,
-//    final int typeString,
-//    final String errorMsg) {
-//    StringBuffer sBuffer = new StringBuffer();
-//    boolean openString = true;
-//    int startRow = rowCount;
-//    while (str.length() > chIndx) {
-//      ch = str.charAt(chIndx++);
-//      if (ch == '\\') {
-//        sBuffer.append(ch);
-//        if (str.length() > chIndx) {
-//          ch = str.charAt(chIndx++);
-//          sBuffer.append(ch);
-//        }
-//      } else if (ch == openChar) {
-//        openString = false;
-//        break;
-//      } else if (ch == '\n') {
-//        rowCount++;
-//        columnCount = chIndx;
-//      } else {
-//        sBuffer.append(ch);
-//      }
-//    }
-//    if (openString) {
-//      if (typeString == TokenNameStringConstant) {
-//        throwSyntaxError(errorMsg, startRow);
-//      } else {
-//        throwSyntaxError(errorMsg);
-//      }
-//    }
-//    token = typeString;
-//    stringValue = sBuffer.toString();
-//  }
+  //  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 = TokenNameDoubleLiteral;
+  //        return;
+  //      } else {
+  //        longNumber = Long.valueOf(inum.toString(), numFormat);
+  //        token = TokenNameIntegerLiteral;
+  //        return;
+  //      }
+  //
+  //    } catch (Throwable e) {
+  //      throwSyntaxError("Number format error: " + inum.toString());
+  //    }
+  //  }
+  //
+  //  /**
+  //   * Get a String.
+  //   * @param openChar the opening char ('\'', '"', '`')
+  //   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
+  //   * @param errorMsg the error message in case of parse error in the string
+  //   */
+  //  private void getString(
+  //    final char openChar,
+  //    final int typeString,
+  //    final String errorMsg) {
+  //    StringBuffer sBuffer = new StringBuffer();
+  //    boolean openString = true;
+  //    int startRow = rowCount;
+  //    while (str.length() > chIndx) {
+  //      ch = str.charAt(chIndx++);
+  //      if (ch == '\\') {
+  //        sBuffer.append(ch);
+  //        if (str.length() > chIndx) {
+  //          ch = str.charAt(chIndx++);
+  //          sBuffer.append(ch);
+  //        }
+  //      } else if (ch == openChar) {
+  //        openString = false;
+  //        break;
+  //      } else if (ch == '\n') {
+  //        rowCount++;
+  //        columnCount = chIndx;
+  //      } else {
+  //        sBuffer.append(ch);
+  //      }
+  //    }
+  //    if (openString) {
+  //      if (typeString == TokenNameStringConstant) {
+  //        throwSyntaxError(errorMsg, startRow);
+  //      } else {
+  //        throwSyntaxError(errorMsg);
+  //      }
+  //    }
+  //    token = typeString;
+  //    stringValue = sBuffer.toString();
+  //  }
 
   //   public void htmlParserTester(String input) {
   //           int lineNumber = 1;
@@ -1278,9 +1274,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
     }
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = rowCount;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = rowCount;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = true;
     scanner.setSource(s.toCharArray());
@@ -1291,7 +1287,13 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         if (token != TokenNameEOF && token != TokenNameERROR) {
           statementList();
         }
-        if (token != TokenNameEOF && token != TokenNameERROR) {
+        if (token != TokenNameEOF) {
+          if (token == TokenNameERROR) {
+            throwSyntaxError(
+              "Scanner error (Found unknown token: "
+                + scanner.toStringAction(token)
+                + ")");
+          }
           if (token == TokenNameRPAREN) {
             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
           }
@@ -1350,9 +1352,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   public void parse(String s) throws CoreException {
     this.str = s;
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = false;
     /* scanner initialization */
@@ -1364,7 +1366,13 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         if (token != TokenNameEOF && token != TokenNameERROR) {
           statementList();
         }
-        if (token != TokenNameEOF && token != TokenNameERROR) {
+        if (token != TokenNameEOF) {
+          if (token == TokenNameERROR) {
+            throwSyntaxError(
+              "Scanner error (Found unknown token: "
+                + scanner.toStringAction(token)
+                + ")");
+          }
           if (token == TokenNameRPAREN) {
             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
           }
@@ -1429,9 +1437,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
 
     this.str = s;
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = false;
     scanner.setSource(s.toCharArray());
@@ -1453,7 +1461,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
     PHPSegmentWithChildren temp;
     int counter = 0;
-    
+
     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
     try {
       while (token != TokenNameEOF && token != TokenNameERROR) {
@@ -1470,7 +1478,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
             outlineInfo.addVariable(variableName);
             getNextToken();
             if (token != TokenNameSEMICOLON) {
-              
+
               getNextToken();
               ident = scanner.getCurrentTokenSource();
               if (token > TokenNameKEYWORD) {
@@ -1581,12 +1589,12 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
             || token == TokenNamerequire_once
             || token == TokenNameinclude
             || token == TokenNameinclude_once) {
-          ident =   scanner.getCurrentTokenSource(); 
-         
+          ident = scanner.getCurrentTokenSource();
+
           getNextToken();
           int startPosition = scanner.getCurrentTokenStartPosition();
           expression();
-          char[] expr =   scanner.getCurrentTokenSource(startPosition); 
+          char[] expr = scanner.getCurrentTokenSource(startPosition);
           outlineInfo.addVariable(new String(ident));
           current.add(new PHPReqIncDeclaration(current, new String(ident),
           //    chIndx - ident.length,
@@ -2453,14 +2461,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
 
   private void expression() throws CoreException {
     //todo: find a better way to get the expression
-//    expression = new StringBuffer();
-//    for (int i = chIndx; i < str.length(); i++) {
-//      if (str.charAt(i) == ';') {
-//        break;
-//      }
-//      expression.append(str.charAt(i));
-//    }
-    
+    //    expression = new StringBuffer();
+    //    for (int i = chIndx; i < str.length(); i++) {
+    //      if (str.charAt(i) == ';') {
+    //        break;
+    //      }
+    //      expression.append(str.charAt(i));
+    //    }
+
     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
     //      getNextToken();
     //    } else {
index c5d042b..0826535 100644 (file)
@@ -156,12 +156,31 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public static final int SquareBracket = 1;
   public static final int CurlyBracket = 2;
   public static final int BracketKinds = 3;
+
+  public static final boolean DEBUG = false;
   public Scanner() {
     this(false, false);
   }
   public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace) {
     this(tokenizeComments, tokenizeWhiteSpace, false);
   }
+
+  /**
+   * Determines if the specified character is
+   * permissible as the first character in a PHP identifier
+   */
+  public static boolean isPHPIdentifierStart(char ch) {
+    return Character.isLetter(ch) || (ch == '_');
+  }
+
+  /**
+   * Determines if the specified character may be part of a PHP identifier as
+   * other than the first character
+   */
+  public static boolean isPHPIdentifierPart(char ch) {
+    return Character.isLetterOrDigit(ch) || (ch == '_');
+  }
+
   public final boolean atEnd() {
     // This code is not relevant if source is 
     // Only a part of the real stream input
@@ -232,7 +251,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
     }
     return result;
   }
-  
+
   public final char[] getCurrentTokenSource(int startPos) {
     // Return the token REAL source (aka unicodes are precomputed)
 
@@ -256,7 +275,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
     }
     return result;
   }
-  
+
   public final char[] getCurrentTokenSourceString() {
     //return the token REAL source (aka unicodes are precomputed).
     //REMOVE the two " that are at the beginning and the end.
@@ -663,7 +682,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
         }
 
         currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-        if (!Character.isJavaIdentifierPart(currentCharacter)) {
+        if (!isPHPIdentifierPart(currentCharacter)) {
           currentPosition = temp;
           return false;
         }
@@ -684,7 +703,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return true;
       } //-------------end unicode traitement--------------
       else {
-        if (!Character.isJavaIdentifierPart(currentCharacter)) {
+        if (!isPHPIdentifierPart(currentCharacter)) {
           currentPosition = temp;
           return false;
         }
@@ -860,12 +879,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
                     int heredocStart = currentPosition;
                     int heredocLength = 0;
                     currentCharacter = source[currentPosition++];
-                    if (Character.isJavaIdentifierStart(currentCharacter)) {
+                    if (isPHPIdentifierStart(currentCharacter)) {
                       currentCharacter = source[currentPosition++];
                     } else {
                       return TokenNameERROR;
                     }
-                    while (Character.isJavaIdentifierPart(currentCharacter)) {
+                    while (isPHPIdentifierPart(currentCharacter)) {
                       currentCharacter = source[currentPosition++];
                     }
 
@@ -1047,28 +1066,28 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 }
 
                 while (currentCharacter != '\'') {
-                  
+
                   /**** in PHP \r and \n are valid in string literals ****/
-//                  if ((currentCharacter == '\n')
-//                    || (currentCharacter == '\r')) {
-//                    // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
-//                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-//                      if (currentPosition + lookAhead == source.length)
-//                        break;
-//                      if (source[currentPosition + lookAhead] == '\n')
-//                        break;
-//                      if (source[currentPosition + lookAhead] == '\"') {
-//                        currentPosition += lookAhead + 1;
-//                        break;
-//                      }
-//                    }
-//                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
-//                  }
+                  //                  if ((currentCharacter == '\n')
+                  //                    || (currentCharacter == '\r')) {
+                  //                    // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+                  //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                  //                      if (currentPosition + lookAhead == source.length)
+                  //                        break;
+                  //                      if (source[currentPosition + lookAhead] == '\n')
+                  //                        break;
+                  //                      if (source[currentPosition + lookAhead] == '\"') {
+                  //                        currentPosition += lookAhead + 1;
+                  //                        break;
+                  //                      }
+                  //                    }
+                  //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+                  //                  }
                   if (currentCharacter == '\\') {
                     int escapeSize = currentPosition;
                     boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
                     //scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-                    scanEscapeCharacter();
+                    scanSingleQuotedEscapeCharacter();
                     escapeSize = currentPosition - escapeSize;
                     if (withoutUnicodePtr == 0) {
                       //buffer all the entries that have been left aside....
@@ -1149,29 +1168,28 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 }
 
                 while (currentCharacter != '"') {
-                  
-                  
+
                   /**** in PHP \r and \n are valid in string literals ****/
-//                  if ((currentCharacter == '\n')
-//                    || (currentCharacter == '\r')) {
-//                    // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
-//                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-//                      if (currentPosition + lookAhead == source.length)
-//                        break;
-//                      if (source[currentPosition + lookAhead] == '\n')
-//                        break;
-//                      if (source[currentPosition + lookAhead] == '\"') {
-//                        currentPosition += lookAhead + 1;
-//                        break;
-//                      }
-//                    }
-//                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
-//                  }
+                  //                  if ((currentCharacter == '\n')
+                  //                    || (currentCharacter == '\r')) {
+                  //                    // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+                  //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                  //                      if (currentPosition + lookAhead == source.length)
+                  //                        break;
+                  //                      if (source[currentPosition + lookAhead] == '\n')
+                  //                        break;
+                  //                      if (source[currentPosition + lookAhead] == '\"') {
+                  //                        currentPosition += lookAhead + 1;
+                  //                        break;
+                  //                      }
+                  //                    }
+                  //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+                  //                  }
                   if (currentCharacter == '\\') {
                     int escapeSize = currentPosition;
                     boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
                     //scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-                    scanEscapeCharacter();
+                    scanDoubleQuotedEscapeCharacter();
                     escapeSize = currentPosition - escapeSize;
                     if (withoutUnicodePtr == 0) {
                       //buffer all the entries that have been left aside....
@@ -1238,64 +1256,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
               }
               return TokenNameStringLiteral;
             case '`' :
-            try {
-              // consume next character
-              unicodeAsBackSlash = false;
-              if (((currentCharacter = source[currentPosition++]) == '\\')
-                && (source[currentPosition] == 'u')) {
-                getNextUnicodeChar();
-              } else {
-                if (withoutUnicodePtr != 0) {
-                  withoutUnicodeBuffer[++withoutUnicodePtr] =
-                    currentCharacter;
-                }
-              }
-
-              while (currentCharacter != '`') {
-                  
-                  
-                /**** in PHP \r and \n are valid in string literals ****/
-//                if ((currentCharacter == '\n')
-//                  || (currentCharacter == '\r')) {
-//                  // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
-//                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-//                    if (currentPosition + lookAhead == source.length)
-//                      break;
-//                    if (source[currentPosition + lookAhead] == '\n')
-//                      break;
-//                    if (source[currentPosition + lookAhead] == '\"') {
-//                      currentPosition += lookAhead + 1;
-//                      break;
-//                    }
-//                  }
-//                  throw new InvalidInputException(INVALID_CHAR_IN_STRING);
-//                }
-                if (currentCharacter == '\\') {
-                  int escapeSize = currentPosition;
-                  boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
-                  //scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-                  scanEscapeCharacter();
-                  escapeSize = currentPosition - escapeSize;
-                  if (withoutUnicodePtr == 0) {
-                    //buffer all the entries that have been left aside....
-                    withoutUnicodePtr =
-                      currentPosition - escapeSize - 1 - startPosition;
-                    System.arraycopy(
-                      source,
-                      startPosition,
-                      withoutUnicodeBuffer,
-                      1,
-                      withoutUnicodePtr);
-                    withoutUnicodeBuffer[++withoutUnicodePtr] =
-                      currentCharacter;
-                  } else { //overwrite the / in the buffer
-                    withoutUnicodeBuffer[withoutUnicodePtr] =
-                      currentCharacter;
-                    if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
-                      withoutUnicodePtr--;
-                    }
-                  }
-                }
+              try {
                 // consume next character
                 unicodeAsBackSlash = false;
                 if (((currentCharacter = source[currentPosition++]) == '\\')
@@ -1308,38 +1269,94 @@ public class Scanner implements IScanner, ITerminalSymbols {
                   }
                 }
 
-              }
-            } catch (IndexOutOfBoundsException e) {
-              throw new InvalidInputException(UNTERMINATED_STRING);
-            } catch (InvalidInputException e) {
-              if (e.getMessage().equals(INVALID_ESCAPE)) {
-                // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
-                for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                  if (currentPosition + lookAhead == source.length)
-                    break;
-                  if (source[currentPosition + lookAhead] == '\n')
-                    break;
-                  if (source[currentPosition + lookAhead] == '`') {
-                    currentPosition += lookAhead + 1;
-                    break;
+                while (currentCharacter != '`') {
+
+                  /**** in PHP \r and \n are valid in string literals ****/
+                  //                if ((currentCharacter == '\n')
+                  //                  || (currentCharacter == '\r')) {
+                  //                  // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+                  //                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                  //                    if (currentPosition + lookAhead == source.length)
+                  //                      break;
+                  //                    if (source[currentPosition + lookAhead] == '\n')
+                  //                      break;
+                  //                    if (source[currentPosition + lookAhead] == '\"') {
+                  //                      currentPosition += lookAhead + 1;
+                  //                      break;
+                  //                    }
+                  //                  }
+                  //                  throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+                  //                }
+                  if (currentCharacter == '\\') {
+                    int escapeSize = currentPosition;
+                    boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
+                    //scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
+                    scanDoubleQuotedEscapeCharacter();
+                    escapeSize = currentPosition - escapeSize;
+                    if (withoutUnicodePtr == 0) {
+                      //buffer all the entries that have been left aside....
+                      withoutUnicodePtr =
+                        currentPosition - escapeSize - 1 - startPosition;
+                      System.arraycopy(
+                        source,
+                        startPosition,
+                        withoutUnicodeBuffer,
+                        1,
+                        withoutUnicodePtr);
+                      withoutUnicodeBuffer[++withoutUnicodePtr] =
+                        currentCharacter;
+                    } else { //overwrite the / in the buffer
+                      withoutUnicodeBuffer[withoutUnicodePtr] =
+                        currentCharacter;
+                      if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
+                        withoutUnicodePtr--;
+                      }
+                    }
                   }
+                  // consume next character
+                  unicodeAsBackSlash = false;
+                  if (((currentCharacter = source[currentPosition++]) == '\\')
+                    && (source[currentPosition] == 'u')) {
+                    getNextUnicodeChar();
+                  } else {
+                    if (withoutUnicodePtr != 0) {
+                      withoutUnicodeBuffer[++withoutUnicodePtr] =
+                        currentCharacter;
+                    }
+                  }
+
                 }
+              } catch (IndexOutOfBoundsException e) {
+                throw new InvalidInputException(UNTERMINATED_STRING);
+              } catch (InvalidInputException e) {
+                if (e.getMessage().equals(INVALID_ESCAPE)) {
+                  // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                    if (currentPosition + lookAhead == source.length)
+                      break;
+                    if (source[currentPosition + lookAhead] == '\n')
+                      break;
+                    if (source[currentPosition + lookAhead] == '`') {
+                      currentPosition += lookAhead + 1;
+                      break;
+                    }
+                  }
 
+                }
+                throw e; // rethrow
               }
-              throw e; // rethrow
-            }
-            if (checkNonExternalizedStringLiterals) { // check for presence of NLS tags //$NON-NLS-?$ where ? is an int.
-              if (currentLine == null) {
-                currentLine = new NLSLine();
-                lines.add(currentLine);
+              if (checkNonExternalizedStringLiterals) { // check for presence of       NLS tags //$NON-NLS-?$ where ? is an int.
+                if (currentLine == null) {
+                  currentLine = new NLSLine();
+                  lines.add(currentLine);
+                }
+                currentLine.add(
+                  new StringLiteral(
+                    getCurrentTokenSourceString(),
+                    startPosition,
+                    currentPosition - 1));
               }
-              currentLine.add(
-                new StringLiteral(
-                  getCurrentTokenSourceString(),
-                  startPosition,
-                  currentPosition - 1));
-            }
-            return TokenNameStringInterpolated;
+              return TokenNameStringInterpolated;
             case '#' :
             case '/' :
               {
@@ -1568,11 +1585,15 @@ public class Scanner implements IScanner, ITerminalSymbols {
 
             default :
               if (currentCharacter == '$') {
-                if (getNextChar('{'))
+                while ( (currentCharacter = source[currentPosition++])=='$') {
+                }
+                if (currentCharacter == '{')
                   return TokenNameDOLLAR_LBRACE;
-                return scanIdentifierOrKeyword(true);
+                if (isPHPIdentifierStart(currentCharacter))
+                  return scanIdentifierOrKeyword(true);
+                return TokenNameERROR;
               }
-              if (Character.isJavaIdentifierStart(currentCharacter))
+              if (isPHPIdentifierStart(currentCharacter))
                 return scanIdentifierOrKeyword(false);
               if (Character.isDigit(currentCharacter))
                 return scanNumber(false);
@@ -1669,7 +1690,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
               test = getNextChar('\\');
               if (test) {
                 try {
-                  scanEscapeCharacter();
+                  scanDoubleQuotedEscapeCharacter();
                 } catch (InvalidInputException ex) {
                 };
               } else {
@@ -1718,7 +1739,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 }
                 if (currentCharacter == '\\') {
                   try {
-                    scanEscapeCharacter();
+                    scanDoubleQuotedEscapeCharacter();
                   } catch (InvalidInputException ex) {
                   };
                 }
@@ -1930,7 +1951,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
             }
 
           default :
-            if (Character.isJavaIdentifierStart(currentCharacter)
+            if (isPHPIdentifierStart(currentCharacter)
               || currentCharacter == '$') {
               try {
                 scanIdentifierOrKeyword((currentCharacter == '$'));
@@ -2421,7 +2442,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
     commentPtr = -1; // reset comment stack
   }
 
-  public final void scanEscapeCharacter() throws InvalidInputException {
+  public final void scanSingleQuotedEscapeCharacter()
+    throws InvalidInputException {
     // the string with "\\u" is a legal string of two chars \ and u
     //thus we use a direct access to the source (for regular cases).
 
@@ -2439,18 +2461,49 @@ public class Scanner implements IScanner, ITerminalSymbols {
     } else
       currentCharacter = source[currentPosition++];
     switch (currentCharacter) {
-      case 'b' :
-        currentCharacter = '\b';
+      case '\'' :
+        currentCharacter = '\'';
         break;
+      case '\\' :
+        currentCharacter = '\\';
+        break;
+      default :
+        currentCharacter = '\\';
+        currentPosition--;
+    }
+  }
+
+  public final void scanDoubleQuotedEscapeCharacter()
+    throws InvalidInputException {
+    // the string with "\\u" is a legal string of two chars \ and u
+    //thus we use a direct access to the source (for regular cases).
+
+    if (unicodeAsBackSlash) {
+      // consume next character
+      unicodeAsBackSlash = false;
+      if (((currentCharacter = source[currentPosition++]) == '\\')
+        && (source[currentPosition] == 'u')) {
+        getNextUnicodeChar();
+      } else {
+        if (withoutUnicodePtr != 0) {
+          withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
+        }
+      }
+    } else
+      currentCharacter = source[currentPosition++];
+    switch (currentCharacter) {
+      //      case 'b' :
+      //        currentCharacter = '\b';
+      //        break;
       case 't' :
         currentCharacter = '\t';
         break;
       case 'n' :
         currentCharacter = '\n';
         break;
-      case 'f' :
-        currentCharacter = '\f';
-        break;
+        //      case 'f' :
+        //        currentCharacter = '\f';
+        //        break;
       case 'r' :
         currentCharacter = '\r';
         break;
@@ -2463,6 +2516,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
       case '\\' :
         currentCharacter = '\\';
         break;
+      case '$' :
+        currentCharacter = '$';
+        break;
       default :
         // -----------octal escape--------------
         // OctalDigit
@@ -2522,6 +2578,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
     //disptach on the second char :-)...cool....but fast !
 
     useAssertAsAnIndentifier = false;
+    
     while (getNextCharAsJavaIdentifierPart()) {
     };
 
index 68119e7..6e09389 100644 (file)
@@ -1,6 +1,5 @@
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-
 /**
  * @author Choochter
  *
@@ -9,8 +8,8 @@ package net.sourceforge.phpeclipse.phpeditor.php;
  * To enable and disable the creation of type comments go to
  * Window>Preferences>Java>Code Generation.
  */
-public class PHPConstant extends PHPElement{
-       public PHPConstant(String Name, String Description){
-       super(Name, Description);
-       }
+public class PHPConstant extends PHPElement {
+  public PHPConstant(String Name, String Description) {
+    super(Name, Description);
+  }
 }
\ No newline at end of file
index 54720d6..e7bc6d9 100644 (file)
@@ -18,7 +18,7 @@ package net.sourceforge.phpeclipse.phpeditor.php;
  */
 public class PHPFunctionNames {
 
-       public static String[] FUNCTION_NAMES =
+        public static String[] FUNCTION_NAMES =
                {
                        "COM_invoke",
                        "COM_load",
index 646a990..c36c59d 100644 (file)
@@ -18,142 +18,148 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
  */
 public interface PHPKeywords extends ITerminalSymbols {
 
-  public final static String[] PHP_KEYWORS =
-    {
-      "if",
-      "elseif",
-      "else",
-      "endif",
-      "for",
-      "endfor",
-      "while",
-      "endwhile",
-      "switch",
-      "case",
-      "endswitch",
-      "break",
-      "continue",
-      "return",
-      "define",
-      "include",
-      "include_once",
-      "require",
-      "require_once",
-      "function",
-      "class",
-      "new",
-      "do",
-      "old_function",
-      "default",
-      "global",
-      "static",
-      "foreach",
-      "endforeach",
-      "extends",
-    //  "empty",
-    //  "array",
-    //   "isset",
-    "echo", "var", "as", 
-    "print", 
-    // "unset", 
-    // "exit", "die", 
-    // "and", "or", "xor", 
-    "list", 
-    "null", "false", "true" };
+//  public final static String[] PHP_KEYWORS =
+//    {
+//      "if",
+//      "elseif",
+//      "else",
+//      "endif",
+//      "for",
+//      "endfor",
+//      "while",
+//      "endwhile",
+//      "switch",
+//      "case",
+//      "endswitch",
+//      "break",
+//      "continue",
+//      "return",
+//      "define",
+//      "include",
+//      "include_once",
+//      "require",
+//      "require_once",
+//      "function",
+//      "class",
+//      "new",
+//      "do",
+//      "old_function",
+//      "default",
+//      "global",
+//      "static",
+//      "foreach",
+//      "endforeach",
+//      "extends",
+//      "empty",
+//      "array",
+//      "isset",
+//      "echo",
+//      "var",
+//      "as",
+//      "print",
+//      "unset",
+//      "exit",
+//      "die",
+//      "and",
+//      "or",
+//      "xor",
+//      "list",
+//      "null",
+//      "false",
+//      "true" };
 
-  public final static String[] PHP_TYPES =
-    { "string", "unset", 
-      //"array", 
-      "object", "bool", "boolean", "real", "double", "float", "int", "integer", };
+  public final static String[] PHP_TYPES = { "string", "unset",
+    //"array", 
+    "object", "bool", "boolean", "real", "double", "float", "int", "integer", };
 
-//  public final static int TokenNameKEYWORD = 1000;
-//  public final static int TokenNameif = 1001;
-//  public final static int TokenNameelseif = 1002;
-//  public final static int TokenNameelse = 1003;
-//  public final static int TokenNameendif = 1004;
-//  public final static int TokenNamefor = 1005;
-//  public final static int TokenNameendfor = 1006;
-//  public final static int TokenNamewhile = 1007;
-//  public final static int TokenNameendwhile = 1008;
-//  public final static int TokenNameswitch = 1009;
-//  public final static int TokenNamecase = 10010;
-//  public final static int TokenNameendswitch = 1011;
-//  public final static int TokenNamebreak = 1012;
-//  public final static int TokenNamecontinue = 1013;
-//  public final static int TokenNamereturn = 1014;
-//  public final static int TokenNamedefine = 1015;
-//  public final static int TokenNameinclude = 1016;
-//  public final static int TokenNameinclude_once = 1017;
-//  public final static int TokenNamerequire = 1018;
-//  public final static int TokenNamerequire_once = 1019;
-//  public final static int TokenNamefunction = 1020;
-//  public final static int TokenNameclass = 1021;
-//  public final static int TokenNamenew = 1022;
-//  public final static int TokenNamedo = 1023;
-//  public final static int TokenNameold_function = 1024;
-//  public final static int TokenNamedefault = 1025;
-//  public final static int TokenNameglobal = 1026;
-//  public final static int TokenNamestatic = 1027;
-//  public final static int TokenNameforeach = 1028;
-//  public final static int TokenNameendforeach = 1029;
-//  public final static int TokenNameextends = 1030;
-//  // public final static int TokenNameempty = 1031;
-//  // public final static int TokenNamearray = 1032;
-//  public final static int TokenNameecho = 1033;
-//  public final static int TokenNamevar = 1034;
-//  public final static int TokenNameas = 1035;
-//  public final static int TokenNameprint = 1036;
-// // public final static int TokenNameunset = 1037;
-// //  public final static int TokenNameexit = 1038;
-// // public final static int TokenNamedie = 1039;
-//  public final static int TokenNameand = 1040;
-//  public final static int TokenNameor = 1041;
-//  public final static int TokenNamexor = 1042;
-//  public final static int TokenNamelist = 1043;
-//  public final static int TokenNamenull = 1044;
-//  public final static int TokenNamefalse = 1045;
-//  public final static int TokenNametrue = 1046;
-/*
-  public final static int[] PHP_KEYWORD_TOKEN =
-    {
-      TokenNameif,
-      TokenNameelseif,
-      TokenNameelse,
-      TokenNameendif,
-      TokenNamefor,
-      TokenNameendfor,
-      TokenNamewhile,
-      TokenNameendwhile,
-      TokenNameswitch,
-      TokenNamecase,
-      TokenNameendswitch,
-      TokenNamebreak,
-      TokenNamecontinue,
-      TokenNamereturn,
-      TokenNamedefine,
-      TokenNameinclude,
-      TokenNameinclude_once,
-      TokenNamerequire,
-      TokenNamerequire_once,
-      TokenNamefunction,
-      TokenNameclass,
-      TokenNamenew,
-      TokenNamedo,
-      TokenNameold_function,
-      TokenNamedefault,
-      TokenNameglobal,
-      TokenNamestatic,
-      TokenNameforeach,
-      TokenNameendforeach,
-      TokenNameextends,
-    // TokenNameempty,
-    //  TokenNamearray,
-    //   TokenNameisset,
-    TokenNameecho, TokenNamevar, TokenNameas, 
-    TokenNameprint, 
-    // TokenNameunset, 
-    // TokenNameexit, TokenNamedie, 
-    // TokenNameand, TokenNameor, TokenNamexor, 
-    TokenNamelist, 
-    TokenNamenull, TokenNamefalse, TokenNametrue };*/
+  //  public final static int TokenNameKEYWORD = 1000;
+  //  public final static int TokenNameif = 1001;
+  //  public final static int TokenNameelseif = 1002;
+  //  public final static int TokenNameelse = 1003;
+  //  public final static int TokenNameendif = 1004;
+  //  public final static int TokenNamefor = 1005;
+  //  public final static int TokenNameendfor = 1006;
+  //  public final static int TokenNamewhile = 1007;
+  //  public final static int TokenNameendwhile = 1008;
+  //  public final static int TokenNameswitch = 1009;
+  //  public final static int TokenNamecase = 10010;
+  //  public final static int TokenNameendswitch = 1011;
+  //  public final static int TokenNamebreak = 1012;
+  //  public final static int TokenNamecontinue = 1013;
+  //  public final static int TokenNamereturn = 1014;
+  //  public final static int TokenNamedefine = 1015;
+  //  public final static int TokenNameinclude = 1016;
+  //  public final static int TokenNameinclude_once = 1017;
+  //  public final static int TokenNamerequire = 1018;
+  //  public final static int TokenNamerequire_once = 1019;
+  //  public final static int TokenNamefunction = 1020;
+  //  public final static int TokenNameclass = 1021;
+  //  public final static int TokenNamenew = 1022;
+  //  public final static int TokenNamedo = 1023;
+  //  public final static int TokenNameold_function = 1024;
+  //  public final static int TokenNamedefault = 1025;
+  //  public final static int TokenNameglobal = 1026;
+  //  public final static int TokenNamestatic = 1027;
+  //  public final static int TokenNameforeach = 1028;
+  //  public final static int TokenNameendforeach = 1029;
+  //  public final static int TokenNameextends = 1030;
+  //  // public final static int TokenNameempty = 1031;
+  //  // public final static int TokenNamearray = 1032;
+  //  public final static int TokenNameecho = 1033;
+  //  public final static int TokenNamevar = 1034;
+  //  public final static int TokenNameas = 1035;
+  //  public final static int TokenNameprint = 1036;
+  // // public final static int TokenNameunset = 1037;
+  // //  public final static int TokenNameexit = 1038;
+  // // public final static int TokenNamedie = 1039;
+  //  public final static int TokenNameand = 1040;
+  //  public final static int TokenNameor = 1041;
+  //  public final static int TokenNamexor = 1042;
+  //  public final static int TokenNamelist = 1043;
+  //  public final static int TokenNamenull = 1044;
+  //  public final static int TokenNamefalse = 1045;
+  //  public final static int TokenNametrue = 1046;
+  /*
+    public final static int[] PHP_KEYWORD_TOKEN =
+      {
+        TokenNameif,
+        TokenNameelseif,
+        TokenNameelse,
+        TokenNameendif,
+        TokenNamefor,
+        TokenNameendfor,
+        TokenNamewhile,
+        TokenNameendwhile,
+        TokenNameswitch,
+        TokenNamecase,
+        TokenNameendswitch,
+        TokenNamebreak,
+        TokenNamecontinue,
+        TokenNamereturn,
+        TokenNamedefine,
+        TokenNameinclude,
+        TokenNameinclude_once,
+        TokenNamerequire,
+        TokenNamerequire_once,
+        TokenNamefunction,
+        TokenNameclass,
+        TokenNamenew,
+        TokenNamedo,
+        TokenNameold_function,
+        TokenNamedefault,
+        TokenNameglobal,
+        TokenNamestatic,
+        TokenNameforeach,
+        TokenNameendforeach,
+        TokenNameextends,
+      // TokenNameempty,
+      //  TokenNamearray,
+      //   TokenNameisset,
+      TokenNameecho, TokenNamevar, TokenNameas, 
+      TokenNameprint, 
+      // TokenNameunset, 
+      // TokenNameexit, TokenNamedie, 
+      // TokenNameand, TokenNameor, TokenNamexor, 
+      TokenNamelist, 
+      TokenNamenull, TokenNamefalse, TokenNametrue };*/
 }