misc parser changes
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Scanner.java
index bef873a..041fd95 100644 (file)
@@ -131,6 +131,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public char[][] taskTags = null;
   public char[][] taskPriorities = null;
   public static final boolean DEBUG = false;
+  public static final boolean TRACE = false;
   public Scanner() {
     this(false, false);
   }
@@ -675,6 +676,133 @@ public class Scanner implements IScanner, ITerminalSymbols {
       return false;
     }
   }
+  public int getCastOrParen() {
+    int tempPosition = currentPosition;
+    char tempCharacter = currentCharacter;
+    int tempToken = TokenNameLPAREN;
+    boolean found = false;
+    StringBuffer buf = new StringBuffer();
+    try {
+      do {
+        currentCharacter = source[currentPosition++];
+      } while (currentCharacter == ' ' || currentCharacter == '\t');
+      while ((currentCharacter >= 'a' && currentCharacter <= 'z')
+          || (currentCharacter >= 'A' && currentCharacter <= 'Z')) {
+        buf.append(currentCharacter);
+        currentCharacter = source[currentPosition++];
+      }
+      if (buf.length() >= 3 && buf.length() <= 7) {
+        char[] data = buf.toString().toCharArray();
+        int index = 0;
+        switch (data.length) {
+          case 3 :
+            // int
+            if ((data[index] == 'i') && (data[++index] == 'n')
+                && (data[++index] == 't')) {
+              found = true;
+              tempToken = TokenNameintCAST;
+            }
+            break;
+          case 4 :
+            // bool real
+            if ((data[index] == 'b') && (data[++index] == 'o')
+                && (data[++index] == 'o') && (data[++index] == 'l')) {
+              found = true;
+              tempToken = TokenNameboolCAST;
+            } else {
+              index = 0;
+              if ((data[index] == 'r') && (data[++index] == 'e')
+                  && (data[++index] == 'a') && (data[++index] == 'l')) {
+                found = true;
+                tempToken = TokenNamedoubleCAST;
+              }
+            }
+            break;
+          case 5 :
+            // array unset float
+            if ((data[index] == 'a') && (data[++index] == 'r')
+                && (data[++index] == 'r') && (data[++index] == 'a')
+                && (data[++index] == 'y')) {
+              found = true;
+              tempToken = TokenNamearrayCAST;
+            } else {
+              index = 0;
+              if ((data[index] == 'u') && (data[++index] == 'n')
+                  && (data[++index] == 's') && (data[++index] == 'e')
+                  && (data[++index] == 't')) {
+                found = true;
+                tempToken = TokenNameunsetCAST;
+              } else {
+                index = 0;
+                if ((data[index] == 'f') && (data[++index] == 'l')
+                    && (data[++index] == 'o') && (data[++index] == 'a')
+                    && (data[++index] == 't')) {
+                  found = true;
+                  tempToken = TokenNamedoubleCAST;
+                }
+              }
+            }
+            break;
+          case 6 :
+            // object string double
+            if ((data[index] == 'o') && (data[++index] == 'b')
+                && (data[++index] == 'j') && (data[++index] == 'e')
+                && (data[++index] == 'c') && (data[++index] == 't')) {
+              found = true;
+              tempToken = TokenNameobjectCAST;
+            } else {
+              index = 0;
+              if ((data[index] == 's') && (data[++index] == 't')
+                  && (data[++index] == 'r') && (data[++index] == 'i')
+                  && (data[++index] == 'n') && (data[++index] == 'g')) {
+                found = true;
+                tempToken = TokenNamestringCAST;
+              } else {
+                index = 0;
+                if ((data[index] == 'd') && (data[++index] == 'o')
+                    && (data[++index] == 'u') && (data[++index] == 'b')
+                    && (data[++index] == 'l') && (data[++index] == 'e')) {
+                  found = true;
+                  tempToken = TokenNamedoubleCAST;
+                }
+              }
+            }
+            break;
+          case 7 :
+            // boolean integer
+            if ((data[index] == 'b') && (data[++index] == 'o')
+                && (data[++index] == 'o') && (data[++index] == 'l')
+                && (data[++index] == 'e') && (data[++index] == 'a')
+                && (data[++index] == 'n')) {
+              found = true;
+              tempToken = TokenNameboolCAST;
+            } else {
+              index = 0;
+              if ((data[index] == 'i') && (data[++index] == 'n')
+                  && (data[++index] == 't') && (data[++index] == 'e')
+                  && (data[++index] == 'g') && (data[++index] == 'e')
+                  && (data[++index] == 'r')) {
+                found = true;
+                tempToken = TokenNameintCAST;
+              }
+            }
+            break;
+        }
+        if (found) {
+          while (currentCharacter == ' ' || currentCharacter == '\t') {
+            currentCharacter = source[currentPosition++];
+          }
+          if (currentCharacter == ')') {
+            return tempToken;
+          }
+        }
+      }
+    } catch (IndexOutOfBoundsException e) {
+    }
+    currentCharacter = tempCharacter;
+    currentPosition = tempPosition;
+    return TokenNameLPAREN;
+  }
   public int getNextToken() throws InvalidInputException {
     int htmlPosition = currentPosition;
     try {
@@ -781,7 +909,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
           // ---------Identify the next token-------------
           switch (currentCharacter) {
             case '(' :
-              return TokenNameLPAREN;
+              return getCastOrParen();
             case ')' :
               return TokenNameRPAREN;
             case '{' :
@@ -797,6 +925,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
             case ',' :
               return TokenNameCOMMA;
             case '.' :
+              if (getNextChar('='))
+                return TokenNameDOT_EQUAL;
               if (getNextCharAsDigit())
                 return scanNumber(true);
               return TokenNameDOT;
@@ -842,56 +972,66 @@ public class Scanner implements IScanner, ITerminalSymbols {
               return TokenNameREMAINDER;
             case '<' :
               {
-                int test;
-                if ((test = getNextChar('=', '<')) == 0)
-                  return TokenNameLESS_EQUAL;
-                if (test > 0) {
-                  if (getNextChar('='))
-                    return TokenNameLEFT_SHIFT_EQUAL;
-                  if (getNextChar('<')) {
-                    int heredocStart = currentPosition;
-                    int heredocLength = 0;
-                    currentCharacter = source[currentPosition++];
-                    if (isPHPIdentifierStart(currentCharacter)) {
-                      currentCharacter = source[currentPosition++];
-                    } else {
-                      return TokenNameERROR;
-                    }
-                    while (isPHPIdentifierPart(currentCharacter)) {
+                int oldPosition = currentPosition;
+                try {
+                  currentCharacter = source[currentPosition++];
+                } catch (IndexOutOfBoundsException e) {
+                  currentPosition = oldPosition;
+                  return TokenNameLESS;
+                }
+                switch (currentCharacter) {
+                  case '=' :
+                    return TokenNameLESS_EQUAL;
+                  case '>' :
+                    return TokenNameNOT_EQUAL;
+                  case '<' :
+                    if (getNextChar('='))
+                      return TokenNameLEFT_SHIFT_EQUAL;
+                    if (getNextChar('<')) {
+                      int heredocStart = currentPosition;
+                      int heredocLength = 0;
                       currentCharacter = source[currentPosition++];
-                    }
-                    heredocLength = currentPosition - heredocStart - 1;
-                    // heredoc end-tag determination
-                    boolean endTag = true;
-                    char ch;
-                    do {
-                      ch = source[currentPosition++];
-                      if (ch == '\r' || ch == '\n') {
-                        if (recordLineSeparator) {
-                          pushLineSeparator();
-                        } else {
-                          currentLine = null;
-                        }
-                        for (int i = 0; i < heredocLength; i++) {
-                          if (source[currentPosition + i] != source[heredocStart
-                              + i]) {
-                            endTag = false;
-                            break;
+                      if (isPHPIdentifierStart(currentCharacter)) {
+                        currentCharacter = source[currentPosition++];
+                      } else {
+                        return TokenNameERROR;
+                      }
+                      while (isPHPIdentifierPart(currentCharacter)) {
+                        currentCharacter = source[currentPosition++];
+                      }
+                      heredocLength = currentPosition - heredocStart - 1;
+                      // heredoc end-tag determination
+                      boolean endTag = true;
+                      char ch;
+                      do {
+                        ch = source[currentPosition++];
+                        if (ch == '\r' || ch == '\n') {
+                          if (recordLineSeparator) {
+                            pushLineSeparator();
+                          } else {
+                            currentLine = null;
+                          }
+                          for (int i = 0; i < heredocLength; i++) {
+                            if (source[currentPosition + i] != source[heredocStart
+                                + i]) {
+                              endTag = false;
+                              break;
+                            }
+                          }
+                          if (endTag) {
+                            currentPosition += heredocLength - 1;
+                            currentCharacter = source[currentPosition++];
+                            break; // do...while loop
+                          } else {
+                            endTag = true;
                           }
                         }
-                        if (endTag) {
-                          currentPosition += heredocLength - 1;
-                          currentCharacter = source[currentPosition++];
-                          break; // do...while loop
-                        } else {
-                          endTag = true;
-                        }
-                      }
-                    } while (true);
-                    return TokenNameHEREDOC;
-                  }
-                  return TokenNameLEFT_SHIFT;
+                      } while (true);
+                      return TokenNameHEREDOC;
+                    }
+                    return TokenNameLEFT_SHIFT;
                 }
+                currentPosition = oldPosition;
                 return TokenNameLESS;
               }
             case '>' :
@@ -1330,9 +1470,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
             case '#' :
             case '/' :
               {
+                char startChar = currentCharacter;
+                if (getNextChar('=')) {
+                  return TokenNameDIVIDE_EQUAL;
+                }
                 int test;
-                if ((currentCharacter == '#')
-                    || (test = getNextChar('/', '*')) == 0) {
+                if ((startChar == '#') || (test = getNextChar('/', '*')) == 0) {
                   //line comment
                   int endPositionForLineComment = 0;
                   try { //get the next char
@@ -1546,8 +1689,6 @@ public class Scanner implements IScanner, ITerminalSymbols {
                   }
                   break;
                 }
-                if (getNextChar('='))
-                  return TokenNameDIVIDE_EQUAL;
                 return TokenNameDIVIDE;
               }
             case '\u001a' :
@@ -1558,13 +1699,20 @@ public class Scanner implements IScanner, ITerminalSymbols {
               throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
             default :
               if (currentCharacter == '$') {
-                while ((currentCharacter = source[currentPosition++]) == '$') {
+                int oldPosition = currentPosition;
+                try {
+                  currentCharacter = source[currentPosition++];
+                  
+                  if (isPHPIdentifierStart(currentCharacter)) {
+                    return scanIdentifierOrKeyword(true);
+                  } else {
+                    currentPosition = oldPosition;
+                    return TokenNameDOLLAR;
+                  }
+                } catch (IndexOutOfBoundsException e) {
+                  currentPosition = oldPosition;
+                  return TokenNameDOLLAR;
                 }
-                if (currentCharacter == '{')
-                  return TokenNameDOLLAR_LBRACE;
-                if (isPHPIdentifierStart(currentCharacter))
-                  return scanIdentifierOrKeyword(true);
-                return TokenNameERROR;
               }
               if (isPHPIdentifierStart(currentCharacter))
                 return scanIdentifierOrKeyword(false);
@@ -2508,9 +2656,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
     while (getNextCharAsJavaIdentifierPart()) {
     };
     if (isVariable) {
-      if (new String(getCurrentTokenSource()).equals("$this")) {
-        return TokenNamethis;
-      }
+      //      if (new String(getCurrentTokenSource()).equals("$this")) {
+      //        return TokenNamethis;
+      //      }
       return TokenNameVariable;
     }
     int index, length;
@@ -2600,7 +2748,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
           case 3 :
             //and
             if ((data[++index] == 'n') && (data[++index] == 'd')) {
-              return TokenNameAND;
+              return TokenNameand;
             } else {
               return TokenNameIdentifier;
             }
@@ -2635,7 +2783,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
             return TokenNameIdentifier;
         }
       case 'c' :
-        //case catch class const continue
+        //case catch class clone const continue
         switch (length) {
           case 4 :
             if ((data[++index] == 'a') && (data[++index] == 's')
@@ -2647,10 +2795,16 @@ public class Scanner implements IScanner, ITerminalSymbols {
             if ((data[++index] == 'a') && (data[++index] == 't')
                 && (data[++index] == 'c') && (data[++index] == 'h'))
               return TokenNamecatch;
-            if ((data[index] == 'l') && (data[++index] == 'a')
+            index = 0;
+            if ((data[++index] == 'l') && (data[++index] == 'a')
                 && (data[++index] == 's') && (data[++index] == 's'))
               return TokenNameclass;
-            if ((data[index] == 'o') && (data[++index] == 'n')
+            index = 0;
+            if ((data[++index] == 'l') && (data[++index] == 'o')
+                && (data[++index] == 'n') && (data[++index] == 'e'))
+              return TokenNameclone;
+            index = 0;
+            if ((data[++index] == 'o') && (data[++index] == 'n')
                 && (data[++index] == 's') && (data[++index] == 't'))
               return TokenNameconst;
             else
@@ -2793,9 +2947,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
             else
               return TokenNameIdentifier;
           case 5 :
-//            if ((data[++index] == 'a') && (data[++index] == 'l')
-//                && (data[++index] == 's') && (data[++index] == 'e'))
-//              return TokenNamefalse;
+            //            if ((data[++index] == 'a') && (data[++index] == 'l')
+            //                && (data[++index] == 's') && (data[++index] == 'e'))
+            //              return TokenNamefalse;
             if ((data[++index] == 'i') && (data[++index] == 'n')
                 && (data[++index] == 'a') && (data[++index] == 'l'))
               return TokenNamefinal;
@@ -2912,12 +3066,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
               return TokenNamenew;
             else
               return TokenNameIdentifier;
-//          case 4 :
-//            if ((data[++index] == 'u') && (data[++index] == 'l')
-//                && (data[++index] == 'l'))
-//              return TokenNamenull;
-//            else
-//              return TokenNameIdentifier;
+          //          case 4 :
+          //            if ((data[++index] == 'u') && (data[++index] == 'l')
+          //                && (data[++index] == 'l'))
+          //              return TokenNamenull;
+          //            else
+          //              return TokenNameIdentifier;
           default :
             return TokenNameIdentifier;
         }
@@ -2925,7 +3079,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
         // or old_function
         if (length == 2) {
           if (data[++index] == 'r') {
-            return TokenNameOR;
+            return TokenNameor;
           }
         }
         //        if (length == 12) {
@@ -3029,12 +3183,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
               return TokenNametry;
             else
               return TokenNameIdentifier;
-//          case 4 :
-//            if ((data[++index] == 'r') && (data[++index] == 'u')
-//                && (data[++index] == 'e'))
-//              return TokenNametrue;
-//            else
-//              return TokenNameIdentifier;
+          //          case 4 :
+          //            if ((data[++index] == 'r') && (data[++index] == 'u')
+          //                && (data[++index] == 'e'))
+          //              return TokenNametrue;
+          //            else
+          //              return TokenNameIdentifier;
           case 5 :
             if ((data[++index] == 'h') && (data[++index] == 'r')
                 && (data[++index] == 'o') && (data[++index] == 'w'))
@@ -3095,7 +3249,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
         switch (length) {
           case 3 :
             if ((data[++index] == 'o') && (data[++index] == 'r'))
-              return TokenNameXOR;
+              return TokenNamexor;
             else
               return TokenNameIdentifier;
           default :
@@ -3325,6 +3479,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "Variable(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameabstract :
         return "abstract"; //$NON-NLS-1$
+      case TokenNameand :
+        return "AND"; //$NON-NLS-1$
       case TokenNamearray :
         return "array"; //$NON-NLS-1$
       case TokenNameas :
@@ -3335,6 +3491,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "case"; //$NON-NLS-1$
       case TokenNameclass :
         return "class"; //$NON-NLS-1$
+      case TokenNameclone :
+        //$NON-NLS-1$
+        return "clone";
+      case TokenNameconst :
+        //$NON-NLS-1$
+        return "const";
       case TokenNamecontinue :
         return "continue"; //$NON-NLS-1$
       case TokenNamedefault :
@@ -3361,8 +3523,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "endwhile"; //$NON-NLS-1$
       case TokenNameextends :
         return "extends"; //$NON-NLS-1$
-//      case TokenNamefalse :
-//        return "false"; //$NON-NLS-1$
+      //      case TokenNamefalse :
+      //        return "false"; //$NON-NLS-1$
       case TokenNamefinal :
         return "final"; //$NON-NLS-1$
       case TokenNamefor :
@@ -3383,12 +3545,16 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "include_once"; //$NON-NLS-1$
       case TokenNameinterface :
         return "interface"; //$NON-NLS-1$
+      case TokenNameisset :
+        return "isset"; //$NON-NLS-1$
       case TokenNamelist :
         return "list"; //$NON-NLS-1$
       case TokenNamenew :
         return "new"; //$NON-NLS-1$
-//      case TokenNamenull :
-//        return "null"; //$NON-NLS-1$
+      //      case TokenNamenull :
+      //        return "null"; //$NON-NLS-1$
+      case TokenNameor :
+        return "OR"; //$NON-NLS-1$
       case TokenNameprint :
         return "print"; //$NON-NLS-1$
       case TokenNameprivate :
@@ -3407,16 +3573,18 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "static"; //$NON-NLS-1$
       case TokenNameswitch :
         return "switch"; //$NON-NLS-1$
-//      case TokenNametrue :
-//        return "true"; //$NON-NLS-1$
+      //      case TokenNametrue :
+      //        return "true"; //$NON-NLS-1$
       case TokenNameunset :
         return "unset"; //$NON-NLS-1$
       case TokenNamevar :
         return "var"; //$NON-NLS-1$
       case TokenNamewhile :
         return "while"; //$NON-NLS-1$
-      case TokenNamethis :
-        return "$this"; //$NON-NLS-1$
+      case TokenNamexor :
+        return "XOR"; //$NON-NLS-1$
+      //      case TokenNamethis :
+      //        return "$this"; //$NON-NLS-1$
       case TokenNameIntegerLiteral :
         return "Integer(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameDoubleLiteral :
@@ -3468,6 +3636,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "^="; //$NON-NLS-1$
       case TokenNameREMAINDER_EQUAL :
         return "%="; //$NON-NLS-1$
+      case TokenNameDOT_EQUAL :
+        return ".="; //$NON-NLS-1$
       case TokenNameLEFT_SHIFT_EQUAL :
         return "<<="; //$NON-NLS-1$
       case TokenNameRIGHT_SHIFT_EQUAL :
@@ -3530,8 +3700,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "="; //$NON-NLS-1$
       case TokenNameAT :
         return "@";
-      case TokenNameDOLLAR_LBRACE :
-        return "${";
+      case TokenNameDOLLAR :
+        return "$";
+      //      case TokenNameDOLLAR_LBRACE :
+      //        return "${";
       case TokenNameEOF :
         return "EOF"; //$NON-NLS-1$
       case TokenNameWHITESPACE :
@@ -3553,7 +3725,17 @@ public class Scanner implements IScanner, ITerminalSymbols {
       case TokenNameMETHOD_C :
         return "__METHOD__"; //$NON-NLS-1$
       case TokenNameFUNC_C :
-        return "__FUNCTION__"; //$NON-NLS-1$
+        return "__FUNCTION__"; //$NON-NLS-1
+      case TokenNameboolCAST :
+        return "( bool )"; //$NON-NLS-1$
+      case TokenNameintCAST :
+        return "( int )"; //$NON-NLS-1$
+      case TokenNamedoubleCAST :
+        return "( double )"; //$NON-NLS-1$
+      case TokenNameobjectCAST :
+        return "( object )"; //$NON-NLS-1$
+      case TokenNamestringCAST :
+        return "( string )"; //$NON-NLS-1$
       default :
         return "not-a-token(" + (new Integer(act)) + ") "
             + new String(getCurrentTokenSource()); //$NON-NLS-1$