improved php parser for keywords do-while, null, false, true...
authorkhartlage <khartlage>
Sat, 23 Nov 2002 16:12:15 +0000 (16:12 +0000)
committerkhartlage <khartlage>
Sat, 23 Nov 2002 16:12:15 +0000 (16:12 +0000)
net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java

index c0a677c..26589fc 100644 (file)
@@ -40,6 +40,7 @@ public class PHPParserTestCase extends TestCase {
     check("if (!$name) { \n }");
     check("mt_srand((double)microtime()*1000000);");
     check("\"\\\"\";");
+    check("$v->read();");
     check("$alttext = ereg_replace(\"\\\"\", \"\", $alttext);");
     check("$message .= \"\"._THISISAUTOMATED.\"\\n\\n\";");
     check("if (!empty($pass) AND $pass==$passwd) { }");
@@ -49,6 +50,16 @@ public class PHPParserTestCase extends TestCase {
     + ".\"<form action=\\\"admin.php\\\" method=\\\"post\\\">\"\n"
     + ".\"<tr><td><b>\"._NICKNAME.\":</b></td><td><input type=\\\"text\\\" name=\\\"name\\\" size=\\\"30\\\" maxlength=\\\"25\\\"></td></tr>\"\n"
     +";");
+    check("/* \n overLib is from Eric Bosrup (http://www.bosrup.com/web/overlib/) \n */");
+    check("if ($arrAtchCookie[1]==0 && $IdAtchPostId!=null){  } ");
+    check("$arrAtchCookie[1] -= filesize(realpath($AtchTempDir).\"/\".$xattachlist)/ 1024; ");
+    check("if (!isset($message)){ \n"
+    + "$message = $myrow[post_text];\n"
+    + "$message = eregi_replace(\"\\[addsig]\", \"\\n-----------------\\n\" .    $myrow[user_sig], $message); \n"
+    +"$message = str_replace(\"<BR>\", \"\\n\", $message); \n"
+    +"$message = str_replace(\"<br>\", \"\\n\", $message); \n } ");
+    check("do {$array[] = array(\"$myrow[uid]\" => \"$myrow[uname]\"); } while($myrow = mysql_fetch_array($result));");
+    check("$ol = new Overlib();");
   }
 
   public void check(String strEval) {
index 5848e7d..3bbd368 100644 (file)
@@ -62,7 +62,7 @@ public class PHPParser extends PHPKeywords {
   final static int TT_DDOT = 47;
   final static int TT_DOTASSIGN = 48;
 
-  final static int TT_SET = 49;
+  final static int TT_ASSIGN = 49;
   final static int TT_REF = 50;
   final static int TT_FOREACH = 51;
   final static int TT_AMPERSAND = 52;
@@ -197,7 +197,11 @@ public class PHPParser extends PHPKeywords {
                   chIndx += 2;
                   break;
                 }
-                chIndx++;
+                ch = str.charAt(chIndx++);
+                if (ch == '\n') {
+                  rowCount++;
+                  columnCount = chIndx;
+                }
               }
               continue;
             }
@@ -220,11 +224,9 @@ public class PHPParser extends PHPKeywords {
             } else if (ch == '"') {
               openString = false;
               break;
-            } else {
-              if (ch == '\n') {
-                rowCount++;
-                columnCount = chIndx;
-              }
+            } else if (ch == '\n') {
+              rowCount++;
+              columnCount = chIndx;
             }
           }
           if (openString) {
@@ -244,11 +246,9 @@ public class PHPParser extends PHPKeywords {
             } else if (ch == '\'') {
               openString = false;
               break;
-            } else {
-              if (ch == '\n') {
-                rowCount++;
-                columnCount = chIndx;
-              }
+            } else if (ch == '\n') {
+              rowCount++;
+              columnCount = chIndx;
             }
           }
           if (openString) {
@@ -393,7 +393,7 @@ public class PHPParser extends PHPKeywords {
 
             break;
           case '=' :
-            token = TT_SET;
+            token = TT_ASSIGN;
 
             if (str.length() > chIndx) {
               ch = str.charAt(chIndx);
@@ -652,8 +652,9 @@ public class PHPParser extends PHPKeywords {
     this.rowCount = rowCount;
     this.columnCount = 0;
     getNextToken();
-
-    statementList();
+    if (token != TT_EOF) {
+      statementList();
+    }
     if (token != TT_EOF) {
       if (token == TT_ARGCLOSE) {
         throwSyntaxError("too many closing ')'; end-of-file not reached");
@@ -724,7 +725,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+          }
         }
         return;
       } else if (token == TT_require || token == TT_require_once) {
@@ -734,7 +737,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+          }
         }
         return;
       } else if (token == TT_if) {
@@ -822,6 +827,45 @@ public class PHPParser extends PHPKeywords {
         }
         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 (token != TT_EOF) {
+            throwSyntaxError("';' expected after do-while statement.");
+          }
+        }
+        return;
       } else if (token == TT_foreach) {
         getNextToken();
         if (token == TT_ARGOPEN) {
@@ -856,7 +900,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
+          }
         }
         return;
 
@@ -866,7 +912,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'echo' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'echo' statement.");
+          }
         }
         return;
 
@@ -876,7 +924,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'print' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'print' statement.");
+          }
         }
         return;
 
@@ -886,7 +936,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'global' or 'static' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'global' or 'static' statement.");
+          }
         }
         return;
 
@@ -906,7 +958,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'unset' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'unset' statement.");
+          }
         }
         return;
 
@@ -918,7 +972,9 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'exit' or 'die' statement.");
+          }
         }
         return;
 
@@ -944,19 +1000,26 @@ public class PHPParser extends PHPKeywords {
         if (token == TT_SEMICOLON) {
           getNextToken();
         } else {
-          throwSyntaxError("';' expected after 'define' statement.");
+          if (token != TT_EOF) {
+            throwSyntaxError("';' expected after 'define' statement.");
+          }
         }
         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) {
-      // compundStatement
+      // compoundStatement
       getNextToken();
       if (token != TT_LISTCLOSE) {
         statementList();
@@ -975,12 +1038,92 @@ public class PHPParser extends PHPKeywords {
         getNextToken();
         return;
       } else {
-        throwSyntaxError("';' expected after expression.");
+        if (token != TT_EOF) {
+          throwSyntaxError("';' expected after expression.");
+        }
       }
     }
 
   }
 
+  public void classDeclarator() {
+    //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'.");
+    }
+  }
+
+  public void classBody() {
+    //'{' [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.");
+    }
+  }
+
+  public void classElementList() {
+    do {
+      classElement();
+    } while (token != TT_function || token != TT_var);
+  }
+
+  public void classElement() {
+    //class-property
+    //function-definition
+    if (token == TT_function) {
+      getNextToken();
+      functionDefinition();
+    } else if (token == TT_var) {
+      getNextToken();
+      classProperty();
+    } else {
+      throwSyntaxError("'function' or 'var' expected.");
+    }
+  }
+
+  public void classProperty() {
+    //'var' variable ';'
+    //'var' variable '=' constant ';'
+    if (token == TT_VARIABLE) {
+      getNextToken();
+      if (token == TT_ASSIGN) {
+        getNextToken();
+        constant();
+        if (token == TT_SEMICOLON) {
+          getNextToken();
+        } else {
+          throwSyntaxError("';' expected after variable declaration.");
+        }
+      } else if (token == TT_SEMICOLON) {
+        getNextToken();
+      } else {
+        throwSyntaxError("';' or '=' expected after variable declaration.");
+      }
+    } else {
+      throwSyntaxError("Variable expected after keyword 'var'.");
+    }
+  }
+
   public void functionDefinition() {
     functionDeclarator();
     compoundStatement();
@@ -1024,7 +1167,7 @@ public class PHPParser extends PHPKeywords {
     //variable '=' constant
     if (token == TT_VARIABLE) {
       getNextToken();
-      if (token == TT_SET) {
+      if (token == TT_ASSIGN) {
         getNextToken();
         constant();
       }
@@ -1335,6 +1478,19 @@ public class PHPParser extends PHPKeywords {
     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;
@@ -1456,12 +1612,31 @@ public class PHPParser extends PHPKeywords {
           getNextToken();
           break;
         case TT_REF : // ->
+          getNextToken();
           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();
+              if (token == TT_ARGOPEN) {
+                getNextToken();
+                expressionList();
+                if (token != TT_ARGCLOSE) {
+                  throwSyntaxError(") expected after identifier '" + ident + "'.");
+                }
+                getNextToken();
+              }
               break;
             case TT_LISTOPEN :
               getNextToken();
@@ -1474,6 +1649,7 @@ public class PHPParser extends PHPKeywords {
             default :
               throwSyntaxError("Syntax error after '->' token.");
           }
+          break;
         case TT_INCREMENT :
           getNextToken();
           break;
@@ -1559,7 +1735,7 @@ public class PHPParser extends PHPKeywords {
 
   public void assignExpression() {
     castExpression();
-    if (token == TT_SET) { // =
+    if (token == TT_ASSIGN) { // =
       getNextToken();
       logicalinclusiveorExpression();
     } else if (token == TT_DOTASSIGN) { // .=
@@ -1568,6 +1744,18 @@ public class PHPParser extends PHPKeywords {
     } 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();
     }
   }
 
@@ -1754,6 +1942,15 @@ public class PHPParser extends PHPKeywords {
 
   public void constant() {
     switch (token) {
+      case TT_null :
+        getNextToken();
+        break;
+      case TT_false :
+        getNextToken();
+        break;
+      case TT_true :
+        getNextToken();
+        break;
       case TT_STRING_CONSTANT :
         getNextToken();
         break;
index 3336763..97d996e 100644 (file)
@@ -117,7 +117,7 @@ public class PHPCodeScanner extends RuleBasedScanner {
                rules.add(new EndOfLineRule("#", comment));
 
                // Add rule for strings and character constants.
-               rules.add(new SingleLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
+               rules.add(new MultiLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
                rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
 
                // rules.add(new SingleLineRule("//", "//", php_comment));
index 8e86fb0..8e6409b 100644 (file)
@@ -51,9 +51,8 @@ public class PHPKeywords {
     //  "empty",
     //  "array",
     //   "isset",
-    "echo", "var", "as", "print", 
-    "unset", "exit", "die", "and", "or", "xor",
-    "list" };
+    "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", };
@@ -89,8 +88,8 @@ public class PHPKeywords {
   public final static int TT_foreach = 1028;
   public final static int TT_endforeach = 1029;
   public final static int TT_extends = 1030;
- // public final static int TT_empty = 1031;
- // public final static int TT_array = 1032;
+  // public final static int TT_empty = 1031;
+  // public final static int TT_array = 1032;
   public final static int TT_echo = 1033;
   public final static int TT_var = 1034;
   public final static int TT_as = 1035;
@@ -102,6 +101,9 @@ public class PHPKeywords {
   public final static int TT_or = 1041;
   public final static int TT_xor = 1042;
   public final static int TT_list = 1043;
+  public final static int TT_null = 1044;
+  public final static int TT_false = 1045;
+  public final static int TT_true = 1046;
 
   public final static int[] PHP_KEYWORD_TOKEN =
     {
@@ -135,9 +137,9 @@ public class PHPKeywords {
       TT_foreach,
       TT_endforeach,
       TT_extends,
-     // TT_empty,
+    // TT_empty,
     //  TT_array,
     //   TT_isset,
-    TT_echo, TT_var, TT_as, TT_print, TT_unset, TT_exit, 
-    TT_die, TT_and, TT_or, TT_xor, TT_list };
+    TT_echo, TT_var, TT_as, TT_print, TT_unset, TT_exit, TT_die, TT_and, TT_or, TT_xor, TT_list, 
+    TT_null, TT_false, TT_true };
 }