1 package net.sourceforge.phpeclipse.phpeditor;
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.Hashtable;
7 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
8 import org.eclipse.core.resources.IFile;
9 import org.eclipse.core.resources.IMarker;
10 import org.eclipse.core.runtime.CoreException;
11 import org.eclipse.ui.texteditor.MarkerUtilities;
13 /**********************************************************************
14 Copyright (c) 2000, 2002 IBM Corp. and others.
15 All rights reserved. This program and the accompanying materials
16 are made available under the terms of the Common Public License v1.0
17 which accompanies this distribution, and is available at
18 http://www.eclipse.org/legal/cpl-v10.html
21 IBM Corporation - Initial implementation
22 Klaus Hartlage - www.eclipseproject.de
23 **********************************************************************/
25 public class PHPParser extends PHPKeywords {
27 public static final int ERROR = 2;
28 public static final int WARNING = 1;
29 public static final int INFO = 0;
30 private IFile fileToParse;
31 private ArrayList phpList;
33 private int currentPHPString;
34 private boolean phpEnd;
36 private static HashMap keywordMap = null;
44 // row counter for syntax errors:
46 // column counter for syntax errors:
57 final static int TT_EOF = 0;
58 final static int TT_UNDEFINED = 1;
60 final static int TT_MOD = 30;
61 final static int TT_NOT = 31;
62 final static int TT_DOT = 32;
63 final static int TT_POW = 33;
64 final static int TT_DIV = 34;
65 final static int TT_MULTIPLY = 35;
66 final static int TT_SUBTRACT = 36;
67 final static int TT_ADD = 37;
68 final static int TT_EQUAL = 38;
69 final static int TT_UNEQUAL = 39;
70 final static int TT_GREATER = 40;
71 final static int TT_GREATEREQUAL = 41;
72 final static int TT_LESS = 42;
73 final static int TT_LESSEQUAL = 43;
74 final static int TT_AND = 44;
75 final static int TT_OR = 45;
76 final static int TT_HASH = 46;
77 final static int TT_DDOT = 47;
78 final static int TT_DOTASSIGN = 48;
80 final static int TT_ASSIGN = 49;
81 final static int TT_REF = 50;
82 final static int TT_FOREACH = 51;
83 final static int TT_AMPERSAND = 52;
84 final static int TT_DOLLARLISTOPEN = 53;
85 final static int TT_TILDE = 54;
86 final static int TT_TILDEASSIGN = 55;
87 final static int TT_MODASSIGN = 56;
88 final static int TT_POWASSIGN = 57;
89 final static int TT_RSHIFTASSIGN = 58;
90 final static int TT_LSHIFTASSIGN = 59;
91 final static int TT_ANDASSIGN = 60;
92 final static int TT_QUESTIONMARK = 61;
94 final static int TT_ARGOPEN = 128;
95 final static int TT_ARGCLOSE = 129;
96 final static int TT_LISTOPEN = 130;
97 final static int TT_LISTCLOSE = 131;
98 final static int TT_PARTOPEN = 132;
99 final static int TT_PARTCLOSE = 133;
100 final static int TT_COMMA = 134;
102 final static int TT_STRING = 136;
103 final static int TT_IDENTIFIER = 138;
104 final static int TT_DIGIT = 139;
105 final static int TT_SEMICOLON = 140;
106 final static int TT_SLOT = 141;
107 final static int TT_SLOTSEQUENCE = 142;
108 final static int TT_DECREMENT = 144;
109 final static int TT_INCREMENT = 145;
110 final static int TT_ADDTO = 146;
111 final static int TT_DIVIDEBY = 147;
112 final static int TT_SUBTRACTFROM = 148;
113 final static int TT_TIMESBY = 149;
114 final static int TT_VARIABLE = 150;
115 final static int TT_INT_NUMBER = 151;
116 final static int TT_DOUBLE_NUMBER = 152;
117 final static int TT_INTERPOLATED_STRING = 153;
118 final static int TT_STRING_CONSTANT = 154;
120 final static int TT_LSHIFT = 155;
121 final static int TT_RSHIFT = 156;
122 final static int TT_EX_EQUAL = 157;
123 final static int TT_EX_UNEQUAL = 158;
124 final static int TT_LINE = 159;
125 // final static int TT_AT = 153; // @
130 *@param sess Description of Parameter
133 public PHPParser(IFile fileToParse) {
134 if (keywordMap == null) {
135 keywordMap = new HashMap();
136 for (int i = 0; i < PHP_KEYWORS.length; i++) {
137 keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
140 this.currentPHPString = 0;
141 this.fileToParse = fileToParse;
147 this.columnCount = 0;
154 * Create marker for the parse error
156 protected void setMarker(String message, int lineNumber, int errorLevel) throws CoreException {
157 setMarker(fileToParse, message, lineNumber, errorLevel);
160 public static void setMarker(IFile file, String message, int lineNumber, int errorLevel) throws CoreException {
162 Hashtable attributes = new Hashtable();
163 MarkerUtilities.setMessage(attributes, message);
164 switch (errorLevel) {
166 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
169 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
172 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
175 MarkerUtilities.setLineNumber(attributes, lineNumber);
176 MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
179 private void throwSyntaxError(String error) {
181 if (str.length() < chIndx) {
184 // read until end-of-line
186 while (str.length() > eol) {
187 ch = str.charAt(eol++);
193 throw new SyntaxError(rowCount, chIndx - columnCount + 1, str.substring(columnCount, eol), error);
197 * Method Declaration.
202 if (str.length() > chIndx) {
203 ch = str.charAt(chIndx++);
208 chIndx = str.length() + 1;
215 * gets the next token from input
217 void getNextToken() {
220 while (str.length() > chIndx) {
221 ch = str.charAt(chIndx++);
222 token = TT_UNDEFINED;
225 columnCount = chIndx;
226 continue; // while loop
228 if (str.length() == chIndx) {
231 if (!Character.isWhitespace(ch)) {
232 if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '_') || (ch == '$') || (ch == '@')) {
236 if (ch >= '0' && ch <= '9') {
241 if (str.length() > chIndx) {
242 if (str.charAt(chIndx) == '/') {
244 // read comment until end of line:
245 while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
249 } else if (str.charAt(chIndx) == '*') {
251 // multi line comment:
252 while (str.length() > chIndx) {
253 if (str.charAt(chIndx) == '*' && (str.length() > (chIndx + 1)) && str.charAt(chIndx + 1) == '/') {
257 ch = str.charAt(chIndx++);
260 columnCount = chIndx;
266 } else if (ch == '#') {
267 // read comment until end of line:
268 while ((str.length() > chIndx) && (str.charAt(chIndx) != '\n')) {
272 } else if (ch == '"') {
273 // read string until end
274 boolean openString = true;
275 while (str.length() > chIndx) {
276 ch = str.charAt(chIndx++);
278 if (str.length() > chIndx) {
279 ch = str.charAt(chIndx++);
281 } else if (ch == '"') {
284 } else if (ch == '\n') {
286 columnCount = chIndx;
290 throwSyntaxError("Open string character '\"' at end of file.");
292 token = TT_INTERPOLATED_STRING;
294 } else if (ch == '\'') {
295 // read string until end
296 boolean openString = true;
297 while (str.length() > chIndx) {
298 ch = str.charAt(chIndx++);
300 if (str.length() > chIndx) {
301 ch = str.charAt(chIndx++);
303 } else if (ch == '\'') {
306 } else if (ch == '\n') {
308 columnCount = chIndx;
312 throwSyntaxError("Open string character \"'\" at end of file.");
314 token = TT_STRING_CONSTANT;
333 token = TT_LISTCLOSE;
341 token = TT_PARTCLOSE;
349 token = TT_QUESTIONMARK;
353 if (str.length() > chIndx) {
354 if (str.charAt(chIndx) == '=') {
356 token = TT_TILDEASSIGN;
364 if (str.length() > chIndx) {
365 if (str.charAt(chIndx) == '=') {
367 token = TT_DOTASSIGN;
380 if (str.length() > chIndx) {
381 if (str.charAt(chIndx) == '=') {
383 token = TT_MODASSIGN;
390 token = TT_SEMICOLON;
395 if (str.length() > chIndx) {
396 if (str.charAt(chIndx) == '=') {
398 token = TT_POWASSIGN;
407 if (str.length() > chIndx) {
408 if (str.charAt(chIndx) == '=') {
419 if (str.length() > chIndx) {
420 if (str.charAt(chIndx) == '*') {
426 if (str.charAt(chIndx) == '=') {
437 if (str.length() > chIndx) {
438 if (str.charAt(chIndx) == '+') {
440 token = TT_INCREMENT;
444 if (str.charAt(chIndx) == '=') {
454 if (str.length() > chIndx) {
455 if (str.charAt(chIndx) == '-') {
457 token = TT_DECREMENT;
461 if (str.charAt(chIndx) == '=') {
463 token = TT_SUBTRACTFROM;
467 if (str.charAt(chIndx) == '>') {
479 if (str.length() > chIndx) {
480 ch = str.charAt(chIndx);
485 if (str.length() > chIndx) {
486 ch = str.charAt(chIndx);
507 if (str.length() > chIndx) {
508 if (str.charAt(chIndx) == '=') {
511 if (str.length() > chIndx) {
512 ch = str.charAt(chIndx);
516 token = TT_EX_UNEQUAL;
527 if (str.length() > chIndx) {
528 if (str.charAt(chIndx) == '=') {
530 token = TT_GREATEREQUAL;
533 if (str.charAt(chIndx) == '>') {
536 if (str.length() > chIndx) {
537 if (str.charAt(chIndx) == '=') {
539 token = TT_RSHIFTASSIGN;
551 if (str.length() > chIndx) {
552 if (str.charAt(chIndx) == '=') {
554 token = TT_LESSEQUAL;
558 if (str.charAt(chIndx) == '<') {
561 if (str.length() > chIndx) {
562 if (str.charAt(chIndx) == '=') {
564 token = TT_LSHIFTASSIGN;
577 if (str.length() > chIndx) {
578 if (str.charAt(chIndx) == '|') {
588 token = TT_AMPERSAND;
589 if (str.length() > chIndx) {
590 if (str.charAt(chIndx) == '&') {
595 if (str.charAt(chIndx) == '=') {
597 token = TT_ANDASSIGN;
617 throwSyntaxError("unexpected character: '" + ch + "'");
620 if (token == TT_UNDEFINED) {
621 throwSyntaxError("token not found");
628 chIndx = str.length() + 1;
633 if (phpList != null) {
634 if (currentPHPString < phpList.size()) {
635 token = TT_UNDEFINED;
636 temp = (PHPString) phpList.get(currentPHPString++);
637 this.str = temp.getPHPString();
640 this.rowCount = temp.getLineNumber();
641 this.columnCount = 0;
645 token = TT_UNDEFINED;
651 void getIdentifier() {
652 StringBuffer ident = new StringBuffer();
658 token = TT_IDENTIFIER;
661 while ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_')) {
665 identifier = ident.toString();
668 Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
670 token = i.intValue();
675 StringBuffer inum = new StringBuffer();
684 // determine number conversions:
685 if (firstCh == '0') {
714 if (numFormat == 16) {
715 while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
720 while ((ch >= '0' && ch <= '9') || (ch == '.') || (ch == 'E') || (ch == 'e')) {
721 if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
722 if (ch == '.' && dFlag != ' ') {
725 if ((dFlag == 'E') || (dFlag == 'e')) {
731 if ((ch == '-') || (ch == '+')) {
745 doubleNumber = new Double(inum.toString());
746 token = TT_DOUBLE_NUMBER;
749 longNumber = Long.valueOf(inum.toString(), numFormat);
750 token = TT_INT_NUMBER;
754 } catch (Throwable e) {
755 throwSyntaxError("Number format error: " + inum.toString());
759 public void htmlParse(String input) {
760 boolean lineCommentMode = false;
761 boolean multiLineCommentMode = false;
762 boolean stringMode = false;
764 StringBuffer buf = new StringBuffer();
766 int startLineNumber = 1;
770 boolean phpMode = false;
771 boolean phpFound = false;
773 phpList = new ArrayList();
774 currentPHPString = 0;
778 while (i < input.length()) {
779 ch = input.charAt(i++);
783 if ((!phpMode) && ch == '<') {
784 ch2 = input.charAt(i++);
786 ch2 = input.charAt(i++);
787 if (Character.isWhitespace(ch2)) {
792 startLineNumber = lineNumber;
794 } else if (ch2 == 'p') {
795 ch2 = input.charAt(i++);
797 ch2 = input.charAt(i++);
802 startLineNumber = lineNumber;
808 } else if (ch2 == 'P') {
809 ch2 = input.charAt(i++);
811 ch2 = input.charAt(i++);
816 startLineNumber = lineNumber;
830 if (lineCommentMode && (ch == '\n')) {
831 lineCommentMode = false;
832 // read until end of line
833 } else if ((!stringMode) && (ch == '#')) {
834 // read until end of line
835 lineCommentMode = true;
837 } else if ((!stringMode) && (!multiLineCommentMode) && (ch == '/')) {
838 ch2 = input.charAt(i++);
840 lineCommentMode = true;
842 } else if (ch2 == '*') {
843 multiLineCommentMode = true;
848 } else if (ch == '*' && multiLineCommentMode) {
849 ch2 = input.charAt(i++);
851 multiLineCommentMode = false;
856 } else if (ch == '\\' && stringMode) {
857 ch2 = input.charAt(i++);
863 } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
871 if (lineCommentMode || multiLineCommentMode || stringMode) {
876 ch2 = input.charAt(i++);
880 phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
889 setMarker("No PHP source code found.", lineNumber, PHPParser.INFO);
891 // for (int j=0;j<phpList.size();j++) {
892 // String temp = ((PHPString)phpList.get(j)).getPHPString();
893 // int startIndx = temp.length()-10;
894 // if (startIndx<0) {
897 // System.out.println(temp.substring(startIndx)+"?>");
901 // for(int j=0;j<phpList.size();j++) {
902 // temp = (PHPString) phpList.get(j);
903 // parser.start(temp.getPHPString(), temp.getLineNumber());
906 } catch (CoreException e) {
910 public void phpParse(String s, int rowCount) throws CoreException {
915 if (phpList.size() != 0) {
916 this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
921 this.rowCount = rowCount;
922 this.columnCount = 0;
925 if (token != TT_EOF && token != TT_UNDEFINED) {
928 if (token != TT_EOF && token != TT_UNDEFINED) {
929 if (token == TT_ARGCLOSE) {
930 throwSyntaxError("too many closing ')'; end-of-file not reached");
932 if (token == TT_LISTCLOSE) {
933 throwSyntaxError("too many closing '}'; end-of-file not reached");
935 if (token == TT_PARTCLOSE) {
936 throwSyntaxError("too many closing ']'; end-of-file not reached");
939 if (token == TT_ARGOPEN) {
940 throwSyntaxError("read character '('; end-of-file not reached");
942 if (token == TT_LISTOPEN) {
943 throwSyntaxError("read character '{'; end-of-file not reached");
945 if (token == TT_PARTOPEN) {
946 throwSyntaxError("read character '['; end-of-file not reached");
949 throwSyntaxError("end-of-file not reached");
951 } catch (SyntaxError err) {
955 setMarker(err.getMessage(), err.getLine(), ERROR);
960 public void statementList() throws CoreException {
963 if ((token == TT_LISTCLOSE)
964 || (token == TT_case)
965 || (token == TT_default)
966 || (token == TT_elseif)
967 || (token == TT_endif)
968 || (token == TT_endfor)
969 || (token == TT_endforeach)
970 || (token == TT_endwhile)
971 || (token == TT_endswitch)
973 || (token == TT_UNDEFINED)) {
979 public void compoundStatement() throws CoreException {
980 // '{' [statement-list] '}'
981 if (token == TT_LISTOPEN) {
984 throwSyntaxError("'{' expected in compound-statement.");
986 if (token != TT_LISTCLOSE) {
989 if (token == TT_LISTCLOSE) {
992 throwSyntaxError("'}' expected in compound-statement.");
996 public void statement() throws CoreException {
997 if (token > TT_KEYWORD && token != TT_list) {
998 String keyword = identifier;
999 if (token == TT_include || token == TT_include_once) {
1002 if (token == TT_SEMICOLON) {
1006 throwSyntaxError("';' character after 'include' or 'include_once' expected.");
1010 } else if (token == TT_require || token == TT_require_once) {
1014 if (token == TT_SEMICOLON) {
1018 throwSyntaxError("';' character after 'require' or 'require_once' expected.");
1022 } else if (token == TT_if) {
1024 if (token == TT_ARGOPEN) {
1027 throwSyntaxError("'(' expected after 'if' keyword.");
1030 if (token == TT_ARGCLOSE) {
1033 throwSyntaxError("')' expected after 'if' condition.");
1038 } else if (token == TT_switch) {
1040 if (token == TT_ARGOPEN) {
1043 throwSyntaxError("'(' expected after 'switch' keyword.");
1046 if (token == TT_ARGCLOSE) {
1049 throwSyntaxError("')' expected after 'switch' condition.");
1053 } else if (token == TT_for) {
1055 if (token == TT_ARGOPEN) {
1058 throwSyntaxError("'(' expected after 'for' keyword.");
1060 if (token == TT_SEMICOLON) {
1064 if (token == TT_SEMICOLON) {
1067 throwSyntaxError("';' character after 'for' expected.");
1070 if (token == TT_SEMICOLON) {
1074 if (token == TT_SEMICOLON) {
1077 throwSyntaxError("';' character after 'for' expected.");
1080 if (token == TT_ARGCLOSE) {
1084 if (token == TT_ARGCLOSE) {
1087 throwSyntaxError("')' expected after 'for' condition.");
1092 } else if (token == TT_while) {
1094 if (token == TT_ARGOPEN) {
1097 throwSyntaxError("'(' expected after 'while' keyword.");
1100 if (token == TT_ARGCLOSE) {
1103 throwSyntaxError("')' expected after 'while' condition.");
1107 } else if (token == TT_do) {
1109 if (token == TT_LISTOPEN) {
1112 throwSyntaxError("'{' expected after 'do' keyword.");
1114 if (token != TT_LISTCLOSE) {
1117 if (token == TT_LISTCLOSE) {
1120 throwSyntaxError("'}' expected after 'do' keyword.");
1122 if (token == TT_while) {
1124 if (token == TT_ARGOPEN) {
1127 throwSyntaxError("'(' expected after 'while' keyword.");
1130 if (token == TT_ARGCLOSE) {
1133 throwSyntaxError("')' expected after 'while' condition.");
1136 throwSyntaxError("'while' expected after 'do' keyword.");
1138 if (token == TT_SEMICOLON) {
1142 throwSyntaxError("';' expected after do-while statement.");
1146 } else if (token == TT_foreach) {
1148 if (token == TT_ARGOPEN) {
1151 throwSyntaxError("'(' expected after 'foreach' keyword.");
1154 if (token == TT_as) {
1157 throwSyntaxError("'as' expected after 'foreach' exxpression.");
1160 if (token == TT_FOREACH) {
1164 if (token == TT_ARGCLOSE) {
1167 throwSyntaxError("')' expected after 'foreach' expression.");
1172 } else if (token == TT_continue || token == TT_break || token == TT_return) {
1174 if (token != TT_SEMICOLON) {
1177 if (token == TT_SEMICOLON) {
1181 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1186 } else if (token == TT_echo) {
1189 if (token == TT_SEMICOLON) {
1193 throwSyntaxError("';' expected after 'echo' statement.");
1197 } else if (token == TT_print) {
1200 if (token == TT_SEMICOLON) {
1204 throwSyntaxError("';' expected after 'print' statement.");
1209 } else if (token == TT_global || token == TT_static) {
1212 if (token == TT_SEMICOLON) {
1216 throwSyntaxError("';' expected after 'global' or 'static' statement.");
1221 } else if (token == TT_unset) {
1223 if (token == TT_ARGOPEN) {
1226 throwSyntaxError("'(' expected after 'unset' keyword.");
1229 if (token == TT_ARGCLOSE) {
1232 throwSyntaxError("')' expected after 'unset' statement.");
1234 if (token == TT_SEMICOLON) {
1238 throwSyntaxError("';' expected after 'unset' statement.");
1243 // } else if (token == TT_exit || token == TT_die) {
1245 // if (token != TT_SEMICOLON) {
1248 // if (token == TT_SEMICOLON) {
1252 // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
1257 } else if (token == TT_define) {
1259 if (token == TT_ARGOPEN) {
1262 throwSyntaxError("'(' expected after 'define' keyword.");
1265 if (token == TT_COMMA) {
1268 throwSyntaxError("',' expected after first 'define' constant.");
1271 if (token == TT_ARGCLOSE) {
1274 throwSyntaxError("')' expected after 'define' statement.");
1276 if (token == TT_SEMICOLON) {
1280 throwSyntaxError("';' expected after 'define' statement.");
1284 } else if (token == TT_function) {
1286 functionDefinition();
1288 } else if (token == TT_class) {
1294 throwSyntaxError("Unexpected keyword '" + keyword + "'");
1297 } else if (token == TT_LISTOPEN) {
1298 // compoundStatement
1300 if (token != TT_LISTCLOSE) {
1303 if (token == TT_LISTCLOSE) {
1307 throwSyntaxError("'}' expected.");
1310 if (token != TT_SEMICOLON) {
1313 if (token == TT_SEMICOLON) {
1318 throwSyntaxError("';' expected after expression.");
1325 public void classDeclarator() {
1327 //identifier 'extends' identifier
1328 if (token == TT_IDENTIFIER) {
1330 if (token == TT_extends) {
1332 if (token == TT_IDENTIFIER) {
1335 throwSyntaxError("Class name expected after keyword 'extends'.");
1339 throwSyntaxError("Class name expected after keyword 'class'.");
1343 public void classBody() throws CoreException {
1344 //'{' [class-element-list] '}'
1345 if (token == TT_LISTOPEN) {
1347 if (token != TT_LISTCLOSE) {
1350 if (token == TT_LISTCLOSE) {
1353 throwSyntaxError("'}' expected at end of class body.");
1356 throwSyntaxError("'{' expected at start of class body.");
1360 public void classElementList() throws CoreException {
1363 } while (token == TT_function || token == TT_var);
1366 public void classElement() throws CoreException {
1368 //function-definition
1369 if (token == TT_function) {
1371 functionDefinition();
1372 } else if (token == TT_var) {
1376 throwSyntaxError("'function' or 'var' expected.");
1380 public void classProperty() {
1381 //'var' variable ';'
1382 //'var' variable '=' constant ';'
1383 if (token == TT_VARIABLE) {
1385 if (token == TT_ASSIGN) {
1388 if (token == TT_SEMICOLON) {
1391 throwSyntaxError("';' expected after variable declaration.");
1393 } else if (token == TT_SEMICOLON) {
1396 throwSyntaxError("';' or '=' expected after variable declaration.");
1399 throwSyntaxError("Variable expected after keyword 'var'.");
1403 public void functionDefinition() throws CoreException {
1404 functionDeclarator();
1405 compoundStatement();
1408 public void functionDeclarator() {
1409 //identifier '(' [parameter-list] ')'
1410 if (token == TT_IDENTIFIER) {
1412 if (token == TT_ARGOPEN) {
1415 throwSyntaxError("'(' expected in function declaration.");
1417 if (token != TT_ARGCLOSE) {
1420 if (token != TT_ARGCLOSE) {
1421 throwSyntaxError("')' expected in function declaration.");
1428 public void parameterList() {
1429 //parameter-declaration
1430 //parameter-list ',' parameter-declaration
1432 parameterDeclaration();
1433 if (token != TT_COMMA) {
1440 public void parameterDeclaration() {
1442 //variable-reference
1443 //variable '=' constant
1444 if (token == TT_VARIABLE) {
1446 if (token == TT_ASSIGN) {
1454 public void labeledStatementList() throws CoreException {
1455 if (token != TT_case && token != TT_default) {
1456 throwSyntaxError("'case' or 'default' expected.");
1459 if (token == TT_case) {
1462 if (token == TT_DDOT) {
1465 } else if (token == TT_SEMICOLON) {
1466 setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
1470 throwSyntaxError("':' character after 'case' constant expected.");
1472 } else { // TT_default
1474 if (token == TT_DDOT) {
1478 throwSyntaxError("':' character after 'default' expected.");
1481 } while (token == TT_case || token == TT_default);
1484 // public void labeledStatement() {
1485 // if (token == TT_case) {
1488 // if (token == TT_DDOT) {
1492 // throwSyntaxError("':' character after 'case' constant expected.");
1495 // } else if (token == TT_default) {
1497 // if (token == TT_DDOT) {
1501 // throwSyntaxError("':' character after 'default' expected.");
1507 public void expressionStatement() {
1510 public void inclusionStatement() {
1513 // public void compoundStatement() {
1516 // public void selectionStatement() {
1519 // public void iterationStatement() {
1522 // public void jumpStatement() {
1525 // public void outputStatement() {
1528 // public void scopeStatement() {
1531 // public void flowStatement() {
1534 // public void definitionStatement() {
1537 public void ifStatement() throws CoreException {
1538 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1539 if (token == TT_DDOT) {
1545 if (token == TT_DDOT) {
1549 if (token == TT_if) { //'else if'
1551 elseifStatementList();
1553 throwSyntaxError("':' expected after 'else'.");
1559 elseifStatementList();
1563 if (token != TT_endif) {
1564 throwSyntaxError("'endif' expected.");
1567 if (token != TT_SEMICOLON) {
1568 throwSyntaxError("';' expected after if-statement.");
1572 // statement [else-statement]
1574 if (token == TT_elseif) {
1576 if (token == TT_ARGOPEN) {
1579 throwSyntaxError("'(' expected after 'elseif' keyword.");
1582 if (token == TT_ARGCLOSE) {
1585 throwSyntaxError("')' expected after 'elseif' condition.");
1588 } else if (token == TT_else) {
1594 public void elseifStatementList() throws CoreException {
1600 if (token == TT_DDOT) {
1605 if (token == TT_if) { //'else if'
1608 throwSyntaxError("':' expected after 'else'.");
1621 public void elseifStatement() throws CoreException {
1622 if (token == TT_ARGOPEN) {
1625 if (token != TT_ARGOPEN) {
1626 throwSyntaxError("')' expected in else-if-statement.");
1629 if (token != TT_DDOT) {
1630 throwSyntaxError("':' expected in else-if-statement.");
1637 public void switchStatement() throws CoreException {
1638 if (token == TT_DDOT) {
1639 // ':' [labeled-statement-list] 'endswitch' ';'
1641 labeledStatementList();
1642 if (token != TT_endswitch) {
1643 throwSyntaxError("'endswitch' expected.");
1646 if (token != TT_SEMICOLON) {
1647 throwSyntaxError("';' expected after switch-statement.");
1651 // '{' [labeled-statement-list] '}'
1652 if (token != TT_LISTOPEN) {
1653 throwSyntaxError("'{' expected in switch statement.");
1656 if (token != TT_LISTCLOSE) {
1657 labeledStatementList();
1659 if (token != TT_LISTCLOSE) {
1660 throwSyntaxError("'}' expected in switch statement.");
1667 public void forStatement() throws CoreException {
1668 if (token == TT_DDOT) {
1671 if (token != TT_endfor) {
1672 throwSyntaxError("'endfor' expected.");
1675 if (token != TT_SEMICOLON) {
1676 throwSyntaxError("';' expected after for-statement.");
1684 public void whileStatement() throws CoreException {
1685 // ':' statement-list 'endwhile' ';'
1686 if (token == TT_DDOT) {
1689 if (token != TT_endwhile) {
1690 throwSyntaxError("'endwhile' expected.");
1693 if (token != TT_SEMICOLON) {
1694 throwSyntaxError("';' expected after while-statement.");
1702 public void foreachStatement() throws CoreException {
1703 if (token == TT_DDOT) {
1706 if (token != TT_endforeach) {
1707 throwSyntaxError("'endforeach' expected.");
1710 if (token != TT_SEMICOLON) {
1711 throwSyntaxError("';' expected after foreach-statement.");
1719 public void exitStatus() {
1720 if (token == TT_ARGOPEN) {
1723 throwSyntaxError("'(' expected in 'exit-status'.");
1725 if (token != TT_ARGCLOSE) {
1728 if (token == TT_ARGCLOSE) {
1731 throwSyntaxError("')' expected after 'exit-status'.");
1735 public void expressionList() {
1738 if (token == TT_COMMA) {
1746 public void expression() {
1747 // if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
1750 logicalinclusiveorExpression();
1751 // while (token != TT_SEMICOLON) {
1757 public void postfixExpression() {
1759 boolean castFlag = false;
1774 case TT_STRING_CONSTANT :
1777 case TT_INTERPOLATED_STRING :
1782 if (token == TT_IDENTIFIER) {
1783 // check if identifier is a type:
1785 String str = identifier.toLowerCase();
1786 for (int i = 0; i < PHP_TYPES.length; i++) {
1787 if (PHP_TYPES[i].equals(str)) {
1794 if (token != TT_ARGCLOSE) {
1795 throwSyntaxError(") expected after cast-type '" + ident + "'.");
1805 if (token != TT_ARGCLOSE) {
1806 throwSyntaxError(") expected in postfix-expression.");
1810 case TT_DOUBLE_NUMBER :
1813 case TT_INT_NUMBER :
1819 if (token == TT_LISTOPEN) {
1822 if (token != TT_LISTCLOSE) {
1823 throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
1828 case TT_IDENTIFIER :
1831 if (token == TT_ARGOPEN) {
1833 if (token != TT_ARGCLOSE) {
1835 if (token != TT_ARGCLOSE) {
1836 throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
1844 if (token == TT_ARGOPEN) {
1846 if (token == TT_COMMA) {
1850 if (token != TT_ARGCLOSE) {
1851 throwSyntaxError("')' expected after 'list' keyword.");
1854 // if (token == TT_SET) {
1856 // logicalinclusiveorExpression();
1859 throwSyntaxError("'(' expected after 'list' keyword.");
1864 // if (token != TT_SEMICOLON) {
1867 // if (token == TT_SEMICOLON) {
1871 // throwSyntaxError("';' expected after 'exit' expression.");
1877 // if (token != TT_SEMICOLON) {
1880 // if (token == TT_SEMICOLON) {
1884 // throwSyntaxError("';' expected after 'die' expression.");
1891 // if (token == TT_ARGOPEN) {
1893 // if (token == TT_COMMA) {
1896 // expressionList();
1897 // if (token != TT_ARGCLOSE) {
1898 // throwSyntaxError("')' expected after 'list' keyword.");
1901 // if (token == TT_SET) {
1903 // logicalinclusiveorExpression();
1906 // throwSyntaxError("'(' expected after 'list' keyword.");
1910 boolean while_flag = true;
1916 if (token != TT_PARTCLOSE) {
1917 throwSyntaxError("] expected in postfix-expression.");
1927 // if (token == TT_ARGOPEN) {
1929 // expressionList();
1930 // if (token != TT_ARGCLOSE) {
1931 // throwSyntaxError(") expected after variable '" + ident + "'.");
1936 case TT_IDENTIFIER :
1939 if (token == TT_ARGOPEN) {
1942 if (token != TT_ARGCLOSE) {
1943 throwSyntaxError(") expected after identifier '" + ident + "'.");
1951 if (token != TT_LISTCLOSE) {
1952 throwSyntaxError("} expected in postfix-expression.");
1957 throwSyntaxError("Syntax error after '->' token.");
1969 } while (while_flag);
1972 public void unaryExpression() {
1982 //'&' '*' '+' '-' '~' '!'
2008 postfixExpression();
2012 public void castExpression() {
2013 // if (token == TT_ARGOPEN) {
2016 // if (token != TT_ARGCLOSE) {
2017 // throwSyntaxError(") expected after cast-expression.");
2024 public void typeName() {
2025 //'string' 'unset' 'array' 'object'
2027 //'real' 'double' 'float'
2030 if (token == TT_IDENTIFIER) {
2032 String str = identifier.toLowerCase();
2034 for (int i = 0; i < PHP_TYPES.length; i++) {
2035 if (PHP_TYPES[i].equals(str)) {
2040 throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
2043 public void assignExpression() {
2045 if (token == TT_ASSIGN) { // =
2047 logicalinclusiveorExpression();
2048 } else if (token == TT_DOTASSIGN) { // .=
2050 logicalinclusiveorExpression();
2051 } else if (token == TT_FOREACH) { // =>
2053 logicalinclusiveorExpression();
2054 } else if (token == TT_ADDTO) { // +=
2056 logicalinclusiveorExpression();
2057 } else if (token == TT_SUBTRACTFROM) { // -=
2059 logicalinclusiveorExpression();
2060 } else if (token == TT_TIMESBY) { // *=
2062 logicalinclusiveorExpression();
2063 } else if (token == TT_DIVIDEBY) { // *=
2065 logicalinclusiveorExpression();
2066 } else if (token == TT_MODASSIGN) { // %=
2068 logicalinclusiveorExpression();
2069 } else if (token == TT_ANDASSIGN) { // &=
2071 logicalinclusiveorExpression();
2072 } else if (token == TT_POWASSIGN) { // ^=
2074 logicalinclusiveorExpression();
2075 } else if (token == TT_LSHIFTASSIGN) { // <<=
2077 logicalinclusiveorExpression();
2078 } else if (token == TT_RSHIFTASSIGN) { // >>=
2080 logicalinclusiveorExpression();
2081 } else if (token == TT_TILDEASSIGN) { // ~=
2083 logicalinclusiveorExpression();
2087 public void multiplicativeExpression() {
2090 if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
2097 public void concatenationExpression() {
2099 multiplicativeExpression();
2100 if (token != TT_DOT) {
2107 public void additiveExpression() {
2109 concatenationExpression();
2110 if (token != TT_ADD && token != TT_SUBTRACT) {
2117 public void shiftExpression() {
2119 additiveExpression();
2120 if (token != TT_LSHIFT && token != TT_RSHIFT) {
2127 public void relationalExpression() {
2130 if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
2137 public void identicalExpression() {
2139 relationalExpression();
2140 if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
2147 public void equalityExpression() {
2149 identicalExpression();
2150 if (token != TT_EQUAL && token != TT_UNEQUAL) {
2157 public void ternaryExpression() {
2158 equalityExpression();
2159 if (token == TT_QUESTIONMARK) {
2162 if (token == TT_DDOT) {
2166 throwSyntaxError("':' expected in ternary operator '? :'.");
2171 public void andExpression() {
2173 ternaryExpression();
2174 if (token != TT_AMPERSAND) {
2181 public void exclusiveorExpression() {
2184 if (token != TT_POW) {
2191 public void inclusiveorExpression() {
2193 exclusiveorExpression();
2194 if (token != TT_LINE) {
2201 public void booleanandExpression() {
2203 inclusiveorExpression();
2204 if (token != TT_AND) {
2211 public void booleanorExpression() {
2213 booleanandExpression();
2214 if (token != TT_OR) {
2221 public void logicalandExpression() {
2223 booleanorExpression();
2224 if (token != TT_and) {
2231 public void logicalexclusiveorExpression() {
2233 logicalandExpression();
2234 if (token != TT_xor) {
2241 public void logicalinclusiveorExpression() {
2243 logicalexclusiveorExpression();
2244 if (token != TT_or) {
2251 // public void assignmentExpression() {
2252 // if (token == TT_VARIABLE) {
2254 // if (token == TT_SET) {
2256 // logicalinclusiveorExpression();
2259 // logicalinclusiveorExpression();
2263 public void variableList() {
2266 if (token == TT_COMMA) {
2274 public void variable() {
2275 if (token == TT_VARIABLE) {
2278 throwSyntaxError("$-variable expected in variable-list.");
2282 public void constant() {
2287 case TT_DOUBLE_NUMBER :
2290 case TT_INT_NUMBER :
2294 throwSyntaxError("Constant expected after '+' presign.");
2300 case TT_DOUBLE_NUMBER :
2303 case TT_INT_NUMBER :
2307 throwSyntaxError("Constant expected after '-' presign.");
2319 case TT_STRING_CONSTANT :
2322 case TT_INTERPOLATED_STRING :
2325 case TT_DOUBLE_NUMBER :
2328 case TT_INT_NUMBER :
2332 throwSyntaxError("Constant expected.");