X-Git-Url: http://secure.phpeclipse.com 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 e2f1dce..5848e7d 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPParser.java @@ -42,10 +42,11 @@ public class PHPParser extends PHPKeywords { final static int TT_EOF = 0; final static int TT_UNDEFINED = 1; + final static int TT_MOD = 30; final static int TT_NOT = 31; final static int TT_DOT = 32; final static int TT_POW = 33; - final static int TT_DIVIDE = 34; + final static int TT_DIV = 34; final static int TT_MULTIPLY = 35; final static int TT_SUBTRACT = 36; final static int TT_ADD = 37; @@ -62,8 +63,12 @@ public class PHPParser extends PHPKeywords { final static int TT_DOTASSIGN = 48; final static int TT_SET = 49; - + final static int TT_REF = 50; final static int TT_FOREACH = 51; + final static int TT_AMPERSAND = 52; + final static int TT_DOLLARLISTOPEN = 53; + final static int TT_TILDE = 54; + final static int TT_ARGOPEN = 128; final static int TT_ARGCLOSE = 129; final static int TT_LISTOPEN = 130; @@ -71,7 +76,7 @@ public class PHPParser extends PHPKeywords { final static int TT_PARTOPEN = 132; final static int TT_PARTCLOSE = 133; final static int TT_COMMA = 134; - final static int TT_PERCENT = 135; + final static int TT_STRING = 136; final static int TT_IDENTIFIER = 138; final static int TT_DIGIT = 139; @@ -89,6 +94,12 @@ public class PHPParser extends PHPKeywords { final static int TT_DOUBLE_NUMBER = 152; final static int TT_INTERPOLATED_STRING = 153; final static int TT_STRING_CONSTANT = 154; + + final static int TT_LSHIFT = 155; + final static int TT_RSHIFT = 156; + final static int TT_EX_EQUAL = 157; + final static int TT_EX_UNEQUAL = 158; + final static int TT_LINE = 159; // final static int TT_AT = 153; // @ /** * Class Constructor. @@ -97,17 +108,17 @@ public class PHPParser extends PHPKeywords { *@param sess Description of Parameter *@see */ - public PHPParser(String s, int rowCount) { + public PHPParser() { 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.str = s; + this.str = ""; this.token = TT_EOF; this.chIndx = 0; - this.rowCount = rowCount; + this.rowCount = 1; this.columnCount = 0; getNextToken(); @@ -127,7 +138,7 @@ public class PHPParser extends PHPKeywords { break; } } - throw new SyntaxError(rowCount, chIndx - columnCount, str.substring(columnCount + 1, eol), error); + throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error); } /** @@ -182,9 +193,7 @@ public class PHPParser extends PHPKeywords { chIndx++; // multi line comment: while (str.length() > chIndx) { - if (str.charAt(chIndx) == '*' && - (str.length() > (chIndx+1) ) && - str.charAt(chIndx+1) == '/') { + if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') { chIndx += 2; break; } @@ -201,40 +210,49 @@ public class PHPParser extends PHPKeywords { continue; } else if (ch == '"') { // read string until end - while ((str.length() > chIndx) && (str.charAt(chIndx++) != '"')) { - if (str.charAt(chIndx) == '\\') { + boolean openString = true; + while (str.length() > chIndx) { + ch = str.charAt(chIndx++); + if (ch == '\\') { if (str.length() > chIndx) { - chIndx++; - } - if (str.length() > chIndx) { - chIndx++; + ch = str.charAt(chIndx++); } + } else if (ch == '"') { + openString = false; + break; } else { - if (str.charAt(chIndx) == '\n') { + if (ch == '\n') { rowCount++; columnCount = chIndx; } } } - if (str.length() > chIndx) { - chIndx++; + if (openString) { + throwSyntaxError("Open string character '\"' at end of file."); } token = TT_INTERPOLATED_STRING; return; } else if (ch == '\'') { // read string until end - while ((str.length() > chIndx) && (str.charAt(chIndx++) != '\'')) { - if (str.charAt(chIndx) == '\\') { + boolean openString = true; + while (str.length() > chIndx) { + ch = str.charAt(chIndx++); + if (ch == '\\') { if (str.length() > chIndx) { - chIndx++; + ch = str.charAt(chIndx++); } - if (str.length() > chIndx) { - chIndx++; + } else if (ch == '\'') { + openString = false; + break; + } else { + if (ch == '\n') { + rowCount++; + columnCount = chIndx; } } } - if (str.length() > chIndx) { - chIndx++; + if (openString) { + throwSyntaxError("Open string character \"'\" at end of file."); } token = TT_STRING_CONSTANT; return; @@ -270,7 +288,10 @@ public class PHPParser extends PHPKeywords { token = TT_COMMA; break; + case '~' : + token = TT_TILDE; + break; case '.' : token = TT_DOT; if (str.length() > chIndx) { @@ -288,7 +309,7 @@ public class PHPParser extends PHPKeywords { break; case '%' : - token = TT_PERCENT; + token = TT_MOD; break; case ';' : @@ -300,7 +321,7 @@ public class PHPParser extends PHPKeywords { break; case '/' : - token = TT_DIVIDE; + token = TT_DIV; if (str.length() > chIndx) { if (str.charAt(chIndx) == '=') { @@ -362,6 +383,12 @@ public class PHPParser extends PHPKeywords { break; } + if (str.charAt(chIndx) == '>') { + chIndx++; + token = TT_REF; + + break; + } } break; @@ -374,7 +401,14 @@ public class PHPParser extends PHPKeywords { if (ch == '=') { chIndx++; token = TT_EQUAL; + if (str.length() > chIndx) { + ch = str.charAt(chIndx); + if (ch == '=') { + chIndx++; + token = TT_EX_EQUAL; + } + } break; } if (ch == '>') { @@ -393,7 +427,14 @@ public class PHPParser extends PHPKeywords { if (str.charAt(chIndx) == '=') { chIndx++; token = TT_UNEQUAL; + if (str.length() > chIndx) { + ch = str.charAt(chIndx); + if (ch == '=') { + chIndx++; + token = TT_EX_UNEQUAL; + } + } break; } } @@ -409,6 +450,12 @@ public class PHPParser extends PHPKeywords { break; } + if (str.charAt(chIndx) == '>') { + chIndx++; + token = TT_RSHIFT; + + break; + } } break; @@ -422,13 +469,22 @@ public class PHPParser extends PHPKeywords { break; } + if (str.charAt(chIndx) == '<') { + chIndx++; + token = TT_LSHIFT; + + break; + } } break; case '|' : + token = TT_LINE; + if (str.length() > chIndx) { - if (str.charAt(chIndx++) == '|') { + if (str.charAt(chIndx) == '|') { + chIndx++; token = TT_OR; break; @@ -438,10 +494,15 @@ public class PHPParser extends PHPKeywords { break; case '&' : if (str.length() > chIndx) { - if (str.charAt(chIndx++) == '&') { + if (str.charAt(chIndx) == '&') { + chIndx++; token = TT_AND; break; + } else { + token = TT_AMPERSAND; + + break; } } @@ -477,7 +538,6 @@ public class PHPParser extends PHPKeywords { void getIdentifier() { StringBuffer ident = new StringBuffer(); - ident.append(ch); ident.append(ch); if (ch == '$') { @@ -486,13 +546,14 @@ public class PHPParser extends PHPKeywords { token = TT_IDENTIFIER; } getChar(); - while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch >= '_')) { + while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_')) { ident.append(ch); getChar(); } identifier = ident.toString(); + chIndx--; - Integer i = (Integer) keywordMap.get(identifier); + Integer i = (Integer) keywordMap.get(identifier.toLowerCase()); if (i != null) { token = i.intValue(); } @@ -565,8 +626,7 @@ public class PHPParser extends PHPKeywords { } } } - - // token = TT_INT_NUMBER; + chIndx--; try { if (dFlag != ' ') { @@ -584,7 +644,15 @@ public class PHPParser extends PHPKeywords { } } - public void start() throws SyntaxError { + public void start(String s, int rowCount) throws SyntaxError { + // start up + this.str = s; + this.token = TT_EOF; + this.chIndx = 0; + this.rowCount = rowCount; + this.columnCount = 0; + getNextToken(); + statementList(); if (token != TT_EOF) { if (token == TT_ARGCLOSE) { @@ -597,334 +665,632 @@ public class PHPParser extends PHPKeywords { throwSyntaxError("too many closing ']'; end-of-file not reached"); } + if (token == TT_ARGOPEN) { + throwSyntaxError("read character '('; end-of-file not reached"); + } + if (token == TT_LISTOPEN) { + throwSyntaxError("read character '{'; end-of-file not reached"); + } + if (token == TT_PARTOPEN) { + throwSyntaxError("read character '['; end-of-file not reached"); + } + throwSyntaxError("end-of-file not reached"); } } public void statementList() { - statement(); + do { + statement(); + if ((token == TT_LISTCLOSE) + || (token == TT_case) + || (token == TT_default) + || (token == TT_elseif) + || (token == TT_endif) + || (token == TT_endfor) + || (token == TT_endforeach) + || (token == TT_endwhile) + || (token == TT_endswitch) + || (token == TT_EOF)) { + return; + } + } while (true); + } + + public void compoundStatement() { + // '{' [statement-list] '}' + if (token == TT_LISTOPEN) { + getNextToken(); + } else { + throwSyntaxError("'{' expected in compound-statement."); + } + if (token != TT_LISTCLOSE) { + statementList(); + } + if (token == TT_LISTCLOSE) { + getNextToken(); + } else { + throwSyntaxError("'}' expected in compound-statement."); + } } public void statement() { - while (token != TT_UNDEFINED) { - if (token > TT_KEYWORD) { - if (token == TT_case) { + if (token > TT_KEYWORD && token != TT_list) { + String keyword = identifier; + if (token == TT_include || token == TT_include_once) { + getNextToken(); + expression(); + if (token == TT_SEMICOLON) { getNextToken(); - constant(); - if (token == TT_DDOT) { - getNextToken(); - statement(); - } else { - throwSyntaxError("':' character after 'case' constant expected."); - } - return; - } else if (token == TT_default) { + } else { + throwSyntaxError("';' character after 'include' or 'include_once' expected."); + } + return; + } else if (token == TT_require || token == TT_require_once) { + getNextToken(); + //constant(); + expression(); + if (token == TT_SEMICOLON) { getNextToken(); - if (token == TT_DDOT) { - getNextToken(); - statement(); - } else { - throwSyntaxError("':' character after 'default' expected."); - } - return; - } else if (token == TT_include || token == TT_include_once) { + } else { + throwSyntaxError("';' character after 'require' or 'require_once' expected."); + } + return; + } else if (token == TT_if) { + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'if' keyword."); + } + expression(); + if (token == TT_ARGCLOSE) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'if' condition."); + } + ifStatement(); + return; + + } else if (token == TT_switch) { + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'switch' keyword."); + } + expression(); + if (token == TT_ARGCLOSE) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'switch' condition."); + } + switchStatement(); + return; + } else if (token == TT_for) { + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'for' keyword."); + } + if (token == TT_SEMICOLON) { getNextToken(); + } else { expression(); if (token == TT_SEMICOLON) { getNextToken(); } else { - throwSyntaxError("';' character after 'include' or 'include_once' expected."); + throwSyntaxError("';' character after 'for' expected."); } - return; - } else if (token == TT_require || token == TT_require_once) { + } + if (token == TT_SEMICOLON) { getNextToken(); - constant(); + } else { + expression(); if (token == TT_SEMICOLON) { getNextToken(); } else { - throwSyntaxError("';' character after 'require' or 'require_once' expected."); + throwSyntaxError("';' character after 'for' expected."); } - return; - } else if (token == TT_if) { + } + if (token == TT_ARGCLOSE) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'if' keyword."); - } + } else { expression(); if (token == TT_ARGCLOSE) { getNextToken(); } else { - throwSyntaxError("')' expected after 'if' condition."); + throwSyntaxError("')' expected after 'for' condition."); } - ifStatement(); - return; - - } else if (token == TT_switch) { + } + forStatement(); + return; + } else if (token == TT_while) { + getNextToken(); + if (token == TT_ARGOPEN) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'switch' keyword."); - } - expression(); - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'switch' condition."); - } - switchStatement(); - return; - } else if (token == TT_for) { + } else { + throwSyntaxError("'(' expected after 'while' keyword."); + } + expression(); + if (token == TT_ARGCLOSE) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'for' keyword."); - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - expression(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' character after 'for' expected."); - } - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - expression(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' character after 'for' expected."); - } - } - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - expression(); - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'for' condition."); - } - } - forStatement(); - return; - } else if (token == TT_while) { + } else { + throwSyntaxError("')' expected after 'while' condition."); + } + whileStatement(); + return; + } else if (token == TT_foreach) { + getNextToken(); + if (token == TT_ARGOPEN) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'while' keyword."); - } - expression(); - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'while' condition."); - } - whileStatement(); - return; - } else if (token == TT_foreach) { + } else { + throwSyntaxError("'(' expected after 'foreach' keyword."); + } + expression(); + if (token == TT_as) { + getNextToken(); + } else { + throwSyntaxError("'as' expected after 'foreach' exxpression."); + } + variable(); + if (token == TT_FOREACH) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'foreach' keyword."); - } - expression(); - if (token == TT_as) { - getNextToken(); - } else { - throwSyntaxError("'as' expected after 'foreach' exxpression."); - } variable(); - if (token == TT_FOREACH) { - getNextToken(); - variable(); - } - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'foreach' expression."); - } - foreachStatement(); - return; - - } else if (token == TT_continue || token == TT_break || token == TT_return) { + } + if (token == TT_ARGCLOSE) { getNextToken(); - if (token != TT_SEMICOLON) { - expression(); - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'continue', 'break' or 'return'."); - } - return; + } else { + throwSyntaxError("')' expected after 'foreach' expression."); + } + foreachStatement(); + return; - } else if (token == TT_echo) { + } else if (token == TT_continue || token == TT_break || token == TT_return) { + getNextToken(); + if (token != TT_SEMICOLON) { + expression(); + } + if (token == TT_SEMICOLON) { getNextToken(); - expressionList(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'echo' statement."); - } - return; + } else { + throwSyntaxError("';' expected after 'continue', 'break' or 'return'."); + } + return; - } else if (token == TT_print) { + } else if (token == TT_echo) { + getNextToken(); + expressionList(); + if (token == TT_SEMICOLON) { getNextToken(); - expression(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'print' statement."); - } - return; + } else { + throwSyntaxError("';' expected after 'echo' statement."); + } + return; - } else if (token == TT_global || token == TT_static) { + } else if (token == TT_print) { + getNextToken(); + expression(); + if (token == TT_SEMICOLON) { getNextToken(); - variableList(); - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'global' or 'static' statement."); - } - return; + } else { + throwSyntaxError("';' expected after 'print' statement."); + } + return; - } else if (token == TT_unset) { + } else if (token == TT_global || token == TT_static) { + getNextToken(); + variableList(); + if (token == TT_SEMICOLON) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'unset' keyword."); - } - variableList(); - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'unset' statement."); - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'unset' statement."); - } - return; + } else { + throwSyntaxError("';' expected after 'global' or 'static' statement."); + } + return; - } else if (token == TT_exit || token == TT_die) { + } else if (token == TT_unset) { + getNextToken(); + if (token == TT_ARGOPEN) { getNextToken(); - if (token != TT_SEMICOLON) { - exitStatus(); - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'exit' or 'die' statement."); - } - return; - - } else if (token == TT_define) { + } else { + throwSyntaxError("'(' expected after 'unset' keyword."); + } + variableList(); + if (token == TT_ARGCLOSE) { getNextToken(); - if (token == TT_ARGOPEN) { - getNextToken(); - } else { - throwSyntaxError("'(' expected after 'define' keyword."); - } - constant(); - if (token == TT_COMMA) { - getNextToken(); - } else { - throwSyntaxError("',' expected after first 'define' constant."); - } - constant(); - if (token == TT_ARGCLOSE) { - getNextToken(); - } else { - throwSyntaxError("')' expected after 'define' statement."); - } - if (token == TT_SEMICOLON) { - getNextToken(); - } else { - throwSyntaxError("';' expected after 'define' statement."); - } - return; + } else { + throwSyntaxError("')' expected after 'unset' statement."); + } + if (token == TT_SEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'unset' statement."); + } + return; + } else if (token == TT_exit || token == TT_die) { + getNextToken(); + if (token != TT_SEMICOLON) { + exitStatus(); } + if (token == TT_SEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'exit' or 'die' statement."); + } + return; - } else { - if (token == TT_LISTOPEN) { + } else if (token == TT_define) { + getNextToken(); + if (token == TT_ARGOPEN) { getNextToken(); - statementList(); - if (token == TT_LISTCLOSE) { - getNextToken(); - } else { - throwSyntaxError("'}' expected."); - } + } else { + throwSyntaxError("'(' expected after 'define' keyword."); + } + constant(); + if (token == TT_COMMA) { + getNextToken(); + } else { + throwSyntaxError("',' expected after first 'define' constant."); } + constant(); + if (token == TT_ARGCLOSE) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'define' statement."); + } + if (token == TT_SEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'define' statement."); + } + return; + } else if (token == TT_function) { + getNextToken(); + functionDefinition(); + return; + } else { + throwSyntaxError("Unexpected keyword '" + keyword + "'"); + } + + } else if (token == TT_LISTOPEN) { + // compundStatement + getNextToken(); + if (token != TT_LISTCLOSE) { + statementList(); + } + if (token == TT_LISTCLOSE) { + getNextToken(); + return; + } else { + throwSyntaxError("'}' expected."); + } + } else { + if (token != TT_SEMICOLON) { + expression(); } - expression(); if (token == TT_SEMICOLON) { getNextToken(); + return; } else { throwSyntaxError("';' expected after expression."); } } - } - public void labeledStatement() { } - public void expressionStatement() { + public void functionDefinition() { + functionDeclarator(); + compoundStatement(); } - public void inclusionStatement() { + public void functionDeclarator() { + //identifier '(' [parameter-list] ')' + if (token == TT_IDENTIFIER) { + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected in function declaration."); + } + if (token != TT_ARGCLOSE) { + parameterList(); + } + if (token != TT_ARGCLOSE) { + throwSyntaxError("')' expected in function declaration."); + } else { + getNextToken(); + } + } } - - public void compoundStatement() { + // + public void parameterList() { + //parameter-declaration + //parameter-list ',' parameter-declaration + do { + parameterDeclaration(); + if (token != TT_COMMA) { + break; + } + getNextToken(); + } while (true); } - public void selectionStatement() { + public void parameterDeclaration() { + //variable + //variable-reference + //variable '=' constant + if (token == TT_VARIABLE) { + getNextToken(); + if (token == TT_SET) { + getNextToken(); + constant(); + } + return; + } } - public void iterationStatement() { + public void labeledStatementList() { + if (token != TT_case && token != TT_default) { + throwSyntaxError("'case' or 'default' expected."); + } + do { + if (token == TT_case) { + getNextToken(); + constant(); + if (token == TT_DDOT) { + getNextToken(); + statementList(); + } else { + throwSyntaxError("':' character after 'case' constant expected."); + } + } else { // TT_default + getNextToken(); + if (token == TT_DDOT) { + getNextToken(); + statementList(); + } else { + throwSyntaxError("':' character after 'default' expected."); + } + } + } while (token == TT_case || token == TT_default); } - public void jumpStatement() { - } + // public void labeledStatement() { + // if (token == TT_case) { + // getNextToken(); + // constant(); + // if (token == TT_DDOT) { + // getNextToken(); + // statement(); + // } else { + // throwSyntaxError("':' character after 'case' constant expected."); + // } + // return; + // } else if (token == TT_default) { + // getNextToken(); + // if (token == TT_DDOT) { + // getNextToken(); + // statement(); + // } else { + // throwSyntaxError("':' character after 'default' expected."); + // } + // return; + // } + // } - public void outputStatement() { + public void expressionStatement() { } - public void scopeStatement() { + public void inclusionStatement() { } - public void flowStatement() { - } + // public void compoundStatement() { + // } + + // public void selectionStatement() { + // } + // + // public void iterationStatement() { + // } + // + // public void jumpStatement() { + // } + // + // public void outputStatement() { + // } + // + // public void scopeStatement() { + // } + // + // public void flowStatement() { + // } + // + // public void definitionStatement() { + // } + + public void ifStatement() { + // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';' + if (token == TT_DDOT) { + getNextToken(); + statementList(); + switch (token) { + case TT_else : + getNextToken(); + if (token == TT_DDOT) { + getNextToken(); + statementList(); + } else { + if (token == TT_if) { //'else if' + getNextToken(); + elseifStatementList(); + } else { + throwSyntaxError("':' expected after 'else'."); + } + } + break; + case TT_elseif : + getNextToken(); + elseifStatementList(); + break; + } - public void definitionStatement() { + if (token != TT_endif) { + throwSyntaxError("'endif' expected."); + } + getNextToken(); + if (token != TT_SEMICOLON) { + throwSyntaxError("';' expected after if-statement."); + } + getNextToken(); + } else { + // statement [else-statement] + statement(); + if (token == TT_elseif) { + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'elseif' keyword."); + } + expression(); + if (token == TT_ARGCLOSE) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'elseif' condition."); + } + ifStatement(); + } else if (token == TT_else) { + getNextToken(); + statement(); + } + } + } + public void elseifStatementList() { + do { + elseifStatement(); + switch (token) { + case TT_else : + getNextToken(); + if (token == TT_DDOT) { + getNextToken(); + statementList(); + return; + } else { + if (token == TT_if) { //'else if' + getNextToken(); + } else { + throwSyntaxError("':' expected after 'else'."); + } + } + break; + case TT_elseif : + getNextToken(); + break; + default : + return; + } + } while (true); } - public void ifStatement() { + public void elseifStatement() { + if (token == TT_ARGOPEN) { + getNextToken(); + expression(); + if (token != TT_ARGOPEN) { + throwSyntaxError("')' expected in else-if-statement."); + } + getNextToken(); + if (token != TT_DDOT) { + throwSyntaxError("':' expected in else-if-statement."); + } + getNextToken(); + statementList(); + } } public void switchStatement() { + if (token == TT_DDOT) { + // ':' [labeled-statement-list] 'endswitch' ';' + getNextToken(); + labeledStatementList(); + if (token != TT_endswitch) { + throwSyntaxError("'endswitch' expected."); + } + getNextToken(); + if (token != TT_SEMICOLON) { + throwSyntaxError("';' expected after switch-statement."); + } + getNextToken(); + } else { + // '{' [labeled-statement-list] '}' + if (token != TT_LISTOPEN) { + throwSyntaxError("'{' expected in switch statement."); + } + getNextToken(); + if (token != TT_LISTCLOSE) { + labeledStatementList(); + } + if (token != TT_LISTCLOSE) { + throwSyntaxError("'}' expected in switch statement."); + } + getNextToken(); + + } } public void forStatement() { + if (token == TT_DDOT) { + getNextToken(); + statementList(); + if (token != TT_endfor) { + throwSyntaxError("'endfor' expected."); + } + getNextToken(); + if (token != TT_SEMICOLON) { + throwSyntaxError("';' expected after for-statement."); + } + getNextToken(); + } else { + statement(); + } } public void whileStatement() { + // ':' statement-list 'endwhile' ';' + if (token == TT_DDOT) { + getNextToken(); + statementList(); + if (token != TT_endwhile) { + throwSyntaxError("'endwhile' expected."); + } + getNextToken(); + if (token != TT_SEMICOLON) { + throwSyntaxError("';' expected after while-statement."); + } + getNextToken(); + } else { + statement(); + } } public void foreachStatement() { + if (token == TT_DDOT) { + getNextToken(); + statementList(); + if (token != TT_endforeach) { + throwSyntaxError("'endforeach' expected."); + } + getNextToken(); + if (token != TT_SEMICOLON) { + throwSyntaxError("';' expected after foreach-statement."); + } + getNextToken(); + } else { + statement(); + } } public void exitStatus() { @@ -955,20 +1321,418 @@ public class PHPParser extends PHPKeywords { } public void expression() { - if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) { + // if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) { + // getNextToken(); + // } else { + logicalinclusiveorExpression(); + // while (token != TT_SEMICOLON) { + // getNextToken(); + // // } + // } + } + + public void postfixExpression() { + String ident; + boolean castFlag = false; + switch (token) { + case TT_STRING_CONSTANT : + getNextToken(); + break; + case TT_INTERPOLATED_STRING : + getNextToken(); + break; + case TT_ARGOPEN : + getNextToken(); + if (token == TT_IDENTIFIER) { + // check if identifier is a type: + ident = identifier; + String str = identifier.toLowerCase(); + for (int i = 0; i < PHP_TYPES.length; i++) { + if (PHP_TYPES[i].equals(str)) { + castFlag = true; + break; + } + } + if (castFlag) { + getNextToken(); + if (token != TT_ARGCLOSE) { + throwSyntaxError(") expected after cast-type '" + ident + "'."); + } + getNextToken(); + expression(); + break; + } + } + if (!castFlag) { + expression(); + } + if (token != TT_ARGCLOSE) { + throwSyntaxError(") expected in postfix-expression."); + } + getNextToken(); + break; + case TT_DOUBLE_NUMBER : + getNextToken(); + break; + case TT_INT_NUMBER : + getNextToken(); + break; + case TT_VARIABLE : + ident = identifier; + getNextToken(); + if (token == TT_LISTOPEN) { + getNextToken(); + expression(); + if (token != TT_LISTCLOSE) { + throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression."); + } + getNextToken(); + } + break; + case TT_IDENTIFIER : + ident = identifier; + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + if (token != TT_ARGCLOSE) { + expressionList(); + if (token != TT_ARGCLOSE) { + throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression."); + } + } + getNextToken(); + } + break; + case TT_list : + getNextToken(); + if (token == TT_ARGOPEN) { + getNextToken(); + if (token == TT_COMMA) { + getNextToken(); + } + expressionList(); + if (token != TT_ARGCLOSE) { + throwSyntaxError("')' expected after 'list' keyword."); + } + getNextToken(); + // if (token == TT_SET) { + // getNextToken(); + // logicalinclusiveorExpression(); + // } + } else { + throwSyntaxError("'(' expected after 'list' keyword."); + } + break; + // case TT_array : + // getNextToken(); + // if (token == TT_ARGOPEN) { + // getNextToken(); + // if (token == TT_COMMA) { + // getNextToken(); + // } + // expressionList(); + // if (token != TT_ARGCLOSE) { + // throwSyntaxError("')' expected after 'list' keyword."); + // } + // getNextToken(); + // if (token == TT_SET) { + // getNextToken(); + // logicalinclusiveorExpression(); + // } + // } else { + // throwSyntaxError("'(' expected after 'list' keyword."); + // } + // break; + } + boolean while_flag = true; + do { + switch (token) { + case TT_PARTOPEN : + getNextToken(); + expression(); + if (token != TT_PARTCLOSE) { + throwSyntaxError("] expected in postfix-expression."); + } + getNextToken(); + break; + case TT_REF : // -> + switch (token) { + case TT_VARIABLE : + getNextToken(); + break; + case TT_IDENTIFIER : + getNextToken(); + break; + case TT_LISTOPEN : + getNextToken(); + expression(); + if (token != TT_LISTCLOSE) { + throwSyntaxError("} expected in postfix-expression."); + } + getNextToken(); + break; + default : + throwSyntaxError("Syntax error after '->' token."); + } + case TT_INCREMENT : + getNextToken(); + break; + case TT_DECREMENT : + getNextToken(); + break; + default : + while_flag = false; + } + } while (while_flag); + } + + public void unaryExpression() { + switch (token) { + case TT_INCREMENT : + getNextToken(); + unaryExpression(); + break; + case TT_DECREMENT : + getNextToken(); + unaryExpression(); + break; + //'&' '*' '+' '-' '~' '!' + case TT_AMPERSAND : + getNextToken(); + castExpression(); + break; + case TT_MULTIPLY : + getNextToken(); + castExpression(); + break; + case TT_ADD : + getNextToken(); + castExpression(); + break; + case TT_SUBTRACT : + getNextToken(); + castExpression(); + break; + case TT_TILDE : + getNextToken(); + castExpression(); + break; + case TT_NOT : + getNextToken(); + castExpression(); + break; + default : + postfixExpression(); + } + } + + public void castExpression() { + // if (token == TT_ARGOPEN) { + // getNextToken(); + // typeName(); + // if (token != TT_ARGCLOSE) { + // throwSyntaxError(") expected after cast-expression."); + // } + // getNextToken(); + // } + unaryExpression(); + } + + public void typeName() { + //'string' 'unset' 'array' 'object' + //'bool' 'boolean' + //'real' 'double' 'float' + //'int' 'integer' + String ident = ""; + if (token == TT_IDENTIFIER) { + ident = identifier; + String str = identifier.toLowerCase(); getNextToken(); - } else { - postfixExpression(); - // while (token != TT_SEMICOLON) { - // getNextToken(); - // } + for (int i = 0; i < PHP_TYPES.length; i++) { + if (PHP_TYPES[i].equals(str)) { + return; + } + } } + throwSyntaxError("Expected type cast '( )'; Got '" + ident + "'."); } - public void postfixExpression() { + public void assignExpression() { + castExpression(); + if (token == TT_SET) { // = + getNextToken(); + logicalinclusiveorExpression(); + } else if (token == TT_DOTASSIGN) { // .= + getNextToken(); + logicalinclusiveorExpression(); + } else if (token == TT_FOREACH) { // => + getNextToken(); + logicalinclusiveorExpression(); + } + } + + public void multiplicativeExpression() { + do { + assignExpression(); + if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) { + return; + } + getNextToken(); + } while (true); + } + + public void concatenationExpression() { + do { + multiplicativeExpression(); + if (token != TT_DOT) { + return; + } + getNextToken(); + } while (true); + } + public void additiveExpression() { + do { + concatenationExpression(); + if (token != TT_ADD && token != TT_SUBTRACT) { + return; + } + getNextToken(); + } while (true); } + public void shiftExpression() { + do { + additiveExpression(); + if (token != TT_LSHIFT && token != TT_RSHIFT) { + return; + } + getNextToken(); + } while (true); + } + + public void relationalExpression() { + do { + shiftExpression(); + if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) { + return; + } + getNextToken(); + } while (true); + } + + public void identicalExpression() { + do { + relationalExpression(); + if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) { + return; + } + getNextToken(); + } while (true); + } + + public void equalityExpression() { + do { + identicalExpression(); + if (token != TT_EQUAL && token != TT_UNEQUAL) { + return; + } + getNextToken(); + } while (true); + } + + public void andExpression() { + do { + equalityExpression(); + if (token != TT_AMPERSAND) { + return; + } + getNextToken(); + } while (true); + } + + public void exclusiveorExpression() { + do { + andExpression(); + if (token != TT_POW) { + return; + } + getNextToken(); + } while (true); + } + + public void inclusiveorExpression() { + do { + exclusiveorExpression(); + if (token != TT_LINE) { + return; + } + getNextToken(); + } while (true); + } + + public void booleanandExpression() { + do { + inclusiveorExpression(); + if (token != TT_AND) { + return; + } + getNextToken(); + } while (true); + } + + public void booleanorExpression() { + do { + booleanandExpression(); + if (token != TT_OR) { + return; + } + getNextToken(); + } while (true); + } + + public void logicalandExpression() { + do { + booleanorExpression(); + if (token != TT_and) { + return; + } + getNextToken(); + } while (true); + } + + public void logicalexclusiveorExpression() { + do { + logicalandExpression(); + if (token != TT_xor) { + return; + } + getNextToken(); + } while (true); + } + + public void logicalinclusiveorExpression() { + do { + logicalexclusiveorExpression(); + if (token != TT_or) { + return; + } + getNextToken(); + } while (true); + } + + // public void assignmentExpression() { + // if (token == TT_VARIABLE) { + // getNextToken(); + // if (token == TT_SET) { + // getNextToken(); + // logicalinclusiveorExpression(); + // } + // } else { + // logicalinclusiveorExpression(); + // } + // } + public void variableList() { do { variable(); @@ -989,6 +1753,22 @@ public class PHPParser extends PHPKeywords { } public void constant() { - + switch (token) { + case TT_STRING_CONSTANT : + getNextToken(); + break; + case TT_INTERPOLATED_STRING : + getNextToken(); + break; + case TT_DOUBLE_NUMBER : + getNextToken(); + break; + case TT_INT_NUMBER : + getNextToken(); + break; + default : + throwSyntaxError("Constant expected."); + } } + } \ No newline at end of file