From: khartlage Date: Sat, 23 Nov 2002 16:12:15 +0000 (+0000) Subject: improved php parser for keywords do-while, null, false, true... X-Git-Url: http://git.phpeclipse.com?hp=ae7216d92aba624dd375db3a2c5f2b121b0a9cf0 improved php parser for keywords do-while, null, false, true... --- diff --git a/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java b/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java index c0a677c..26589fc 100644 --- a/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java +++ b/net.sourceforge.phpeclipse/src/junit/sourceforge/phpeclipse/PHPParserTestCase.java @@ -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 { + ".\"
\"\n" + ".\"\"._NICKNAME.\":\"\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(\"
\", \"\\n\", $message); \n" + +"$message = str_replace(\"
\", \"\\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) { diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java index 5848e7d..3bbd368 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java @@ -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; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java index 3336763..97d996e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java @@ -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)); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java index 8e86fb0..8e6409b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPKeywords.java @@ -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 }; }