1 package net.sourceforge.phpeclipse.phpeditor;
3 import java.util.HashMap;
5 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
7 /**********************************************************************
8 Copyright (c) 2000, 2002 IBM Corp. and others.
9 All rights reserved. This program and the accompanying materials
10 are made available under the terms of the Common Public License v1.0
11 which accompanies this distribution, and is available at
12 http://www.eclipse.org/legal/cpl-v10.html
15 IBM Corporation - Initial implementation
16 Klaus Hartlage - www.eclipseproject.de
17 **********************************************************************/
19 public class PHPParser extends PHPKeywords {
21 private static HashMap keywordMap = null;
29 // row counter for syntax errors:
31 // column counter for syntax errors:
42 final static int TT_EOF = 0;
43 final static int TT_UNDEFINED = 1;
45 final static int TT_MOD = 30;
46 final static int TT_NOT = 31;
47 final static int TT_DOT = 32;
48 final static int TT_POW = 33;
49 final static int TT_DIV = 34;
50 final static int TT_MULTIPLY = 35;
51 final static int TT_SUBTRACT = 36;
52 final static int TT_ADD = 37;
53 final static int TT_EQUAL = 38;
54 final static int TT_UNEQUAL = 39;
55 final static int TT_GREATER = 40;
56 final static int TT_GREATEREQUAL = 41;
57 final static int TT_LESS = 42;
58 final static int TT_LESSEQUAL = 43;
59 final static int TT_AND = 44;
60 final static int TT_OR = 45;
61 final static int TT_HASH = 46;
62 final static int TT_DDOT = 47;
63 final static int TT_DOTASSIGN = 48;
65 final static int TT_ASSIGN = 49;
66 final static int TT_REF = 50;
67 final static int TT_FOREACH = 51;
68 final static int TT_AMPERSAND = 52;
69 final static int TT_DOLLARLISTOPEN = 53;
70 final static int TT_TILDE = 54;
72 final static int TT_ARGOPEN = 128;
73 final static int TT_ARGCLOSE = 129;
74 final static int TT_LISTOPEN = 130;
75 final static int TT_LISTCLOSE = 131;
76 final static int TT_PARTOPEN = 132;
77 final static int TT_PARTCLOSE = 133;
78 final static int TT_COMMA = 134;
80 final static int TT_STRING = 136;
81 final static int TT_IDENTIFIER = 138;
82 final static int TT_DIGIT = 139;
83 final static int TT_SEMICOLON = 140;
84 final static int TT_SLOT = 141;
85 final static int TT_SLOTSEQUENCE = 142;
86 final static int TT_DECREMENT = 144;
87 final static int TT_INCREMENT = 145;
88 final static int TT_ADDTO = 146;
89 final static int TT_DIVIDEBY = 147;
90 final static int TT_SUBTRACTFROM = 148;
91 final static int TT_TIMESBY = 149;
92 final static int TT_VARIABLE = 150;
93 final static int TT_INT_NUMBER = 151;
94 final static int TT_DOUBLE_NUMBER = 152;
95 final static int TT_INTERPOLATED_STRING = 153;
96 final static int TT_STRING_CONSTANT = 154;
98 final static int TT_LSHIFT = 155;
99 final static int TT_RSHIFT = 156;
100 final static int TT_EX_EQUAL = 157;
101 final static int TT_EX_UNEQUAL = 158;
102 final static int TT_LINE = 159;
103 // final static int TT_AT = 153; // @
108 *@param sess Description of Parameter
112 if (keywordMap == null) {
113 keywordMap = new HashMap();
114 for (int i = 0; i < PHP_KEYWORS.length; i++) {
115 keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
122 this.columnCount = 0;
127 private void throwSyntaxError(String error) {
129 if (str.length() < chIndx) {
132 // read until end-of-line
134 while (str.length() > eol) {
135 ch = str.charAt(eol++);
141 throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error);
145 * Method Declaration.
150 if (str.length() > chIndx) {
151 ch = str.charAt(chIndx++);
156 chIndx = str.length() + 1;
162 * gets the next token from input
164 void getNextToken() {
165 while (str.length() > chIndx) {
166 ch = str.charAt(chIndx++);
167 token = TT_UNDEFINED;
170 columnCount = chIndx;
171 continue; // while loop
174 if (!Character.isWhitespace(ch)) {
175 if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$') || (ch == '@')) {
179 if (ch >= '0' && ch <= '9') {
184 if (str.length() > chIndx) {
185 if (str.charAt(chIndx) == '/') {
187 // read comment until end of line:
188 while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
192 } else if (str.charAt(chIndx) == '*') {
194 // multi line comment:
195 while (str.length() > chIndx) {
196 if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') {
200 ch = str.charAt(chIndx++);
203 columnCount = chIndx;
209 } else if (ch == '#') {
210 // read comment until end of line:
211 while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
215 } else if (ch == '"') {
216 // read string until end
217 boolean openString = true;
218 while (str.length() > chIndx) {
219 ch = str.charAt(chIndx++);
221 if (str.length() > chIndx) {
222 ch = str.charAt(chIndx++);
224 } else if (ch == '"') {
227 } else if (ch == '\n') {
229 columnCount = chIndx;
233 throwSyntaxError("Open string character '\"' at end of file.");
235 token = TT_INTERPOLATED_STRING;
237 } else if (ch == '\'') {
238 // read string until end
239 boolean openString = true;
240 while (str.length() > chIndx) {
241 ch = str.charAt(chIndx++);
243 if (str.length() > chIndx) {
244 ch = str.charAt(chIndx++);
246 } else if (ch == '\'') {
249 } else if (ch == '\n') {
251 columnCount = chIndx;
255 throwSyntaxError("Open string character \"'\" at end of file.");
257 token = TT_STRING_CONSTANT;
276 token = TT_LISTCLOSE;
284 token = TT_PARTCLOSE;
297 if (str.length() > chIndx) {
298 if (str.charAt(chIndx) == '=') {
300 token = TT_DOTASSIGN;
316 token = TT_SEMICOLON;
326 if (str.length() > chIndx) {
327 if (str.charAt(chIndx) == '=') {
338 if (str.length() > chIndx) {
339 if (str.charAt(chIndx) == '*') {
345 if (str.charAt(chIndx) == '=') {
356 if (str.length() > chIndx) {
357 if (str.charAt(chIndx) == '+') {
359 token = TT_INCREMENT;
363 if (str.charAt(chIndx) == '=') {
373 if (str.length() > chIndx) {
374 if (str.charAt(chIndx) == '-') {
376 token = TT_DECREMENT;
380 if (str.charAt(chIndx) == '=') {
382 token = TT_SUBTRACTFROM;
386 if (str.charAt(chIndx) == '>') {
398 if (str.length() > chIndx) {
399 ch = str.charAt(chIndx);
404 if (str.length() > chIndx) {
405 ch = str.charAt(chIndx);
426 if (str.length() > chIndx) {
427 if (str.charAt(chIndx) == '=') {
430 if (str.length() > chIndx) {
431 ch = str.charAt(chIndx);
435 token = TT_EX_UNEQUAL;
446 if (str.length() > chIndx) {
447 if (str.charAt(chIndx) == '=') {
449 token = TT_GREATEREQUAL;
453 if (str.charAt(chIndx) == '>') {
465 if (str.length() > chIndx) {
466 if (str.charAt(chIndx) == '=') {
468 token = TT_LESSEQUAL;
472 if (str.charAt(chIndx) == '<') {
485 if (str.length() > chIndx) {
486 if (str.charAt(chIndx) == '|') {
496 if (str.length() > chIndx) {
497 if (str.charAt(chIndx) == '&') {
503 token = TT_AMPERSAND;
523 throwSyntaxError("unexpected character: '" + ch + "'");
526 if (token == TT_UNDEFINED) {
527 throwSyntaxError("token not found");
534 chIndx = str.length() + 1;
539 void getIdentifier() {
540 StringBuffer ident = new StringBuffer();
546 token = TT_IDENTIFIER;
549 while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
553 identifier = ident.toString();
556 Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
558 token = i.intValue();
563 StringBuffer inum = new StringBuffer();
572 // determine number conversions:
573 if (firstCh == '0') {
602 if (numFormat == 16) {
603 while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
608 while ((ch >= '0' && ch <= '9') || (ch == '.') || (ch == 'E') || (ch == 'e')) {
609 if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
610 if (ch == '.' && dFlag != ' ') {
613 if ((dFlag == 'E') || (dFlag == 'e')) {
619 if ((ch == '-') || (ch == '+')) {
633 doubleNumber = new Double(inum.toString());
634 token = TT_DOUBLE_NUMBER;
637 longNumber = Long.valueOf(inum.toString(), numFormat);
638 token = TT_INT_NUMBER;
642 } catch (Throwable e) {
643 throwSyntaxError("Number format error: " + inum.toString());
647 public void start(String s, int rowCount) throws SyntaxError {
652 this.rowCount = rowCount;
653 this.columnCount = 0;
655 if (token != TT_EOF) {
658 if (token != TT_EOF) {
659 if (token == TT_ARGCLOSE) {
660 throwSyntaxError("too many closing ')'; end-of-file not reached");
662 if (token == TT_LISTCLOSE) {
663 throwSyntaxError("too many closing '}'; end-of-file not reached");
665 if (token == TT_PARTCLOSE) {
666 throwSyntaxError("too many closing ']'; end-of-file not reached");
669 if (token == TT_ARGOPEN) {
670 throwSyntaxError("read character '('; end-of-file not reached");
672 if (token == TT_LISTOPEN) {
673 throwSyntaxError("read character '{'; end-of-file not reached");
675 if (token == TT_PARTOPEN) {
676 throwSyntaxError("read character '['; end-of-file not reached");
679 throwSyntaxError("end-of-file not reached");
684 public void statementList() {
687 if ((token == TT_LISTCLOSE)
688 || (token == TT_case)
689 || (token == TT_default)
690 || (token == TT_elseif)
691 || (token == TT_endif)
692 || (token == TT_endfor)
693 || (token == TT_endforeach)
694 || (token == TT_endwhile)
695 || (token == TT_endswitch)
696 || (token == TT_EOF)) {
702 public void compoundStatement() {
703 // '{' [statement-list] '}'
704 if (token == TT_LISTOPEN) {
707 throwSyntaxError("'{' expected in compound-statement.");
709 if (token != TT_LISTCLOSE) {
712 if (token == TT_LISTCLOSE) {
715 throwSyntaxError("'}' expected in compound-statement.");
719 public void statement() {
720 if (token > TT_KEYWORD && token != TT_list) {
721 String keyword = identifier;
722 if (token == TT_include || token == TT_include_once) {
725 if (token == TT_SEMICOLON) {
728 if (token != TT_EOF) {
729 throwSyntaxError("';' character after 'include' or 'include_once' expected.");
733 } else if (token == TT_require || token == TT_require_once) {
737 if (token == TT_SEMICOLON) {
740 if (token != TT_EOF) {
741 throwSyntaxError("';' character after 'require' or 'require_once' expected.");
745 } else if (token == TT_if) {
747 if (token == TT_ARGOPEN) {
750 throwSyntaxError("'(' expected after 'if' keyword.");
753 if (token == TT_ARGCLOSE) {
756 throwSyntaxError("')' expected after 'if' condition.");
761 } else if (token == TT_switch) {
763 if (token == TT_ARGOPEN) {
766 throwSyntaxError("'(' expected after 'switch' keyword.");
769 if (token == TT_ARGCLOSE) {
772 throwSyntaxError("')' expected after 'switch' condition.");
776 } else if (token == TT_for) {
778 if (token == TT_ARGOPEN) {
781 throwSyntaxError("'(' expected after 'for' keyword.");
783 if (token == TT_SEMICOLON) {
787 if (token == TT_SEMICOLON) {
790 throwSyntaxError("';' character after 'for' expected.");
793 if (token == TT_SEMICOLON) {
797 if (token == TT_SEMICOLON) {
800 throwSyntaxError("';' character after 'for' expected.");
803 if (token == TT_ARGCLOSE) {
807 if (token == TT_ARGCLOSE) {
810 throwSyntaxError("')' expected after 'for' condition.");
815 } else if (token == TT_while) {
817 if (token == TT_ARGOPEN) {
820 throwSyntaxError("'(' expected after 'while' keyword.");
823 if (token == TT_ARGCLOSE) {
826 throwSyntaxError("')' expected after 'while' condition.");
830 } else if (token == TT_do) {
832 if (token == TT_LISTOPEN) {
835 throwSyntaxError("'{' expected after 'do' keyword.");
837 if (token != TT_LISTCLOSE) {
840 if (token == TT_LISTCLOSE) {
843 throwSyntaxError("'}' expected after 'do' keyword.");
845 if (token == TT_while) {
847 if (token == TT_ARGOPEN) {
850 throwSyntaxError("'(' expected after 'while' keyword.");
853 if (token == TT_ARGCLOSE) {
856 throwSyntaxError("')' expected after 'while' condition.");
859 throwSyntaxError("'while' expected after 'do' keyword.");
861 if (token == TT_SEMICOLON) {
864 if (token != TT_EOF) {
865 throwSyntaxError("';' expected after do-while statement.");
869 } else if (token == TT_foreach) {
871 if (token == TT_ARGOPEN) {
874 throwSyntaxError("'(' expected after 'foreach' keyword.");
877 if (token == TT_as) {
880 throwSyntaxError("'as' expected after 'foreach' exxpression.");
883 if (token == TT_FOREACH) {
887 if (token == TT_ARGCLOSE) {
890 throwSyntaxError("')' expected after 'foreach' expression.");
895 } else if (token == TT_continue || token == TT_break || token == TT_return) {
897 if (token != TT_SEMICOLON) {
900 if (token == TT_SEMICOLON) {
903 if (token != TT_EOF) {
904 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
909 } else if (token == TT_echo) {
912 if (token == TT_SEMICOLON) {
915 if (token != TT_EOF) {
916 throwSyntaxError("';' expected after 'echo' statement.");
921 } else if (token == TT_print) {
924 if (token == TT_SEMICOLON) {
927 if (token != TT_EOF) {
928 throwSyntaxError("';' expected after 'print' statement.");
933 } else if (token == TT_global || token == TT_static) {
936 if (token == TT_SEMICOLON) {
939 if (token != TT_EOF) {
940 throwSyntaxError("';' expected after 'global' or 'static' statement.");
945 } else if (token == TT_unset) {
947 if (token == TT_ARGOPEN) {
950 throwSyntaxError("'(' expected after 'unset' keyword.");
953 if (token == TT_ARGCLOSE) {
956 throwSyntaxError("')' expected after 'unset' statement.");
958 if (token == TT_SEMICOLON) {
961 if (token != TT_EOF) {
962 throwSyntaxError("';' expected after 'unset' statement.");
967 } else if (token == TT_exit || token == TT_die) {
969 if (token != TT_SEMICOLON) {
972 if (token == TT_SEMICOLON) {
975 if (token != TT_EOF) {
976 throwSyntaxError("';' expected after 'exit' or 'die' statement.");
981 } else if (token == TT_define) {
983 if (token == TT_ARGOPEN) {
986 throwSyntaxError("'(' expected after 'define' keyword.");
989 if (token == TT_COMMA) {
992 throwSyntaxError("',' expected after first 'define' constant.");
995 if (token == TT_ARGCLOSE) {
998 throwSyntaxError("')' expected after 'define' statement.");
1000 if (token == TT_SEMICOLON) {
1003 if (token != TT_EOF) {
1004 throwSyntaxError("';' expected after 'define' statement.");
1008 } else if (token == TT_function) {
1010 functionDefinition();
1012 } else if (token == TT_class) {
1018 throwSyntaxError("Unexpected keyword '" + keyword + "'");
1021 } else if (token == TT_LISTOPEN) {
1022 // compoundStatement
1024 if (token != TT_LISTCLOSE) {
1027 if (token == TT_LISTCLOSE) {
1031 throwSyntaxError("'}' expected.");
1034 if (token != TT_SEMICOLON) {
1037 if (token == TT_SEMICOLON) {
1041 if (token != TT_EOF) {
1042 throwSyntaxError("';' expected after expression.");
1049 public void classDeclarator() {
1051 //identifier 'extends' identifier
1052 if (token == TT_IDENTIFIER) {
1054 if (token == TT_extends) {
1056 if (token == TT_IDENTIFIER) {
1059 throwSyntaxError("Class name expected after keyword 'extends'.");
1063 throwSyntaxError("Class name expected after keyword 'class'.");
1067 public void classBody() {
1068 //'{' [class-element-list] '}'
1069 if (token == TT_LISTOPEN) {
1071 if (token != TT_LISTCLOSE) {
1074 if (token == TT_LISTCLOSE) {
1077 throwSyntaxError("'}' expected at end of class body.");
1080 throwSyntaxError("'{' expected at start of class body.");
1084 public void classElementList() {
1087 } while (token != TT_function || token != TT_var);
1090 public void classElement() {
1092 //function-definition
1093 if (token == TT_function) {
1095 functionDefinition();
1096 } else if (token == TT_var) {
1100 throwSyntaxError("'function' or 'var' expected.");
1104 public void classProperty() {
1105 //'var' variable ';'
1106 //'var' variable '=' constant ';'
1107 if (token == TT_VARIABLE) {
1109 if (token == TT_ASSIGN) {
1112 if (token == TT_SEMICOLON) {
1115 throwSyntaxError("';' expected after variable declaration.");
1117 } else if (token == TT_SEMICOLON) {
1120 throwSyntaxError("';' or '=' expected after variable declaration.");
1123 throwSyntaxError("Variable expected after keyword 'var'.");
1127 public void functionDefinition() {
1128 functionDeclarator();
1129 compoundStatement();
1132 public void functionDeclarator() {
1133 //identifier '(' [parameter-list] ')'
1134 if (token == TT_IDENTIFIER) {
1136 if (token == TT_ARGOPEN) {
1139 throwSyntaxError("'(' expected in function declaration.");
1141 if (token != TT_ARGCLOSE) {
1144 if (token != TT_ARGCLOSE) {
1145 throwSyntaxError("')' expected in function declaration.");
1152 public void parameterList() {
1153 //parameter-declaration
1154 //parameter-list ',' parameter-declaration
1156 parameterDeclaration();
1157 if (token != TT_COMMA) {
1164 public void parameterDeclaration() {
1166 //variable-reference
1167 //variable '=' constant
1168 if (token == TT_VARIABLE) {
1170 if (token == TT_ASSIGN) {
1178 public void labeledStatementList() {
1179 if (token != TT_case && token != TT_default) {
1180 throwSyntaxError("'case' or 'default' expected.");
1183 if (token == TT_case) {
1186 if (token == TT_DDOT) {
1190 throwSyntaxError("':' character after 'case' constant expected.");
1192 } else { // TT_default
1194 if (token == TT_DDOT) {
1198 throwSyntaxError("':' character after 'default' expected.");
1201 } while (token == TT_case || token == TT_default);
1204 // public void labeledStatement() {
1205 // if (token == TT_case) {
1208 // if (token == TT_DDOT) {
1212 // throwSyntaxError("':' character after 'case' constant expected.");
1215 // } else if (token == TT_default) {
1217 // if (token == TT_DDOT) {
1221 // throwSyntaxError("':' character after 'default' expected.");
1227 public void expressionStatement() {
1230 public void inclusionStatement() {
1233 // public void compoundStatement() {
1236 // public void selectionStatement() {
1239 // public void iterationStatement() {
1242 // public void jumpStatement() {
1245 // public void outputStatement() {
1248 // public void scopeStatement() {
1251 // public void flowStatement() {
1254 // public void definitionStatement() {
1257 public void ifStatement() {
1258 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1259 if (token == TT_DDOT) {
1265 if (token == TT_DDOT) {
1269 if (token == TT_if) { //'else if'
1271 elseifStatementList();
1273 throwSyntaxError("':' expected after 'else'.");
1279 elseifStatementList();
1283 if (token != TT_endif) {
1284 throwSyntaxError("'endif' expected.");
1287 if (token != TT_SEMICOLON) {
1288 throwSyntaxError("';' expected after if-statement.");
1292 // statement [else-statement]
1294 if (token == TT_elseif) {
1296 if (token == TT_ARGOPEN) {
1299 throwSyntaxError("'(' expected after 'elseif' keyword.");
1302 if (token == TT_ARGCLOSE) {
1305 throwSyntaxError("')' expected after 'elseif' condition.");
1308 } else if (token == TT_else) {
1314 public void elseifStatementList() {
1320 if (token == TT_DDOT) {
1325 if (token == TT_if) { //'else if'
1328 throwSyntaxError("':' expected after 'else'.");
1341 public void elseifStatement() {
1342 if (token == TT_ARGOPEN) {
1345 if (token != TT_ARGOPEN) {
1346 throwSyntaxError("')' expected in else-if-statement.");
1349 if (token != TT_DDOT) {
1350 throwSyntaxError("':' expected in else-if-statement.");
1357 public void switchStatement() {
1358 if (token == TT_DDOT) {
1359 // ':' [labeled-statement-list] 'endswitch' ';'
1361 labeledStatementList();
1362 if (token != TT_endswitch) {
1363 throwSyntaxError("'endswitch' expected.");
1366 if (token != TT_SEMICOLON) {
1367 throwSyntaxError("';' expected after switch-statement.");
1371 // '{' [labeled-statement-list] '}'
1372 if (token != TT_LISTOPEN) {
1373 throwSyntaxError("'{' expected in switch statement.");
1376 if (token != TT_LISTCLOSE) {
1377 labeledStatementList();
1379 if (token != TT_LISTCLOSE) {
1380 throwSyntaxError("'}' expected in switch statement.");
1387 public void forStatement() {
1388 if (token == TT_DDOT) {
1391 if (token != TT_endfor) {
1392 throwSyntaxError("'endfor' expected.");
1395 if (token != TT_SEMICOLON) {
1396 throwSyntaxError("';' expected after for-statement.");
1404 public void whileStatement() {
1405 // ':' statement-list 'endwhile' ';'
1406 if (token == TT_DDOT) {
1409 if (token != TT_endwhile) {
1410 throwSyntaxError("'endwhile' expected.");
1413 if (token != TT_SEMICOLON) {
1414 throwSyntaxError("';' expected after while-statement.");
1422 public void foreachStatement() {
1423 if (token == TT_DDOT) {
1426 if (token != TT_endforeach) {
1427 throwSyntaxError("'endforeach' expected.");
1430 if (token != TT_SEMICOLON) {
1431 throwSyntaxError("';' expected after foreach-statement.");
1439 public void exitStatus() {
1440 if (token == TT_ARGOPEN) {
1443 throwSyntaxError("'(' expected in 'exit-status'.");
1445 if (token != TT_ARGCLOSE) {
1448 if (token == TT_ARGCLOSE) {
1451 throwSyntaxError("')' expected after 'exit-status'.");
1455 public void expressionList() {
1458 if (token == TT_COMMA) {
1466 public void expression() {
1467 // if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
1470 logicalinclusiveorExpression();
1471 // while (token != TT_SEMICOLON) {
1477 public void postfixExpression() {
1479 boolean castFlag = false;
1494 case TT_STRING_CONSTANT :
1497 case TT_INTERPOLATED_STRING :
1502 if (token == TT_IDENTIFIER) {
1503 // check if identifier is a type:
1505 String str = identifier.toLowerCase();
1506 for (int i = 0; i < PHP_TYPES.length; i++) {
1507 if (PHP_TYPES[i].equals(str)) {
1514 if (token != TT_ARGCLOSE) {
1515 throwSyntaxError(") expected after cast-type '" + ident + "'.");
1525 if (token != TT_ARGCLOSE) {
1526 throwSyntaxError(") expected in postfix-expression.");
1530 case TT_DOUBLE_NUMBER :
1533 case TT_INT_NUMBER :
1539 if (token == TT_LISTOPEN) {
1542 if (token != TT_LISTCLOSE) {
1543 throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
1548 case TT_IDENTIFIER :
1551 if (token == TT_ARGOPEN) {
1553 if (token != TT_ARGCLOSE) {
1555 if (token != TT_ARGCLOSE) {
1556 throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
1564 if (token == TT_ARGOPEN) {
1566 if (token == TT_COMMA) {
1570 if (token != TT_ARGCLOSE) {
1571 throwSyntaxError("')' expected after 'list' keyword.");
1574 // if (token == TT_SET) {
1576 // logicalinclusiveorExpression();
1579 throwSyntaxError("'(' expected after 'list' keyword.");
1584 // if (token == TT_ARGOPEN) {
1586 // if (token == TT_COMMA) {
1589 // expressionList();
1590 // if (token != TT_ARGCLOSE) {
1591 // throwSyntaxError("')' expected after 'list' keyword.");
1594 // if (token == TT_SET) {
1596 // logicalinclusiveorExpression();
1599 // throwSyntaxError("'(' expected after 'list' keyword.");
1603 boolean while_flag = true;
1609 if (token != TT_PARTCLOSE) {
1610 throwSyntaxError("] expected in postfix-expression.");
1620 // if (token == TT_ARGOPEN) {
1622 // expressionList();
1623 // if (token != TT_ARGCLOSE) {
1624 // throwSyntaxError(") expected after variable '" + ident + "'.");
1629 case TT_IDENTIFIER :
1632 if (token == TT_ARGOPEN) {
1635 if (token != TT_ARGCLOSE) {
1636 throwSyntaxError(") expected after identifier '" + ident + "'.");
1644 if (token != TT_LISTCLOSE) {
1645 throwSyntaxError("} expected in postfix-expression.");
1650 throwSyntaxError("Syntax error after '->' token.");
1662 } while (while_flag);
1665 public void unaryExpression() {
1675 //'&' '*' '+' '-' '~' '!'
1701 postfixExpression();
1705 public void castExpression() {
1706 // if (token == TT_ARGOPEN) {
1709 // if (token != TT_ARGCLOSE) {
1710 // throwSyntaxError(") expected after cast-expression.");
1717 public void typeName() {
1718 //'string' 'unset' 'array' 'object'
1720 //'real' 'double' 'float'
1723 if (token == TT_IDENTIFIER) {
1725 String str = identifier.toLowerCase();
1727 for (int i = 0; i < PHP_TYPES.length; i++) {
1728 if (PHP_TYPES[i].equals(str)) {
1733 throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
1736 public void assignExpression() {
1738 if (token == TT_ASSIGN) { // =
1740 logicalinclusiveorExpression();
1741 } else if (token == TT_DOTASSIGN) { // .=
1743 logicalinclusiveorExpression();
1744 } else if (token == TT_FOREACH) { // =>
1746 logicalinclusiveorExpression();
1747 } else if (token == TT_ADDTO) { // +=
1749 logicalinclusiveorExpression();
1750 } else if (token == TT_SUBTRACTFROM) { // -=
1752 logicalinclusiveorExpression();
1753 } else if (token == TT_TIMESBY) { // *=
1755 logicalinclusiveorExpression();
1756 } else if (token == TT_DIVIDEBY) { // *=
1758 logicalinclusiveorExpression();
1762 public void multiplicativeExpression() {
1765 if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
1772 public void concatenationExpression() {
1774 multiplicativeExpression();
1775 if (token != TT_DOT) {
1782 public void additiveExpression() {
1784 concatenationExpression();
1785 if (token != TT_ADD && token != TT_SUBTRACT) {
1792 public void shiftExpression() {
1794 additiveExpression();
1795 if (token != TT_LSHIFT && token != TT_RSHIFT) {
1802 public void relationalExpression() {
1805 if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
1812 public void identicalExpression() {
1814 relationalExpression();
1815 if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
1822 public void equalityExpression() {
1824 identicalExpression();
1825 if (token != TT_EQUAL && token != TT_UNEQUAL) {
1832 public void andExpression() {
1834 equalityExpression();
1835 if (token != TT_AMPERSAND) {
1842 public void exclusiveorExpression() {
1845 if (token != TT_POW) {
1852 public void inclusiveorExpression() {
1854 exclusiveorExpression();
1855 if (token != TT_LINE) {
1862 public void booleanandExpression() {
1864 inclusiveorExpression();
1865 if (token != TT_AND) {
1872 public void booleanorExpression() {
1874 booleanandExpression();
1875 if (token != TT_OR) {
1882 public void logicalandExpression() {
1884 booleanorExpression();
1885 if (token != TT_and) {
1892 public void logicalexclusiveorExpression() {
1894 logicalandExpression();
1895 if (token != TT_xor) {
1902 public void logicalinclusiveorExpression() {
1904 logicalexclusiveorExpression();
1905 if (token != TT_or) {
1912 // public void assignmentExpression() {
1913 // if (token == TT_VARIABLE) {
1915 // if (token == TT_SET) {
1917 // logicalinclusiveorExpression();
1920 // logicalinclusiveorExpression();
1924 public void variableList() {
1927 if (token == TT_COMMA) {
1935 public void variable() {
1936 if (token == TT_VARIABLE) {
1939 throwSyntaxError("$-variable expected in variable-list.");
1943 public void constant() {
1954 case TT_STRING_CONSTANT :
1957 case TT_INTERPOLATED_STRING :
1960 case TT_DOUBLE_NUMBER :
1963 case TT_INT_NUMBER :
1967 throwSyntaxError("Constant expected.");