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();
777 while (i < input.length()) {
778 ch = input.charAt(i++);
782 if ((!phpMode) && ch == '<') {
783 ch2 = input.charAt(i++);
785 ch2 = input.charAt(i++);
786 if (Character.isWhitespace(ch2)) {
791 startLineNumber = lineNumber;
793 } else if (ch2 == 'p') {
794 ch2 = input.charAt(i++);
796 ch2 = input.charAt(i++);
801 startLineNumber = lineNumber;
807 } else if (ch2 == 'P') {
808 ch2 = input.charAt(i++);
810 ch2 = input.charAt(i++);
815 startLineNumber = lineNumber;
829 if (lineCommentMode && (ch == '\n')) {
830 lineCommentMode = false;
831 // read until end of line
832 } else if ((!stringMode) && (ch == '#')) {
833 // read until end of line
834 lineCommentMode = true;
836 } else if ((!stringMode) && (!multiLineCommentMode) && (ch == '/')) {
837 ch2 = input.charAt(i++);
839 lineCommentMode = true;
841 } else if (ch2 == '*') {
842 multiLineCommentMode = true;
847 } else if (ch == '*' && multiLineCommentMode) {
848 ch2 = input.charAt(i++);
850 multiLineCommentMode = false;
855 } else if (ch == '\\' && stringMode) {
856 ch2 = input.charAt(i++);
862 } else if ((!lineCommentMode) && (!multiLineCommentMode) && (ch == '"')) {
870 if (lineCommentMode || multiLineCommentMode || stringMode) {
875 ch2 = input.charAt(i++);
879 phpList.add(new PHPString(input.substring(startIndex, i - 2), startLineNumber));
888 setMarker("No PHP source code found.", lineNumber, PHPParser.INFO);
890 // for (int j=0;j<phpList.size();j++) {
891 // String temp = ((PHPString)phpList.get(j)).getPHPString();
892 // int startIndx = temp.length()-10;
893 // if (startIndx<0) {
896 // System.out.println(temp.substring(startIndx)+"?>");
900 // for(int j=0;j<phpList.size();j++) {
901 // temp = (PHPString) phpList.get(j);
902 // parser.start(temp.getPHPString(), temp.getLineNumber());
905 } catch (CoreException e) {
909 public void phpParse(String s, int rowCount) throws CoreException {
914 if (phpList.size() != 0) {
915 this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
920 this.rowCount = rowCount;
921 this.columnCount = 0;
924 if (token != TT_EOF && token != TT_UNDEFINED) {
927 if (token != TT_EOF && token != TT_UNDEFINED) {
928 if (token == TT_ARGCLOSE) {
929 throwSyntaxError("too many closing ')'; end-of-file not reached");
931 if (token == TT_LISTCLOSE) {
932 throwSyntaxError("too many closing '}'; end-of-file not reached");
934 if (token == TT_PARTCLOSE) {
935 throwSyntaxError("too many closing ']'; end-of-file not reached");
938 if (token == TT_ARGOPEN) {
939 throwSyntaxError("read character '('; end-of-file not reached");
941 if (token == TT_LISTOPEN) {
942 throwSyntaxError("read character '{'; end-of-file not reached");
944 if (token == TT_PARTOPEN) {
945 throwSyntaxError("read character '['; end-of-file not reached");
948 throwSyntaxError("end-of-file not reached");
950 } catch (SyntaxError err) {
954 setMarker(err.getMessage(), err.getLine(), ERROR);
959 public void statementList() throws CoreException {
962 if ((token == TT_LISTCLOSE)
963 || (token == TT_case)
964 || (token == TT_default)
965 || (token == TT_elseif)
966 || (token == TT_endif)
967 || (token == TT_endfor)
968 || (token == TT_endforeach)
969 || (token == TT_endwhile)
970 || (token == TT_endswitch)
972 || (token == TT_UNDEFINED)) {
978 public void compoundStatement() throws CoreException {
979 // '{' [statement-list] '}'
980 if (token == TT_LISTOPEN) {
983 throwSyntaxError("'{' expected in compound-statement.");
985 if (token != TT_LISTCLOSE) {
988 if (token == TT_LISTCLOSE) {
991 throwSyntaxError("'}' expected in compound-statement.");
995 public void statement() throws CoreException {
996 if (token > TT_KEYWORD && token != TT_list) {
997 String keyword = identifier;
998 if (token == TT_include || token == TT_include_once) {
1001 if (token == TT_SEMICOLON) {
1005 throwSyntaxError("';' character after 'include' or 'include_once' expected.");
1009 } else if (token == TT_require || token == TT_require_once) {
1013 if (token == TT_SEMICOLON) {
1017 throwSyntaxError("';' character after 'require' or 'require_once' expected.");
1021 } else if (token == TT_if) {
1023 if (token == TT_ARGOPEN) {
1026 throwSyntaxError("'(' expected after 'if' keyword.");
1029 if (token == TT_ARGCLOSE) {
1032 throwSyntaxError("')' expected after 'if' condition.");
1037 } else if (token == TT_switch) {
1039 if (token == TT_ARGOPEN) {
1042 throwSyntaxError("'(' expected after 'switch' keyword.");
1045 if (token == TT_ARGCLOSE) {
1048 throwSyntaxError("')' expected after 'switch' condition.");
1052 } else if (token == TT_for) {
1054 if (token == TT_ARGOPEN) {
1057 throwSyntaxError("'(' expected after 'for' keyword.");
1059 if (token == TT_SEMICOLON) {
1063 if (token == TT_SEMICOLON) {
1066 throwSyntaxError("';' character after 'for' expected.");
1069 if (token == TT_SEMICOLON) {
1073 if (token == TT_SEMICOLON) {
1076 throwSyntaxError("';' character after 'for' expected.");
1079 if (token == TT_ARGCLOSE) {
1083 if (token == TT_ARGCLOSE) {
1086 throwSyntaxError("')' expected after 'for' condition.");
1091 } else if (token == TT_while) {
1093 if (token == TT_ARGOPEN) {
1096 throwSyntaxError("'(' expected after 'while' keyword.");
1099 if (token == TT_ARGCLOSE) {
1102 throwSyntaxError("')' expected after 'while' condition.");
1106 } else if (token == TT_do) {
1108 if (token == TT_LISTOPEN) {
1111 throwSyntaxError("'{' expected after 'do' keyword.");
1113 if (token != TT_LISTCLOSE) {
1116 if (token == TT_LISTCLOSE) {
1119 throwSyntaxError("'}' expected after 'do' keyword.");
1121 if (token == TT_while) {
1123 if (token == TT_ARGOPEN) {
1126 throwSyntaxError("'(' expected after 'while' keyword.");
1129 if (token == TT_ARGCLOSE) {
1132 throwSyntaxError("')' expected after 'while' condition.");
1135 throwSyntaxError("'while' expected after 'do' keyword.");
1137 if (token == TT_SEMICOLON) {
1141 throwSyntaxError("';' expected after do-while statement.");
1145 } else if (token == TT_foreach) {
1147 if (token == TT_ARGOPEN) {
1150 throwSyntaxError("'(' expected after 'foreach' keyword.");
1153 if (token == TT_as) {
1156 throwSyntaxError("'as' expected after 'foreach' exxpression.");
1159 if (token == TT_FOREACH) {
1163 if (token == TT_ARGCLOSE) {
1166 throwSyntaxError("')' expected after 'foreach' expression.");
1171 } else if (token == TT_continue || token == TT_break || token == TT_return) {
1173 if (token != TT_SEMICOLON) {
1176 if (token == TT_SEMICOLON) {
1180 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1185 } else if (token == TT_echo) {
1188 if (token == TT_SEMICOLON) {
1192 throwSyntaxError("';' expected after 'echo' statement.");
1196 } else if (token == TT_print) {
1199 if (token == TT_SEMICOLON) {
1203 throwSyntaxError("';' expected after 'print' statement.");
1208 } else if (token == TT_global || token == TT_static) {
1211 if (token == TT_SEMICOLON) {
1215 throwSyntaxError("';' expected after 'global' or 'static' statement.");
1220 } else if (token == TT_unset) {
1222 if (token == TT_ARGOPEN) {
1225 throwSyntaxError("'(' expected after 'unset' keyword.");
1228 if (token == TT_ARGCLOSE) {
1231 throwSyntaxError("')' expected after 'unset' statement.");
1233 if (token == TT_SEMICOLON) {
1237 throwSyntaxError("';' expected after 'unset' statement.");
1242 // } else if (token == TT_exit || token == TT_die) {
1244 // if (token != TT_SEMICOLON) {
1247 // if (token == TT_SEMICOLON) {
1251 // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
1256 } else if (token == TT_define) {
1258 if (token == TT_ARGOPEN) {
1261 throwSyntaxError("'(' expected after 'define' keyword.");
1264 if (token == TT_COMMA) {
1267 throwSyntaxError("',' expected after first 'define' constant.");
1270 if (token == TT_ARGCLOSE) {
1273 throwSyntaxError("')' expected after 'define' statement.");
1275 if (token == TT_SEMICOLON) {
1279 throwSyntaxError("';' expected after 'define' statement.");
1283 } else if (token == TT_function) {
1285 functionDefinition();
1287 } else if (token == TT_class) {
1293 throwSyntaxError("Unexpected keyword '" + keyword + "'");
1296 } else if (token == TT_LISTOPEN) {
1297 // compoundStatement
1299 if (token != TT_LISTCLOSE) {
1302 if (token == TT_LISTCLOSE) {
1306 throwSyntaxError("'}' expected.");
1309 if (token != TT_SEMICOLON) {
1312 if (token == TT_SEMICOLON) {
1317 throwSyntaxError("';' expected after expression.");
1324 public void classDeclarator() {
1326 //identifier 'extends' identifier
1327 if (token == TT_IDENTIFIER) {
1329 if (token == TT_extends) {
1331 if (token == TT_IDENTIFIER) {
1334 throwSyntaxError("Class name expected after keyword 'extends'.");
1338 throwSyntaxError("Class name expected after keyword 'class'.");
1342 public void classBody() throws CoreException {
1343 //'{' [class-element-list] '}'
1344 if (token == TT_LISTOPEN) {
1346 if (token != TT_LISTCLOSE) {
1349 if (token == TT_LISTCLOSE) {
1352 throwSyntaxError("'}' expected at end of class body.");
1355 throwSyntaxError("'{' expected at start of class body.");
1359 public void classElementList() throws CoreException {
1362 } while (token == TT_function || token == TT_var);
1365 public void classElement() throws CoreException {
1367 //function-definition
1368 if (token == TT_function) {
1370 functionDefinition();
1371 } else if (token == TT_var) {
1375 throwSyntaxError("'function' or 'var' expected.");
1379 public void classProperty() {
1380 //'var' variable ';'
1381 //'var' variable '=' constant ';'
1382 if (token == TT_VARIABLE) {
1384 if (token == TT_ASSIGN) {
1387 if (token == TT_SEMICOLON) {
1390 throwSyntaxError("';' expected after variable declaration.");
1392 } else if (token == TT_SEMICOLON) {
1395 throwSyntaxError("';' or '=' expected after variable declaration.");
1398 throwSyntaxError("Variable expected after keyword 'var'.");
1402 public void functionDefinition() throws CoreException {
1403 functionDeclarator();
1404 compoundStatement();
1407 public void functionDeclarator() {
1408 //identifier '(' [parameter-list] ')'
1409 if (token == TT_IDENTIFIER) {
1411 if (token == TT_ARGOPEN) {
1414 throwSyntaxError("'(' expected in function declaration.");
1416 if (token != TT_ARGCLOSE) {
1419 if (token != TT_ARGCLOSE) {
1420 throwSyntaxError("')' expected in function declaration.");
1427 public void parameterList() {
1428 //parameter-declaration
1429 //parameter-list ',' parameter-declaration
1431 parameterDeclaration();
1432 if (token != TT_COMMA) {
1439 public void parameterDeclaration() {
1441 //variable-reference
1442 //variable '=' constant
1443 if (token == TT_VARIABLE) {
1445 if (token == TT_ASSIGN) {
1453 public void labeledStatementList() throws CoreException {
1454 if (token != TT_case && token != TT_default) {
1455 throwSyntaxError("'case' or 'default' expected.");
1458 if (token == TT_case) {
1461 if (token == TT_DDOT) {
1464 } else if (token == TT_SEMICOLON) {
1465 setMarker("':' expected after 'case' keyword found ';'.", rowCount, PHPParser.INFO);
1469 throwSyntaxError("':' character after 'case' constant expected.");
1471 } else { // TT_default
1473 if (token == TT_DDOT) {
1477 throwSyntaxError("':' character after 'default' expected.");
1480 } while (token == TT_case || token == TT_default);
1483 // public void labeledStatement() {
1484 // if (token == TT_case) {
1487 // if (token == TT_DDOT) {
1491 // throwSyntaxError("':' character after 'case' constant expected.");
1494 // } else if (token == TT_default) {
1496 // if (token == TT_DDOT) {
1500 // throwSyntaxError("':' character after 'default' expected.");
1506 public void expressionStatement() {
1509 public void inclusionStatement() {
1512 // public void compoundStatement() {
1515 // public void selectionStatement() {
1518 // public void iterationStatement() {
1521 // public void jumpStatement() {
1524 // public void outputStatement() {
1527 // public void scopeStatement() {
1530 // public void flowStatement() {
1533 // public void definitionStatement() {
1536 public void ifStatement() throws CoreException {
1537 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1538 if (token == TT_DDOT) {
1544 if (token == TT_DDOT) {
1548 if (token == TT_if) { //'else if'
1550 elseifStatementList();
1552 throwSyntaxError("':' expected after 'else'.");
1558 elseifStatementList();
1562 if (token != TT_endif) {
1563 throwSyntaxError("'endif' expected.");
1566 if (token != TT_SEMICOLON) {
1567 throwSyntaxError("';' expected after if-statement.");
1571 // statement [else-statement]
1573 if (token == TT_elseif) {
1575 if (token == TT_ARGOPEN) {
1578 throwSyntaxError("'(' expected after 'elseif' keyword.");
1581 if (token == TT_ARGCLOSE) {
1584 throwSyntaxError("')' expected after 'elseif' condition.");
1587 } else if (token == TT_else) {
1593 public void elseifStatementList() throws CoreException {
1599 if (token == TT_DDOT) {
1604 if (token == TT_if) { //'else if'
1607 throwSyntaxError("':' expected after 'else'.");
1620 public void elseifStatement() throws CoreException {
1621 if (token == TT_ARGOPEN) {
1624 if (token != TT_ARGOPEN) {
1625 throwSyntaxError("')' expected in else-if-statement.");
1628 if (token != TT_DDOT) {
1629 throwSyntaxError("':' expected in else-if-statement.");
1636 public void switchStatement() throws CoreException {
1637 if (token == TT_DDOT) {
1638 // ':' [labeled-statement-list] 'endswitch' ';'
1640 labeledStatementList();
1641 if (token != TT_endswitch) {
1642 throwSyntaxError("'endswitch' expected.");
1645 if (token != TT_SEMICOLON) {
1646 throwSyntaxError("';' expected after switch-statement.");
1650 // '{' [labeled-statement-list] '}'
1651 if (token != TT_LISTOPEN) {
1652 throwSyntaxError("'{' expected in switch statement.");
1655 if (token != TT_LISTCLOSE) {
1656 labeledStatementList();
1658 if (token != TT_LISTCLOSE) {
1659 throwSyntaxError("'}' expected in switch statement.");
1666 public void forStatement() throws CoreException {
1667 if (token == TT_DDOT) {
1670 if (token != TT_endfor) {
1671 throwSyntaxError("'endfor' expected.");
1674 if (token != TT_SEMICOLON) {
1675 throwSyntaxError("';' expected after for-statement.");
1683 public void whileStatement() throws CoreException {
1684 // ':' statement-list 'endwhile' ';'
1685 if (token == TT_DDOT) {
1688 if (token != TT_endwhile) {
1689 throwSyntaxError("'endwhile' expected.");
1692 if (token != TT_SEMICOLON) {
1693 throwSyntaxError("';' expected after while-statement.");
1701 public void foreachStatement() throws CoreException {
1702 if (token == TT_DDOT) {
1705 if (token != TT_endforeach) {
1706 throwSyntaxError("'endforeach' expected.");
1709 if (token != TT_SEMICOLON) {
1710 throwSyntaxError("';' expected after foreach-statement.");
1718 public void exitStatus() {
1719 if (token == TT_ARGOPEN) {
1722 throwSyntaxError("'(' expected in 'exit-status'.");
1724 if (token != TT_ARGCLOSE) {
1727 if (token == TT_ARGCLOSE) {
1730 throwSyntaxError("')' expected after 'exit-status'.");
1734 public void expressionList() {
1737 if (token == TT_COMMA) {
1745 public void expression() {
1746 // if (token == TT_STRING_CONSTANT || token == TT_INTERPOLATED_STRING) {
1749 logicalinclusiveorExpression();
1750 // while (token != TT_SEMICOLON) {
1756 public void postfixExpression() {
1758 boolean castFlag = false;
1773 case TT_STRING_CONSTANT :
1776 case TT_INTERPOLATED_STRING :
1781 if (token == TT_IDENTIFIER) {
1782 // check if identifier is a type:
1784 String str = identifier.toLowerCase();
1785 for (int i = 0; i < PHP_TYPES.length; i++) {
1786 if (PHP_TYPES[i].equals(str)) {
1793 if (token != TT_ARGCLOSE) {
1794 throwSyntaxError(") expected after cast-type '" + ident + "'.");
1804 if (token != TT_ARGCLOSE) {
1805 throwSyntaxError(") expected in postfix-expression.");
1809 case TT_DOUBLE_NUMBER :
1812 case TT_INT_NUMBER :
1818 if (token == TT_LISTOPEN) {
1821 if (token != TT_LISTCLOSE) {
1822 throwSyntaxError("'}' expected after variable '" + ident + "' in variable-expression.");
1827 case TT_IDENTIFIER :
1830 if (token == TT_ARGOPEN) {
1832 if (token != TT_ARGCLOSE) {
1834 if (token != TT_ARGCLOSE) {
1835 throwSyntaxError("')' expected after identifier '" + ident + "' in postfix-expression.");
1843 if (token == TT_ARGOPEN) {
1845 if (token == TT_COMMA) {
1849 if (token != TT_ARGCLOSE) {
1850 throwSyntaxError("')' expected after 'list' keyword.");
1853 // if (token == TT_SET) {
1855 // logicalinclusiveorExpression();
1858 throwSyntaxError("'(' expected after 'list' keyword.");
1863 // if (token != TT_SEMICOLON) {
1866 // if (token == TT_SEMICOLON) {
1870 // throwSyntaxError("';' expected after 'exit' expression.");
1876 // if (token != TT_SEMICOLON) {
1879 // if (token == TT_SEMICOLON) {
1883 // throwSyntaxError("';' expected after 'die' expression.");
1890 // if (token == TT_ARGOPEN) {
1892 // if (token == TT_COMMA) {
1895 // expressionList();
1896 // if (token != TT_ARGCLOSE) {
1897 // throwSyntaxError("')' expected after 'list' keyword.");
1900 // if (token == TT_SET) {
1902 // logicalinclusiveorExpression();
1905 // throwSyntaxError("'(' expected after 'list' keyword.");
1909 boolean while_flag = true;
1915 if (token != TT_PARTCLOSE) {
1916 throwSyntaxError("] expected in postfix-expression.");
1926 // if (token == TT_ARGOPEN) {
1928 // expressionList();
1929 // if (token != TT_ARGCLOSE) {
1930 // throwSyntaxError(") expected after variable '" + ident + "'.");
1935 case TT_IDENTIFIER :
1938 if (token == TT_ARGOPEN) {
1941 if (token != TT_ARGCLOSE) {
1942 throwSyntaxError(") expected after identifier '" + ident + "'.");
1950 if (token != TT_LISTCLOSE) {
1951 throwSyntaxError("} expected in postfix-expression.");
1956 throwSyntaxError("Syntax error after '->' token.");
1968 } while (while_flag);
1971 public void unaryExpression() {
1981 //'&' '*' '+' '-' '~' '!'
2007 postfixExpression();
2011 public void castExpression() {
2012 // if (token == TT_ARGOPEN) {
2015 // if (token != TT_ARGCLOSE) {
2016 // throwSyntaxError(") expected after cast-expression.");
2023 public void typeName() {
2024 //'string' 'unset' 'array' 'object'
2026 //'real' 'double' 'float'
2029 if (token == TT_IDENTIFIER) {
2031 String str = identifier.toLowerCase();
2033 for (int i = 0; i < PHP_TYPES.length; i++) {
2034 if (PHP_TYPES[i].equals(str)) {
2039 throwSyntaxError("Expected type cast '( <type-name> )'; Got '" + ident + "'.");
2042 public void assignExpression() {
2044 if (token == TT_ASSIGN) { // =
2046 logicalinclusiveorExpression();
2047 } else if (token == TT_DOTASSIGN) { // .=
2049 logicalinclusiveorExpression();
2050 } else if (token == TT_FOREACH) { // =>
2052 logicalinclusiveorExpression();
2053 } else if (token == TT_ADDTO) { // +=
2055 logicalinclusiveorExpression();
2056 } else if (token == TT_SUBTRACTFROM) { // -=
2058 logicalinclusiveorExpression();
2059 } else if (token == TT_TIMESBY) { // *=
2061 logicalinclusiveorExpression();
2062 } else if (token == TT_DIVIDEBY) { // *=
2064 logicalinclusiveorExpression();
2065 } else if (token == TT_MODASSIGN) { // %=
2067 logicalinclusiveorExpression();
2068 } else if (token == TT_ANDASSIGN) { // &=
2070 logicalinclusiveorExpression();
2071 } else if (token == TT_POWASSIGN) { // ^=
2073 logicalinclusiveorExpression();
2074 } else if (token == TT_LSHIFTASSIGN) { // <<=
2076 logicalinclusiveorExpression();
2077 } else if (token == TT_RSHIFTASSIGN) { // >>=
2079 logicalinclusiveorExpression();
2080 } else if (token == TT_TILDEASSIGN) { // ~=
2082 logicalinclusiveorExpression();
2086 public void multiplicativeExpression() {
2089 if (token != TT_MULTIPLY && token != TT_DIV && token != TT_MOD) {
2096 public void concatenationExpression() {
2098 multiplicativeExpression();
2099 if (token != TT_DOT) {
2106 public void additiveExpression() {
2108 concatenationExpression();
2109 if (token != TT_ADD && token != TT_SUBTRACT) {
2116 public void shiftExpression() {
2118 additiveExpression();
2119 if (token != TT_LSHIFT && token != TT_RSHIFT) {
2126 public void relationalExpression() {
2129 if (token != TT_LESS && token != TT_GREATER && token != TT_LESSEQUAL && token != TT_GREATEREQUAL) {
2136 public void identicalExpression() {
2138 relationalExpression();
2139 if (token != TT_EX_EQUAL && token != TT_EX_UNEQUAL) {
2146 public void equalityExpression() {
2148 identicalExpression();
2149 if (token != TT_EQUAL && token != TT_UNEQUAL) {
2156 public void ternaryExpression() {
2157 equalityExpression();
2158 if (token == TT_QUESTIONMARK) {
2161 if (token == TT_DDOT) {
2165 throwSyntaxError("':' expected in ternary operator '? :'.");
2170 public void andExpression() {
2172 ternaryExpression();
2173 if (token != TT_AMPERSAND) {
2180 public void exclusiveorExpression() {
2183 if (token != TT_POW) {
2190 public void inclusiveorExpression() {
2192 exclusiveorExpression();
2193 if (token != TT_LINE) {
2200 public void booleanandExpression() {
2202 inclusiveorExpression();
2203 if (token != TT_AND) {
2210 public void booleanorExpression() {
2212 booleanandExpression();
2213 if (token != TT_OR) {
2220 public void logicalandExpression() {
2222 booleanorExpression();
2223 if (token != TT_and) {
2230 public void logicalexclusiveorExpression() {
2232 logicalandExpression();
2233 if (token != TT_xor) {
2240 public void logicalinclusiveorExpression() {
2242 logicalexclusiveorExpression();
2243 if (token != TT_or) {
2250 // public void assignmentExpression() {
2251 // if (token == TT_VARIABLE) {
2253 // if (token == TT_SET) {
2255 // logicalinclusiveorExpression();
2258 // logicalinclusiveorExpression();
2262 public void variableList() {
2265 if (token == TT_COMMA) {
2273 public void variable() {
2274 if (token == TT_VARIABLE) {
2277 throwSyntaxError("$-variable expected in variable-list.");
2281 public void constant() {
2286 case TT_DOUBLE_NUMBER :
2289 case TT_INT_NUMBER :
2293 throwSyntaxError("Constant expected after '+' presign.");
2299 case TT_DOUBLE_NUMBER :
2302 case TT_INT_NUMBER :
2306 throwSyntaxError("Constant expected after '-' presign.");
2318 case TT_STRING_CONSTANT :
2321 case TT_INTERPOLATED_STRING :
2324 case TT_DOUBLE_NUMBER :
2327 case TT_INT_NUMBER :
2331 throwSyntaxError("Constant expected.");