1 /**********************************************************************
2 Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
9 Klaus Hartlage - www.eclipseproject.de
10 **********************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
13 import java.util.ArrayList;
14 import java.util.Hashtable;
16 import net.sourceforge.phpdt.core.compiler.*;
17 import net.sourceforge.phpdt.internal.compiler.parser.*;
18 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
19 import net.sourceforge.phpeclipse.phpeditor.PHPString;
20 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IMarker;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.jface.preference.IPreferenceStore;
26 import org.eclipse.ui.texteditor.MarkerUtilities;
27 import test.PHPParserSuperclass;
29 public class Parser extends PHPParserSuperclass implements PHPKeywords, ITerminalSymbols {
31 public static final int ERROR = 2;
32 public static final int WARNING = 1;
33 public static final int INFO = 0;
35 public static final boolean DEBUG = false;
37 public Scanner scanner;
39 private IFile fileToParse;
40 private ArrayList phpList;
42 private int currentPHPString;
43 private boolean phpEnd;
45 // private static HashMap keywordMap = null;
53 // row counter for syntax errors:
55 // column counter for syntax errors:
60 // // current identifier
66 private String stringValue;
68 /** Contains the current expression. */
69 // private StringBuffer expression;
71 private boolean phpMode;
73 // final static int TokenNameEOF = 0;
74 // final static int TokenNameERROR = 1;
75 // final static int TokenNameHTML = 2;
77 // final static int TokenNameREMAINDER = 30;
78 // final static int TokenNameNOT = 31;
79 // final static int TokenNameDOT = 32;
80 // final static int TokenNameXOR = 33;
81 // final static int TokenNameDIVIDE = 34;
82 // final static int TokenNameMULTIPLY = 35;
83 // final static int TokenNameMINUS = 36;
84 // final static int TokenNamePLUS = 37;
85 // final static int TokenNameEQUAL_EQUAL = 38;
86 // final static int TokenNameNOT_EQUAL = 39;
87 // final static int TokenNameGREATER = 40;
88 // final static int TokenNameGREATER_EQUAL = 41;
89 // final static int TokenNameLESS = 42;
90 // final static int TokenNameLESS_EQUAL = 43;
91 // final static int TokenNameAND_AND = 44;
92 // final static int TokenNameOR_OR = 45;
93 // // final static int TokenNameHASH = 46;
94 // final static int TokenNameCOLON = 47;
95 // final static int TokenNameDOT_EQUAL = 48;
97 // final static int TokenNameEQUAL = 49;
98 // final static int TokenNameMINUS_GREATER = 50; // ->
99 // final static int TokenNameFOREACH = 51;
100 // final static int TokenNameAND = 52;
101 // //final static int TokenNameDOLLARLISTOPEN = 53;
102 // final static int TokenNameTWIDDLE = 54;
103 // final static int TokenNameTWIDDLE_EQUAL = 55;
104 // final static int TokenNameREMAINDER_EQUAL = 56;
105 // final static int TokenNameXOR_EQUAL = 57;
106 // final static int TokenNameRIGHT_SHIFT_EQUAL = 58;
107 // final static int TokenNameLEFT_SHIFT_EQUAL = 59;
108 // final static int TokenNameAND_EQUAL = 60;
109 // final static int TokenNameOR_EQUAL = 61;
110 // final static int TokenNameQUESTION = 62;
111 // final static int TokenNameCOLON_COLON = 63;
112 // final static int TokenNameAT = 63;
113 // // final static int TokenNameHEREDOC = 64;
115 // final static int TokenNameDOLLAROPEN = 127;
116 // final static int TokenNameLPAREN = 128;
117 // final static int TokenNameRPAREN = 129;
118 // final static int TokenNameLBRACE = 130;
119 // final static int TokenNameRBRACE = 131;
120 // final static int TokenNameLBRACKET = 132;
121 // final static int TokenNameRBRACKET = 133;
122 // final static int TokenNameCOMMA = 134;
124 // final static int TokenNameStringLiteral = 136;
125 // final static int TokenNameIdentifier = 138;
126 // // final static int TokenNameDIGIT = 139;
127 // final static int TokenNameSEMICOLON = 140;
128 // // final static int TokenNameSLOT = 141;
129 // // final static int TokenNameSLOTSEQUENCE = 142;
130 // final static int TokenNameMINUS_MINUS = 144;
131 // final static int TokenNamePLUS_PLUS = 145;
132 // final static int TokenNamePLUS_EQUAL = 146;
133 // final static int TokenNameDIVIDE_EQUAL = 147;
134 // final static int TokenNameMINUS_EQUAL = 148;
135 // final static int TokenNameMULTIPLY_EQUAL = 149;
136 // final static int TokenNameVariable = 150;
137 // final static int TokenNameIntegerLiteral = 151;
138 // final static int TokenNameDoubleLiteral = 152;
139 // final static int TokenNameStringInterpolated = 153;
140 // final static int TokenNameStringConstant = 154;
142 // final static int TokenNameLEFT_SHIFT = 155;
143 // final static int TokenNameRIGHT_SHIFT = 156;
144 // final static int TokenNameEQUAL_EQUAL_EQUAL = 157;
145 // final static int TokenNameNOT_EQUAL_EQUAL = 158;
146 // final static int TokenNameOR = 159;
147 // final static int TokenNameAT = 153; // @
152 public void setFileToParse(IFile fileToParse) {
153 this.currentPHPString = 0;
154 this.fileToParse = fileToParse;
157 this.token = TokenNameEOF;
159 this.initializeScanner();
165 *@param sess Description of Parameter
168 public Parser(IFile fileToParse) {
169 // if (keywordMap == null) {
170 // keywordMap = new HashMap();
171 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
172 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
175 this.currentPHPString = 0;
176 this.fileToParse = fileToParse;
179 this.token = TokenNameEOF;
181 // this.rowCount = 1;
182 // this.columnCount = 0;
186 this.initializeScanner();
189 public void initializeScanner() {
190 this.scanner = new Scanner(false, false, false, false);
193 * Create marker for the parse error
195 private void setMarker(
200 throws CoreException {
201 setMarker(fileToParse, message, charStart, charEnd, errorLevel);
204 public static void setMarker(
210 throws CoreException {
212 Hashtable attributes = new Hashtable();
213 MarkerUtilities.setMessage(attributes, message);
214 switch (errorLevel) {
216 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
221 new Integer(IMarker.SEVERITY_WARNING));
224 attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
227 MarkerUtilities.setCharStart(attributes, charStart);
228 MarkerUtilities.setCharEnd(attributes, charEnd);
229 // setLineNumber(attributes, lineNumber);
230 MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
235 * This method will throw the SyntaxError.
236 * It will add the good lines and columns to the Error
237 * @param error the error message
238 * @throws SyntaxError the error raised
240 private void throwSyntaxError(String error) {
242 // if (str.length() < chIndx) {
245 // // read until end-of-line
247 // while (str.length() > eol) {
248 // ch = str.charAt(eol++);
254 // throw new SyntaxError(
256 // chIndx - columnCount + 1,
257 // str.substring(columnCount, eol),
259 throw new SyntaxError(
267 * This method will throw the SyntaxError.
268 * It will add the good lines and columns to the Error
269 * @param error the error message
270 * @throws SyntaxError the error raised
272 private void throwSyntaxError(String error, int startRow) {
273 throw new SyntaxError(startRow, 0, " ", error);
277 * Method Declaration.
281 // private void getChar() {
282 // if (str.length() > chIndx) {
283 // ch = str.charAt(chIndx++);
288 // chIndx = str.length() + 1;
290 // // token = TokenNameEOF;
295 * gets the next token from input
297 private void getNextToken() throws CoreException {
299 token = scanner.getNextToken();
301 int currentEndPosition = scanner.getCurrentTokenEndPosition();
302 int currentStartPosition = scanner.getCurrentTokenStartPosition();
305 currentStartPosition + "," + currentEndPosition + ": ");
306 System.out.println(scanner.toStringAction(token));
308 } catch (InvalidInputException e) {
309 token = TokenNameERROR;
313 // boolean phpFound = false;
320 // while (str.length() > chIndx) {
321 // token = TokenNameERROR;
322 // ch = str.charAt(chIndx++);
328 // ch2 = str.charAt(chIndx++);
330 // ch2 = str.charAt(chIndx++);
331 // if (Character.isWhitespace(ch2)) {
336 // } else if (ch2 == 'p' || ch2 == 'P') {
337 // ch2 = str.charAt(chIndx++);
338 // if (ch2 == 'h' || ch2 == 'H') {
339 // ch2 = str.charAt(chIndx++);
340 // if (ch2 == 'p' || ch2 == 'P') {
358 // while (str.length() > chIndx) {
359 // ch = str.charAt(chIndx++);
360 // token = TokenNameERROR;
363 // columnCount = chIndx;
364 // continue; // while loop
366 // if (str.length() == chIndx) {
369 // if (!Character.isWhitespace(ch)) {
371 // if (str.length() > chIndx) {
372 // if (str.charAt(chIndx) == '{') {
374 // token = TokenNameDOLLAROPEN;
381 // if ((ch >= 'a' && ch <= 'z')
382 // || (ch >= 'A' && ch <= 'Z')
388 // if (ch >= '0' && ch <= '9') {
393 // if (str.length() > chIndx) {
394 // if (str.charAt(chIndx) == '/') {
397 // // read comment until end of line:
398 // while ((str.length() > chIndx)
399 // && (ch != '\n')) {
400 // ch = str.charAt(chIndx++);
402 // ch2 = str.charAt(chIndx);
405 // token = TokenNameHTML;
416 // } else if (str.charAt(chIndx) == '*') {
418 // // multi line comment:
419 // while (str.length() > chIndx) {
420 // if (str.charAt(chIndx) == '*'
421 // && (str.length() > (chIndx + 1))
422 // && str.charAt(chIndx + 1) == '/') {
426 // ch = str.charAt(chIndx++);
429 // columnCount = chIndx;
435 // } else if (ch == '#') {
436 // // read comment until end of line:
437 // while ((str.length() > chIndx) && (ch != '\n')) {
438 // ch = str.charAt(chIndx++);
440 // ch2 = str.charAt(chIndx);
443 // token = TokenNameHTML;
454 // } else if (ch == '"') {
457 // TokenNameStringInterpolated,
458 // "Open string character '\"' at end of file.");
460 // } else if (ch == '\'') {
463 // TokenNameStringConstant,
464 // "Open string character \"'\" at end of file.");
466 // } else if (ch == '`') {
469 // TokenNameStringConstant,
470 // "Open string character \"`\" at end of file.");
472 // "Other string delimiters prefered (found \"`\").",
481 // token = TokenNameLPAREN;
485 // token = TokenNameRPAREN;
489 // token = TokenNameLBRACE;
493 // token = TokenNameRBRACE;
497 // token = TokenNameLBRACKET;
501 // token = TokenNameRBRACKET;
505 // token = TokenNameCOMMA;
509 // token = TokenNameQUESTION;
510 // if (str.length() > chIndx) {
511 // if (str.charAt(chIndx) == '>') {
513 // token = TokenNameHTML;
523 // token = TokenNameAT;
526 // token = TokenNameTWIDDLE;
527 // if (str.length() > chIndx) {
528 // if (str.charAt(chIndx) == '=') {
530 // token = TokenNameTWIDDLE_EQUAL;
537 // token = TokenNameDOT;
538 // if (str.length() > chIndx) {
539 // if (str.charAt(chIndx) == '=') {
541 // token = TokenNameDOT_EQUAL;
549 // token = TokenNameStringLiteral;
553 // token = TokenNameREMAINDER;
554 // if (str.length() > chIndx) {
555 // if (str.charAt(chIndx) == '=') {
557 // token = TokenNameREMAINDER_EQUAL;
564 // token = TokenNameSEMICOLON;
568 // token = TokenNameXOR;
569 // if (str.length() > chIndx) {
570 // if (str.charAt(chIndx) == '=') {
572 // token = TokenNameXOR_EQUAL;
579 // token = TokenNameDIVIDE;
581 // if (str.length() > chIndx) {
582 // if (str.charAt(chIndx) == '=') {
584 // token = TokenNameDIVIDE_EQUAL;
592 // token = TokenNameMULTIPLY;
593 // if (str.length() > chIndx) {
594 // if (str.charAt(chIndx) == '*') {
596 // token = TokenNameXOR;
600 // if (str.charAt(chIndx) == '=') {
602 // token = TokenNameMULTIPLY_EQUAL;
610 // token = TokenNamePLUS;
611 // if (str.length() > chIndx) {
612 // if (str.charAt(chIndx) == '+') {
614 // token = TokenNamePLUS_PLUS;
618 // if (str.charAt(chIndx) == '=') {
620 // token = TokenNamePLUS_EQUAL;
627 // token = TokenNameMINUS;
628 // if (str.length() > chIndx) {
629 // if (str.charAt(chIndx) == '-') {
631 // token = TokenNameMINUS_MINUS;
635 // if (str.charAt(chIndx) == '=') {
637 // token = TokenNameMINUS_EQUAL;
641 // if (str.charAt(chIndx) == '>') {
643 // token = TokenNameMINUS_GREATER;
651 // token = TokenNameEQUAL;
653 // if (str.length() > chIndx) {
654 // ch = str.charAt(chIndx);
658 // token = TokenNameEQUAL_EQUAL;
659 // if (str.length() > chIndx) {
660 // ch = str.charAt(chIndx);
665 // TokenNameEQUAL_EQUAL_EQUAL;
672 // token = TokenNameEQUAL_GREATER;
680 // token = TokenNameNOT;
682 // if (str.length() > chIndx) {
683 // if (str.charAt(chIndx) == '=') {
685 // token = TokenNameNOT_EQUAL;
686 // if (str.length() > chIndx) {
687 // ch = str.charAt(chIndx);
692 // TokenNameNOT_EQUAL_EQUAL;
701 // token = TokenNameGREATER;
703 // if (str.length() > chIndx) {
704 // if (str.charAt(chIndx) == '=') {
706 // token = TokenNameGREATER_EQUAL;
709 // if (str.charAt(chIndx) == '>') {
711 // token = TokenNameRIGHT_SHIFT;
712 // if (str.length() > chIndx) {
713 // if (str.charAt(chIndx) == '=') {
716 // TokenNameRIGHT_SHIFT_EQUAL;
726 // token = TokenNameLESS;
728 // if (str.length() > chIndx) {
729 // if (str.charAt(chIndx) == '=') {
731 // token = TokenNameLESS_EQUAL;
735 // if (str.charAt(chIndx) == '<') {
737 // token = TokenNameLEFT_SHIFT;
738 // if (str.charAt(chIndx) == '<') {
740 // int startRow = rowCount;
741 // if (str.length() > chIndx) {
743 // ch = str.charAt(++chIndx);
744 // if ((ch >= 'a' && ch <= 'z')
745 // || (ch >= 'A' && ch <= 'Z')
750 // TokenNameStringConstant;
751 // while (str.length()
767 // .equals(identifier)) {
779 // "Open heredoc syntax after operator '<<<'.",
781 // } else if (str.charAt(chIndx) == '=') {
783 // token = TokenNameLEFT_SHIFT_EQUAL;
793 // token = TokenNameOR;
795 // if (str.length() > chIndx) {
796 // if (str.charAt(chIndx) == '|') {
798 // token = TokenNameOR_OR;
801 // if (str.charAt(chIndx) == '=') {
803 // token = TokenNameOR_EQUAL;
810 // token = TokenNameAND;
811 // if (str.length() > chIndx) {
812 // if (str.charAt(chIndx) == '&') {
814 // token = TokenNameAND_AND;
817 // if (str.charAt(chIndx) == '=') {
819 // token = TokenNameAND_EQUAL;
827 // token = TokenNameCOLON;
828 // if (str.length() > chIndx) {
829 // if (str.charAt(chIndx) == ':') {
831 // token = TokenNameCOLON_COLON;
836 // // token = TokenNameHASH;
840 // // token = TokenNameAT;
845 // "unexpected character: '" + ch + "'");
848 // if (token == TokenNameERROR) {
849 // throwSyntaxError("token not found");
856 // } catch (StringIndexOutOfBoundsException e) {
857 // // catched from charAt
860 // chIndx = str.length() + 1;
862 // token = TokenNameEOF;
865 // // if (phpList != null) {
866 // // if (currentPHPString < phpList.size()) {
867 // // token = TokenNameUNDEFINED;
868 // // temp = (PHPString) phpList.get(currentPHPString++);
869 // // this.str = temp.getPHPString();
870 // // this.token = TokenNameEOF;
871 // // this.chIndx = 0;
872 // // this.rowCount = temp.getLineNumber();
873 // // this.columnCount = 0;
874 // // getNextToken();
877 // // token = TokenNameUNDEFINED;
884 // * Get an identifier.
886 // private void getIdentifier() {
887 // // StringBuffer ident = new StringBuffer();
888 // int startPosition = chIndx - 1;
889 // // ident.append(ch);
892 // // attention recursive call:
894 // token = TokenNameVariable;
897 // token = TokenNameIdentifier;
902 // //this will read the buffer until the next character is a forbidden character for identifier
903 // while ((ch >= 'a' && ch <= 'z')
904 // || (ch >= 'A' && ch <= 'Z')
905 // || (ch >= '0' && ch <= '9')
907 // // ident.append(ch);
910 // int endPosition = chIndx--;
911 // int length = (--endPosition) - startPosition;
913 // identifier = str.substring(startPosition, endPosition);
914 // // System.out.println(identifier);
916 // // determine if this identitfer is a keyword
917 // // @todo improve this in future version
918 // Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
920 // token = i.intValue();
926 * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
927 * value {@link Parser#TokenNameDOUBLE_NUMBER}<br />
928 * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
929 * value {@link Parser#TokenNameINT_NUMBER}
931 // private void getNumber() {
932 // StringBuffer inum = new StringBuffer();
934 // int numFormat = 10;
936 // // save first digit
937 // char firstCh = ch;
941 // // determine number conversions:
942 // if (firstCh == '0') {
971 // if (numFormat == 16) {
972 // while ((ch >= '0' && ch <= '9')
973 // || (ch >= 'a' && ch <= 'f')
974 // || (ch >= 'A' && ch <= 'F')) {
979 // while ((ch >= '0' && ch <= '9')
983 // if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
984 // if (ch == '.' && dFlag != ' ') {
987 // if ((dFlag == 'E') || (dFlag == 'e')) {
993 // if ((ch == '-') || (ch == '+')) {
1006 // if (dFlag != ' ') {
1007 // doubleNumber = new Double(inum.toString());
1008 // token = TokenNameDoubleLiteral;
1011 // longNumber = Long.valueOf(inum.toString(), numFormat);
1012 // token = TokenNameIntegerLiteral;
1016 // } catch (Throwable e) {
1017 // throwSyntaxError("Number format error: " + inum.toString());
1023 // * @param openChar the opening char ('\'', '"', '`')
1024 // * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
1025 // * @param errorMsg the error message in case of parse error in the string
1027 // private void getString(
1028 // final char openChar,
1029 // final int typeString,
1030 // final String errorMsg) {
1031 // StringBuffer sBuffer = new StringBuffer();
1032 // boolean openString = true;
1033 // int startRow = rowCount;
1034 // while (str.length() > chIndx) {
1035 // ch = str.charAt(chIndx++);
1036 // if (ch == '\\') {
1037 // sBuffer.append(ch);
1038 // if (str.length() > chIndx) {
1039 // ch = str.charAt(chIndx++);
1040 // sBuffer.append(ch);
1042 // } else if (ch == openChar) {
1043 // openString = false;
1045 // } else if (ch == '\n') {
1047 // columnCount = chIndx;
1049 // sBuffer.append(ch);
1052 // if (openString) {
1053 // if (typeString == TokenNameStringConstant) {
1054 // throwSyntaxError(errorMsg, startRow);
1056 // throwSyntaxError(errorMsg);
1059 // token = typeString;
1060 // stringValue = sBuffer.toString();
1063 // public void htmlParserTester(String input) {
1064 // int lineNumber = 1;
1065 // int startLineNumber = 1;
1066 // int startIndex = 0;
1069 // boolean phpMode = false;
1070 // boolean phpFound = false;
1072 // phpList = new ArrayList();
1073 // currentPHPString = 0;
1077 // while (i < input.length()) {
1078 // ch = input.charAt(i++);
1079 // if (ch == '\n') {
1082 // if ((!phpMode) && ch == '<') {
1083 // ch2 = input.charAt(i++);
1084 // if (ch2 == '?') {
1085 // ch2 = input.charAt(i++);
1086 // if (Character.isWhitespace(ch2)) {
1091 // startLineNumber = lineNumber;
1093 // } else if (ch2 == 'p') {
1094 // ch2 = input.charAt(i++);
1095 // if (ch2 == 'h') {
1096 // ch2 = input.charAt(i++);
1097 // if (ch2 == 'p') {
1101 // startLineNumber = lineNumber;
1107 // } else if (ch2 == 'P') {
1108 // ch2 = input.charAt(i++);
1109 // if (ch2 == 'H') {
1110 // ch2 = input.charAt(i++);
1111 // if (ch2 == 'P') {
1115 // startLineNumber = lineNumber;
1128 // if (ch == '/' && i < input.length()) {
1129 // ch2 = input.charAt(i++);
1130 // if (ch2 == '/') {
1131 // while (i < input.length()) {
1132 // ch = input.charAt(i++);
1133 // if (ch == '?' && i < input.length()) {
1134 // ch2 = input.charAt(i++);
1135 // if (ch2 == '>') {
1143 // startLineNumber));
1147 // } else if (ch == '\n') {
1153 // } else if (ch2 == '*') {
1154 // // multi-line comment
1155 // while (i < input.length()) {
1156 // ch = input.charAt(i++);
1157 // if (ch == '\n') {
1159 // } else if (ch == '*' && i < input.length()) {
1160 // ch2 = input.charAt(i++);
1161 // if (ch2 == '/') {
1171 // } else if (ch == '#') {
1172 // while (i < input.length()) {
1173 // ch = input.charAt(i++);
1174 // if (ch == '?' && i < input.length()) {
1175 // ch2 = input.charAt(i++);
1176 // if (ch2 == '>') {
1181 // input.substring(startIndex, i - 2),
1182 // startLineNumber));
1186 // } else if (ch == '\n') {
1192 // } else if (ch == '"') {
1194 // while (i < input.length()) {
1195 // ch = input.charAt(i++);
1196 // if (ch == '\n') {
1199 // ch == '\\' && i < input.length()) { // escape
1201 // } else if (ch == '"') {
1206 // } else if (ch == '\'') {
1208 // while (i < input.length()) {
1209 // ch = input.charAt(i++);
1210 // if (ch == '\n') {
1213 // ch == '\\' && i < input.length()) { // escape
1215 // } else if (ch == '\'') {
1222 // if (ch == '?' && i < input.length()) {
1223 // ch2 = input.charAt(i++);
1224 // if (ch2 == '>') {
1229 // input.substring(startIndex, i - 2),
1230 // startLineNumber));
1240 // "No PHP source code found.",
1246 // "Open PHP tag at end of file.",
1251 // input.substring(startIndex, i - 2),
1252 // startLineNumber));
1254 // // for (int j=0;j<phpList.size();j++) {
1255 // // String temp = ((PHPString)phpList.get(j)).getPHPString();
1256 // // int startIndx = temp.length()-10;
1257 // // if (startIndx<0) {
1258 // // startIndx = 0;
1260 // // System.out.println(temp.substring(startIndx)+"?>");
1262 // phpParserTester(null, 1);
1263 // // PHPString temp;
1264 // // for(int j=0;j<phpList.size();j++) {
1265 // // temp = (PHPString) phpList.get(j);
1266 // // parser.start(temp.getPHPString(), temp.getLineNumber());
1269 // } catch (CoreException e) {
1273 public void phpParserTester(String s, int rowCount) throws CoreException {
1276 if (phpList.size() != 0) {
1277 this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
1280 this.token = TokenNameEOF;
1282 // this.rowCount = rowCount;
1283 // this.columnCount = 0;
1284 this.phpEnd = false;
1285 this.phpMode = true;
1286 scanner.setSource(s.toCharArray());
1287 scanner.setPHPMode(true);
1291 if (token != TokenNameEOF && token != TokenNameERROR) {
1294 if (token != TokenNameEOF && token != TokenNameERROR) {
1295 if (token == TokenNameRPAREN) {
1296 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1298 if (token == TokenNameRBRACE) {
1299 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1301 if (token == TokenNameRBRACKET) {
1302 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1305 if (token == TokenNameLPAREN) {
1306 throwSyntaxError("Read character '('; end-of-file not reached.");
1308 if (token == TokenNameLBRACE) {
1309 throwSyntaxError("Read character '{'; end-of-file not reached.");
1311 if (token == TokenNameLBRACKET) {
1312 throwSyntaxError("Read character '['; end-of-file not reached.");
1315 throwSyntaxError("End-of-file not reached.");
1318 } catch (SyntaxError err) {
1322 // setMarker(err.getMessage(), err.getLine(), ERROR);
1325 scanner.getCurrentTokenStartPosition(),
1326 scanner.getCurrentTokenEndPosition(),
1329 // if an error occured,
1330 // try to find keywords 'class' or 'function'
1331 // to parse the rest of the string
1332 while (token != TokenNameEOF && token != TokenNameERROR) {
1333 if (token == TokenNameclass || token == TokenNamefunction) {
1338 if (token == TokenNameEOF || token == TokenNameERROR) {
1347 * Parses a string with php tags
1348 * i.e. '<body> <?php phpinfo() ?> </body>'
1350 public void parse(String s) throws CoreException {
1352 this.token = TokenNameEOF;
1354 // this.rowCount = 1;
1355 // this.columnCount = 0;
1356 this.phpEnd = false;
1357 this.phpMode = false;
1358 /* scanner initialization */
1359 scanner.setSource(s.toCharArray());
1360 scanner.setPHPMode(false);
1364 if (token != TokenNameEOF && token != TokenNameERROR) {
1367 if (token != TokenNameEOF && token != TokenNameERROR) {
1368 if (token == TokenNameRPAREN) {
1369 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1371 if (token == TokenNameRBRACE) {
1372 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1374 if (token == TokenNameRBRACKET) {
1375 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1378 if (token == TokenNameLPAREN) {
1379 throwSyntaxError("Read character '('; end-of-file not reached.");
1381 if (token == TokenNameLBRACE) {
1382 throwSyntaxError("Read character '{'; end-of-file not reached.");
1384 if (token == TokenNameLBRACKET) {
1385 throwSyntaxError("Read character '['; end-of-file not reached.");
1388 throwSyntaxError("End-of-file not reached.");
1391 } catch (SyntaxError sytaxErr1) {
1392 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
1394 sytaxErr1.getMessage(),
1395 scanner.getCurrentTokenStartPosition(),
1396 scanner.getCurrentTokenEndPosition(),
1399 // if an error occured,
1400 // try to find keywords 'class' or 'function'
1401 // to parse the rest of the string
1402 while (token != TokenNameEOF && token != TokenNameERROR) {
1403 if (token == TokenNameclass || token == TokenNamefunction) {
1408 if (token == TokenNameEOF || token == TokenNameERROR) {
1411 } catch (SyntaxError sytaxErr2) {
1412 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
1414 sytaxErr2.getMessage(),
1415 scanner.getCurrentTokenStartPosition(),
1416 scanner.getCurrentTokenEndPosition(),
1425 public PHPOutlineInfo parseInfo(Object parent, String s) {
1426 PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
1427 // Stack stack = new Stack();
1428 // stack.push(outlineInfo.getDeclarations());
1431 this.token = TokenNameEOF;
1433 // this.rowCount = 1;
1434 // this.columnCount = 0;
1435 this.phpEnd = false;
1436 this.phpMode = false;
1437 scanner.setSource(s.toCharArray());
1438 scanner.setPHPMode(false);
1442 parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
1443 } catch (CoreException e) {
1448 private void parseDeclarations(
1449 PHPOutlineInfo outlineInfo,
1450 PHPSegmentWithChildren current,
1453 // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
1454 PHPSegmentWithChildren temp;
1457 IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
1459 while (token != TokenNameEOF && token != TokenNameERROR) {
1460 if (token == TokenNameVariable) {
1461 ident = scanner.getCurrentIdentifierSource();
1462 outlineInfo.addVariable(new String(ident));
1464 } else if (token == TokenNamevar) {
1466 if (token == TokenNameVariable
1467 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
1468 ident = scanner.getCurrentIdentifierSource();
1469 String variableName = new String(ident);
1470 outlineInfo.addVariable(variableName);
1472 if (token != TokenNameSEMICOLON) {
1475 ident = scanner.getCurrentTokenSource();
1476 if (token > TokenNameKEYWORD) {
1477 current.add(new PHPVarDeclaration(current, variableName,
1478 // chIndx - ident.length,
1479 scanner.getCurrentTokenStartPosition(), new String(ident)));
1482 case TokenNameVariable :
1483 current.add(new PHPVarDeclaration(current, variableName,
1484 // chIndx - ident.length,
1485 scanner.getCurrentTokenStartPosition(), new String(ident)));
1487 case TokenNameIdentifier :
1488 current.add(new PHPVarDeclaration(current, variableName,
1489 // chIndx - ident.length,
1490 scanner.getCurrentTokenStartPosition(), new String(ident)));
1492 case TokenNameDoubleLiteral :
1494 .add(new PHPVarDeclaration(
1496 variableName + doubleNumber,
1497 // chIndx - ident.length,
1498 scanner.getCurrentTokenStartPosition(), new String(ident)));
1500 case TokenNameIntegerLiteral :
1501 current.add(new PHPVarDeclaration(current, variableName,
1502 // chIndx - ident.length,
1503 scanner.getCurrentTokenStartPosition(), new String(ident)));
1505 case TokenNameStringInterpolated :
1506 case TokenNameStringLiteral :
1507 current.add(new PHPVarDeclaration(current, variableName,
1508 // chIndx - ident.length,
1509 scanner.getCurrentTokenStartPosition(), new String(ident)));
1511 case TokenNameStringConstant :
1512 current.add(new PHPVarDeclaration(current, variableName,
1513 // chIndx - ident.length,
1514 scanner.getCurrentTokenStartPosition(), new String(ident)));
1517 current.add(new PHPVarDeclaration(current, variableName,
1518 // chIndx - ident.length
1519 scanner.getCurrentTokenStartPosition()));
1525 ident = scanner.getCurrentIdentifierSource();
1527 current.add(new PHPVarDeclaration(current, variableName,
1528 // chIndx - ident.length
1529 scanner.getCurrentTokenStartPosition()));
1532 } else if (token == TokenNamefunction) {
1534 if (token == TokenNameAND) {
1537 if (token == TokenNameIdentifier
1538 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
1539 ident = scanner.getCurrentIdentifierSource();
1540 outlineInfo.addVariable(new String(ident));
1541 temp = new PHPFunctionDeclaration(current, new String(ident),
1542 // chIndx - ident.length
1543 scanner.getCurrentTokenStartPosition());
1546 parseDeclarations(outlineInfo, temp, true);
1548 } else if (token == TokenNameclass) {
1550 if (token == TokenNameIdentifier
1551 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
1552 ident = scanner.getCurrentIdentifierSource();
1553 outlineInfo.addVariable(new String(ident));
1554 temp = new PHPClassDeclaration(current, new String(ident),
1555 // chIndx - ident.len
1556 scanner.getCurrentTokenStartPosition());
1558 // stack.push(temp);
1561 //skip tokens for classname, extends and others until we have the opening '{'
1562 while (token != TokenNameLBRACE
1563 && token != TokenNameEOF
1564 && token != TokenNameERROR) {
1567 parseDeclarations(outlineInfo, temp, true);
1570 } else if (token == TokenNameLBRACE) {
1573 } else if (token == TokenNameRBRACE) {
1576 if (counter == 0 && goBack) {
1580 token == TokenNamerequire
1581 || token == TokenNamerequire_once
1582 || token == TokenNameinclude
1583 || token == TokenNameinclude_once) {
1584 ident = scanner.getCurrentTokenSource();
1587 int startPosition = scanner.getCurrentTokenStartPosition();
1589 char[] expr = scanner.getCurrentTokenSource(startPosition);
1590 outlineInfo.addVariable(new String(ident));
1591 current.add(new PHPReqIncDeclaration(current, new String(ident),
1592 // chIndx - ident.length,
1593 startPosition, new String(expr)));
1599 } catch (CoreException e) {
1600 } catch (SyntaxError sytaxErr) {
1602 // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
1604 sytaxErr.getMessage(),
1605 scanner.getCurrentTokenStartPosition(),
1606 scanner.getCurrentTokenEndPosition(),
1608 } catch (CoreException e) {
1613 private void statementList() throws CoreException {
1616 if ((token == TokenNameRBRACE)
1617 || (token == TokenNamecase)
1618 || (token == TokenNamedefault)
1619 || (token == TokenNameelseif)
1620 || (token == TokenNameendif)
1621 || (token == TokenNameendfor)
1622 || (token == TokenNameendforeach)
1623 || (token == TokenNameendwhile)
1624 || (token == TokenNameendswitch)
1625 || (token == TokenNameEOF)
1626 || (token == TokenNameERROR)) {
1632 private void compoundStatement() throws CoreException {
1633 // '{' [statement-list] '}'
1634 if (token == TokenNameLBRACE) {
1637 throwSyntaxError("'{' expected in compound-statement.");
1639 if (token != TokenNameRBRACE) {
1642 if (token == TokenNameRBRACE) {
1645 throwSyntaxError("'}' expected in compound-statement.");
1649 private void statement() throws CoreException {
1650 // if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
1651 // char[] ident = scanner.getCurrentIdentifierSource();
1652 // String keyword = new String(ident);
1653 if (token == TokenNameinclude || token == TokenNameinclude_once) {
1656 if (token == TokenNameSEMICOLON) {
1659 if (token != TokenNameStopPHP) {
1660 throwSyntaxError("';' character after 'include' or 'include_once' expected.");
1665 } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
1669 if (token == TokenNameSEMICOLON) {
1672 if (token != TokenNameStopPHP) {
1673 throwSyntaxError("';' character after 'require' or 'require_once' expected.");
1678 } else if (token == TokenNameif) {
1680 if (token == TokenNameLPAREN) {
1683 throwSyntaxError("'(' expected after 'if' keyword.");
1686 if (token == TokenNameRPAREN) {
1689 throwSyntaxError("')' expected after 'if' condition.");
1694 } else if (token == TokenNameswitch) {
1696 if (token == TokenNameLPAREN) {
1699 throwSyntaxError("'(' expected after 'switch' keyword.");
1702 if (token == TokenNameRPAREN) {
1705 throwSyntaxError("')' expected after 'switch' condition.");
1709 } else if (token == TokenNamefor) {
1711 if (token == TokenNameLPAREN) {
1714 throwSyntaxError("'(' expected after 'for' keyword.");
1716 if (token == TokenNameSEMICOLON) {
1720 if (token == TokenNameSEMICOLON) {
1723 throwSyntaxError("';' expected after 'for'.");
1726 if (token == TokenNameSEMICOLON) {
1730 if (token == TokenNameSEMICOLON) {
1733 throwSyntaxError("';' expected after 'for'.");
1736 if (token == TokenNameRPAREN) {
1740 if (token == TokenNameRPAREN) {
1743 throwSyntaxError("')' expected after 'for'.");
1748 } else if (token == TokenNamewhile) {
1750 if (token == TokenNameLPAREN) {
1753 throwSyntaxError("'(' expected after 'while' keyword.");
1756 if (token == TokenNameRPAREN) {
1759 throwSyntaxError("')' expected after 'while' condition.");
1763 } else if (token == TokenNamedo) {
1765 if (token == TokenNameLBRACE) {
1768 throwSyntaxError("'{' expected after 'do' keyword.");
1770 if (token != TokenNameRBRACE) {
1773 if (token == TokenNameRBRACE) {
1776 throwSyntaxError("'}' expected after 'do' keyword.");
1778 if (token == TokenNamewhile) {
1780 if (token == TokenNameLPAREN) {
1783 throwSyntaxError("'(' expected after 'while' keyword.");
1786 if (token == TokenNameRPAREN) {
1789 throwSyntaxError("')' expected after 'while' condition.");
1792 throwSyntaxError("'while' expected after 'do' keyword.");
1794 if (token == TokenNameSEMICOLON) {
1797 if (token != TokenNameStopPHP) {
1798 throwSyntaxError("';' expected after do-while statement.");
1803 } else if (token == TokenNameforeach) {
1805 if (token == TokenNameLPAREN) {
1808 throwSyntaxError("'(' expected after 'foreach' keyword.");
1811 if (token == TokenNameas) {
1814 throwSyntaxError("'as' expected after 'foreach' exxpression.");
1817 if (token == TokenNameEQUAL_GREATER) {
1821 if (token == TokenNameRPAREN) {
1824 throwSyntaxError("')' expected after 'foreach' expression.");
1830 token == TokenNamecontinue
1831 || token == TokenNamebreak
1832 || token == TokenNamereturn) {
1834 if (token != TokenNameSEMICOLON) {
1837 if (token == TokenNameSEMICOLON) {
1840 if (token != TokenNameStopPHP) {
1841 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1847 } else if (token == TokenNameecho) {
1850 if (token == TokenNameSEMICOLON) {
1853 if (token != TokenNameStopPHP) {
1854 throwSyntaxError("';' expected after 'echo' statement.");
1859 // } else if (token == TokenNameprint) {
1862 // if (token == TokenNameSEMICOLON) {
1865 // if (token != TokenNameStopPHP) {
1866 // throwSyntaxError("';' expected after 'print' statement.");
1872 } else if (token == TokenNameglobal || token == TokenNamestatic) {
1875 if (token == TokenNameSEMICOLON) {
1878 if (token != TokenNameStopPHP) {
1879 throwSyntaxError("';' expected after 'global' or 'static' statement.");
1885 // } else if (token == TokenNameunset) {
1887 // if (token == TokenNameARGOPEN) {
1890 // throwSyntaxError("'(' expected after 'unset' keyword.");
1893 // if (token == TokenNameARGCLOSE) {
1896 // throwSyntaxError("')' expected after 'unset' statement.");
1898 // if (token == TokenNameSEMICOLON) {
1901 // if (token != TokenNameStopPHP) {
1902 // throwSyntaxError("';' expected after 'unset' statement.");
1908 // } else if (token == TokenNameexit || token == TokenNamedie) {
1910 // if (token != TokenNameSEMICOLON) {
1913 // if (token == TokenNameSEMICOLON) {
1916 // if (token != TokenNameStopPHP) {
1917 // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
1923 } else if (token == TokenNamedefine) {
1925 if (token == TokenNameLPAREN) {
1928 throwSyntaxError("'(' expected after 'define' keyword.");
1931 if (token == TokenNameCOMMA) {
1934 throwSyntaxError("',' expected after first 'define' constant.");
1937 if (token == TokenNameCOMMA) {
1941 if (token == TokenNameRPAREN) {
1944 throwSyntaxError("')' expected after 'define' statement.");
1946 if (token == TokenNameSEMICOLON) {
1949 if (token != TokenNameStopPHP) {
1950 throwSyntaxError("';' expected after 'define' statement.");
1955 } else if (token == TokenNamefunction) {
1957 functionDefinition();
1959 } else if (token == TokenNameclass) {
1965 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
1966 } else if (token == TokenNameLBRACE) {
1967 // compoundStatement
1969 if (token != TokenNameRBRACE) {
1972 if (token == TokenNameRBRACE) {
1976 throwSyntaxError("'}' expected.");
1979 if (token != TokenNameSEMICOLON) {
1982 if (token == TokenNameSEMICOLON) {
1986 if (token != TokenNameStopPHP && token != TokenNameEOF) {
1988 "';' expected after expression (Found token: "
1989 + scanner.toStringAction(token)
1997 private void classDeclarator() throws CoreException {
1999 //identifier 'extends' identifier
2000 if (token == TokenNameIdentifier) {
2002 if (token == TokenNameextends) {
2004 if (token == TokenNameIdentifier) {
2007 throwSyntaxError("Class name expected after keyword 'extends'.");
2011 throwSyntaxError("Class name expected after keyword 'class'.");
2015 private void classBody() throws CoreException {
2016 //'{' [class-element-list] '}'
2017 if (token == TokenNameLBRACE) {
2019 if (token != TokenNameRBRACE) {
2022 if (token == TokenNameRBRACE) {
2025 throwSyntaxError("'}' expected at end of class body.");
2028 throwSyntaxError("'{' expected at start of class body.");
2032 private void classElementList() throws CoreException {
2035 } while (token == TokenNamefunction || token == TokenNamevar);
2038 private void classElement() throws CoreException {
2040 //function-definition
2041 if (token == TokenNamefunction) {
2043 functionDefinition();
2044 } else if (token == TokenNamevar) {
2048 throwSyntaxError("'function' or 'var' expected.");
2052 private void classProperty() throws CoreException {
2053 //'var' variable ';'
2054 //'var' variable '=' constant ';'
2056 if (token == TokenNameVariable) {
2058 if (token == TokenNameEQUAL) {
2063 throwSyntaxError("Variable expected after keyword 'var'.");
2065 if (token != TokenNameCOMMA) {
2070 if (token == TokenNameSEMICOLON) {
2073 throwSyntaxError("';' expected after variable declaration.");
2077 private void functionDefinition() throws CoreException {
2078 functionDeclarator();
2079 compoundStatement();
2082 private void functionDeclarator() throws CoreException {
2083 //identifier '(' [parameter-list] ')'
2084 if (token == TokenNameAND) {
2087 if (token == TokenNameIdentifier) {
2089 if (token == TokenNameLPAREN) {
2092 throwSyntaxError("'(' expected in function declaration.");
2094 if (token != TokenNameRPAREN) {
2097 if (token != TokenNameRPAREN) {
2098 throwSyntaxError("')' expected in function declaration.");
2105 private void parameterList() throws CoreException {
2106 //parameter-declaration
2107 //parameter-list ',' parameter-declaration
2109 parameterDeclaration();
2110 if (token != TokenNameCOMMA) {
2117 private void parameterDeclaration() throws CoreException {
2119 //variable-reference
2120 if (token == TokenNameAND) {
2122 if (token == TokenNameVariable) {
2125 throwSyntaxError("Variable expected after reference operator '&'.");
2128 //variable '=' constant
2129 if (token == TokenNameVariable) {
2131 if (token == TokenNameEQUAL) {
2139 private void labeledStatementList() throws CoreException {
2140 if (token != TokenNamecase && token != TokenNamedefault) {
2141 throwSyntaxError("'case' or 'default' expected.");
2144 if (token == TokenNamecase) {
2147 if (token == TokenNameCOLON) {
2149 if (token == TokenNamecase
2150 || token == TokenNamedefault) { // empty case statement ?
2154 } else if (token == TokenNameSEMICOLON) {
2156 // "':' expected after 'case' keyword (Found token: "
2157 // + scanner.toStringAction(token)
2162 "':' expected after 'case' keyword (Found token: "
2163 + scanner.toStringAction(token)
2165 scanner.getCurrentTokenStartPosition(),
2166 scanner.getCurrentTokenEndPosition(),
2169 if (token == TokenNamecase) { // empty case statement ?
2175 "':' character after 'case' constant expected (Found token: "
2176 + scanner.toStringAction(token)
2179 } else { // TokenNamedefault
2181 if (token == TokenNameCOLON) {
2185 throwSyntaxError("':' character after 'default' expected.");
2188 } while (token == TokenNamecase || token == TokenNamedefault);
2191 // public void labeledStatement() {
2192 // if (token == TokenNamecase) {
2195 // if (token == TokenNameDDOT) {
2199 // throwSyntaxError("':' character after 'case' constant expected.");
2202 // } else if (token == TokenNamedefault) {
2204 // if (token == TokenNameDDOT) {
2208 // throwSyntaxError("':' character after 'default' expected.");
2214 // public void expressionStatement() {
2217 // private void inclusionStatement() {
2220 // public void compoundStatement() {
2223 // public void selectionStatement() {
2226 // public void iterationStatement() {
2229 // public void jumpStatement() {
2232 // public void outputStatement() {
2235 // public void scopeStatement() {
2238 // public void flowStatement() {
2241 // public void definitionStatement() {
2244 private void ifStatement() throws CoreException {
2245 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
2246 if (token == TokenNameCOLON) {
2250 case TokenNameelse :
2252 if (token == TokenNameCOLON) {
2256 if (token == TokenNameif) { //'else if'
2258 elseifStatementList();
2260 throwSyntaxError("':' expected after 'else'.");
2264 case TokenNameelseif :
2266 elseifStatementList();
2270 if (token != TokenNameendif) {
2271 throwSyntaxError("'endif' expected.");
2274 if (token != TokenNameSEMICOLON) {
2275 throwSyntaxError("';' expected after if-statement.");
2279 // statement [else-statement]
2281 if (token == TokenNameelseif) {
2283 if (token == TokenNameLPAREN) {
2286 throwSyntaxError("'(' expected after 'elseif' keyword.");
2289 if (token == TokenNameRPAREN) {
2292 throwSyntaxError("')' expected after 'elseif' condition.");
2295 } else if (token == TokenNameelse) {
2302 private void elseifStatementList() throws CoreException {
2306 case TokenNameelse :
2308 if (token == TokenNameCOLON) {
2313 if (token == TokenNameif) { //'else if'
2316 throwSyntaxError("':' expected after 'else'.");
2320 case TokenNameelseif :
2329 private void elseifStatement() throws CoreException {
2330 if (token == TokenNameLPAREN) {
2333 if (token != TokenNameLPAREN) {
2334 throwSyntaxError("')' expected in else-if-statement.");
2337 if (token != TokenNameCOLON) {
2338 throwSyntaxError("':' expected in else-if-statement.");
2345 private void switchStatement() throws CoreException {
2346 if (token == TokenNameCOLON) {
2347 // ':' [labeled-statement-list] 'endswitch' ';'
2349 labeledStatementList();
2350 if (token != TokenNameendswitch) {
2351 throwSyntaxError("'endswitch' expected.");
2354 if (token != TokenNameSEMICOLON) {
2355 throwSyntaxError("';' expected after switch-statement.");
2359 // '{' [labeled-statement-list] '}'
2360 if (token != TokenNameLBRACE) {
2361 throwSyntaxError("'{' expected in switch statement.");
2364 if (token != TokenNameRBRACE) {
2365 labeledStatementList();
2367 if (token != TokenNameRBRACE) {
2368 throwSyntaxError("'}' expected in switch statement.");
2375 private void forStatement() throws CoreException {
2376 if (token == TokenNameCOLON) {
2379 if (token != TokenNameendfor) {
2380 throwSyntaxError("'endfor' expected.");
2383 if (token != TokenNameSEMICOLON) {
2384 throwSyntaxError("';' expected after for-statement.");
2392 private void whileStatement() throws CoreException {
2393 // ':' statement-list 'endwhile' ';'
2394 if (token == TokenNameCOLON) {
2397 if (token != TokenNameendwhile) {
2398 throwSyntaxError("'endwhile' expected.");
2401 if (token != TokenNameSEMICOLON) {
2402 throwSyntaxError("';' expected after while-statement.");
2410 private void foreachStatement() throws CoreException {
2411 if (token == TokenNameCOLON) {
2414 if (token != TokenNameendforeach) {
2415 throwSyntaxError("'endforeach' expected.");
2418 if (token != TokenNameSEMICOLON) {
2419 throwSyntaxError("';' expected after foreach-statement.");
2427 private void exitStatus() throws CoreException {
2428 if (token == TokenNameLPAREN) {
2431 throwSyntaxError("'(' expected in 'exit-status'.");
2433 if (token != TokenNameRPAREN) {
2436 if (token == TokenNameRPAREN) {
2439 throwSyntaxError("')' expected after 'exit-status'.");
2443 private void expressionList() throws CoreException {
2446 if (token == TokenNameCOMMA) {
2454 private void expression() throws CoreException {
2455 //todo: find a better way to get the expression
2456 // expression = new StringBuffer();
2457 // for (int i = chIndx; i < str.length(); i++) {
2458 // if (str.charAt(i) == ';') {
2461 // expression.append(str.charAt(i));
2464 // if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
2467 logicalinclusiveorExpression();
2468 // while (token != TokenNameSEMICOLON) {
2474 private void postfixExpression() throws CoreException {
2477 boolean castFlag = false;
2483 case TokenNamenull :
2486 case TokenNamefalse :
2489 case TokenNametrue :
2492 case TokenNameStringConstant :
2495 case TokenNameHEREDOC :
2496 case TokenNameStringInterpolated :
2497 case TokenNameStringLiteral :
2500 case TokenNameLPAREN :
2502 if (token == TokenNameIdentifier) {
2503 // check if identifier is a type:
2504 // ident = identifier;
2505 ident = scanner.getCurrentIdentifierSource();
2506 String str = new String(ident).toLowerCase();
2507 for (int i = 0; i < PHP_TYPES.length; i++) {
2508 if (PHP_TYPES[i].equals(str)) {
2515 if (token != TokenNameRPAREN) {
2516 throwSyntaxError(") expected after cast-type '" + str + "'.");
2526 if (token != TokenNameRPAREN) {
2527 throwSyntaxError(") expected in postfix-expression.");
2531 case TokenNameDoubleLiteral :
2534 case TokenNameIntegerLiteral :
2537 case TokenNameDOLLAR_LBRACE :
2540 if (token != TokenNameRBRACE) {
2541 throwSyntaxError("'}' expected after indirect variable token '${'.");
2545 case TokenNameVariable :
2546 ident = scanner.getCurrentIdentifierSource();
2548 if (token == TokenNameLBRACE) {
2551 if (token != TokenNameRBRACE) {
2553 "'}' expected after variable '"
2555 + "' in variable-expression.");
2558 } else if (token == TokenNameLPAREN) {
2560 if (token != TokenNameRPAREN) {
2562 if (token != TokenNameRPAREN) {
2564 "')' expected after variable '"
2566 + "' in postfix-expression.");
2572 case TokenNameIdentifier :
2573 ident = scanner.getCurrentIdentifierSource();
2575 if (token == TokenNameLPAREN) {
2577 if (token != TokenNameRPAREN) {
2579 if (token != TokenNameRPAREN) {
2581 "')' expected after identifier '"
2583 + "' in postfix-expression."
2585 + scanner.toStringAction(token)
2592 case TokenNameprint :
2595 // if (token == TokenNameSEMICOLON) {
2598 // if (token != TokenNameStopPHP) {
2599 // throwSyntaxError("';' expected after 'print' statement.");
2604 case TokenNamelist :
2606 if (token == TokenNameLPAREN) {
2608 if (token == TokenNameCOMMA) {
2612 if (token != TokenNameRPAREN) {
2613 throwSyntaxError("')' expected after 'list' keyword.");
2616 // if (token == TokenNameSET) {
2618 // logicalinclusiveorExpression();
2621 throwSyntaxError("'(' expected after 'list' keyword.");
2624 // case TokenNameexit :
2626 // if (token != TokenNameSEMICOLON) {
2629 // if (token == TokenNameSEMICOLON) {
2632 // if (token != TokenNameStopPHP) {
2633 // throwSyntaxError("';' expected after 'exit' expression.");
2638 // case TokenNamedie :
2640 // if (token != TokenNameSEMICOLON) {
2643 // if (token == TokenNameSEMICOLON) {
2646 // if (token != TokenNameStopPHP) {
2647 // throwSyntaxError("';' expected after 'die' expression.");
2652 // case TokenNamearray :
2654 // if (token == TokenNameARGOPEN) {
2656 // if (token == TokenNameCOMMA) {
2659 // expressionList();
2660 // if (token != TokenNameARGCLOSE) {
2661 // throwSyntaxError("')' expected after 'list' keyword.");
2664 // if (token == TokenNameSET) {
2666 // logicalinclusiveorExpression();
2669 // throwSyntaxError("'(' expected after 'list' keyword.");
2673 boolean while_flag = true;
2676 case TokenNameLBRACKET :
2679 if (token != TokenNameRBRACKET) {
2680 throwSyntaxError("] expected in postfix-expression.");
2684 case TokenNameCOLON_COLON : // ::
2685 case TokenNameMINUS_GREATER : // ->
2687 if (token > TokenNameKEYWORD) {
2688 ident = scanner.getCurrentIdentifierSource();
2690 // "Avoid using keyword '"
2691 // + new String(ident)
2692 // + "' as variable name.",
2696 "Avoid using keyword '"
2698 + "' as variable name.",
2699 scanner.getCurrentTokenStartPosition(),
2700 scanner.getCurrentTokenEndPosition(),
2704 case TokenNameVariable :
2705 ident = scanner.getCurrentIdentifierSource();
2707 // if (token == TokenNameARGOPEN) {
2709 // expressionList();
2710 // if (token != TokenNameARGCLOSE) {
2711 // throwSyntaxError(") expected after variable '" + ident + "'.");
2716 case TokenNameIdentifier :
2717 //ident = scanner.getCurrentIdentifierSource();
2720 case TokenNameLBRACE :
2723 if (token != TokenNameRBRACE) {
2724 throwSyntaxError("} expected in postfix-expression.");
2729 throwSyntaxError("Syntax error after '->' token.");
2731 token == TokenNameLBRACKET
2732 || token == TokenNameLPAREN
2733 || token == TokenNameLBRACE) {
2734 if (token == TokenNameLBRACKET) {
2737 if (token != TokenNameRBRACKET) {
2738 throwSyntaxError("] expected after '->'.");
2742 if (token == TokenNameLPAREN) {
2745 if (token != TokenNameRPAREN) {
2746 throwSyntaxError(") expected after '->'.");
2750 if (token == TokenNameLBRACE) {
2753 if (token != TokenNameRBRACE) {
2754 throwSyntaxError("} expected after '->'.");
2760 case TokenNamePLUS_PLUS :
2763 case TokenNameMINUS_MINUS :
2774 private void unaryExpression() throws CoreException {
2776 case TokenNamePLUS_PLUS :
2780 case TokenNameMINUS_MINUS :
2784 // '@' '&' '*' '+' '-' '~' '!'
2793 case TokenNameMULTIPLY :
2797 case TokenNamePLUS :
2801 case TokenNameMINUS :
2805 case TokenNameTWIDDLE :
2814 postfixExpression();
2818 private void castExpression() throws CoreException {
2819 // if (token == TokenNameARGOPEN) {
2822 // if (token != TokenNameARGCLOSE) {
2823 // throwSyntaxError(") expected after cast-expression.");
2830 private void typeName() throws CoreException {
2831 //'string' 'unset' 'array' 'object'
2833 //'real' 'double' 'float'
2835 String identifier = "";
2836 if (token == TokenNameIdentifier) {
2837 char[] ident = scanner.getCurrentIdentifierSource();
2838 identifier = new String(ident);
2839 String str = identifier.toLowerCase();
2841 for (int i = 0; i < PHP_TYPES.length; i++) {
2842 if (PHP_TYPES[i].equals(str)) {
2848 "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
2851 private void assignExpression() throws CoreException {
2853 if (token == TokenNameEQUAL) { // =
2855 logicalinclusiveorExpression();
2856 } else if (token == TokenNameDOT_EQUAL) { // .=
2858 logicalinclusiveorExpression();
2859 } else if (token == TokenNameEQUAL_GREATER) { // =>
2861 logicalinclusiveorExpression();
2862 } else if (token == TokenNamePLUS_EQUAL) { // +=
2864 logicalinclusiveorExpression();
2865 } else if (token == TokenNameMINUS_EQUAL) { // -=
2867 logicalinclusiveorExpression();
2868 } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
2870 logicalinclusiveorExpression();
2871 } else if (token == TokenNameDIVIDE_EQUAL) { // *=
2873 logicalinclusiveorExpression();
2874 } else if (token == TokenNameREMAINDER_EQUAL) { // %=
2876 logicalinclusiveorExpression();
2877 } else if (token == TokenNameAND_EQUAL) { // &=
2879 logicalinclusiveorExpression();
2880 } else if (token == TokenNameOR_EQUAL) { // |=
2882 logicalinclusiveorExpression();
2883 } else if (token == TokenNameXOR_EQUAL) { // ^=
2885 logicalinclusiveorExpression();
2886 } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
2888 logicalinclusiveorExpression();
2889 } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
2891 logicalinclusiveorExpression();
2892 } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
2894 logicalinclusiveorExpression();
2898 private void multiplicativeExpression() throws CoreException {
2901 if (token != TokenNameMULTIPLY
2902 && token != TokenNameDIVIDE
2903 && token != TokenNameREMAINDER) {
2910 private void concatenationExpression() throws CoreException {
2912 multiplicativeExpression();
2913 if (token != TokenNameDOT) {
2920 private void additiveExpression() throws CoreException {
2922 concatenationExpression();
2923 if (token != TokenNamePLUS && token != TokenNameMINUS) {
2930 private void shiftExpression() throws CoreException {
2932 additiveExpression();
2933 if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
2940 private void relationalExpression() throws CoreException {
2943 if (token != TokenNameLESS
2944 && token != TokenNameGREATER
2945 && token != TokenNameLESS_EQUAL
2946 && token != TokenNameGREATER_EQUAL) {
2953 private void identicalExpression() throws CoreException {
2955 relationalExpression();
2956 if (token != TokenNameEQUAL_EQUAL_EQUAL
2957 && token != TokenNameNOT_EQUAL_EQUAL) {
2964 private void equalityExpression() throws CoreException {
2966 identicalExpression();
2967 if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
2974 private void ternaryExpression() throws CoreException {
2975 equalityExpression();
2976 if (token == TokenNameQUESTION) {
2979 if (token == TokenNameCOLON) {
2983 throwSyntaxError("':' expected in ternary operator '? :'.");
2988 private void andExpression() throws CoreException {
2990 ternaryExpression();
2991 if (token != TokenNameAND) {
2998 private void exclusiveorExpression() throws CoreException {
3001 if (token != TokenNameXOR) {
3008 private void inclusiveorExpression() throws CoreException {
3010 exclusiveorExpression();
3011 if (token != TokenNameOR) {
3018 private void booleanandExpression() throws CoreException {
3020 inclusiveorExpression();
3021 if (token != TokenNameAND_AND) {
3028 private void booleanorExpression() throws CoreException {
3030 booleanandExpression();
3031 if (token != TokenNameOR_OR) {
3038 private void logicalandExpression() throws CoreException {
3040 booleanorExpression();
3041 if (token != TokenNameAND) {
3048 private void logicalexclusiveorExpression() throws CoreException {
3050 logicalandExpression();
3051 if (token != TokenNameXOR) {
3058 private void logicalinclusiveorExpression() throws CoreException {
3060 logicalexclusiveorExpression();
3061 if (token != TokenNameOR) {
3068 // public void assignmentExpression() {
3069 // if (token == TokenNameVARIABLE) {
3071 // if (token == TokenNameSET) {
3073 // logicalinclusiveorExpression();
3076 // logicalinclusiveorExpression();
3080 private void variableList() throws CoreException {
3083 if (token == TokenNameCOMMA) {
3091 private void variable() throws CoreException {
3092 if (token == TokenNameDOLLAR_LBRACE) {
3096 if (token != TokenNameRBRACE) {
3097 throwSyntaxError("'}' expected after indirect variable token '${'.");
3101 if (token == TokenNameVariable) {
3103 if (token == TokenNameLBRACKET) {
3106 if (token != TokenNameRBRACKET) {
3107 throwSyntaxError("']' expected in variable-list.");
3110 } else if (token == TokenNameEQUAL) {
3115 throwSyntaxError("$-variable expected in variable-list.");
3121 * It will look for a value (after a '=' for example)
3122 * @throws CoreException
3124 private void constant() throws CoreException {
3127 case TokenNamePLUS :
3130 case TokenNameDoubleLiteral :
3133 case TokenNameIntegerLiteral :
3137 throwSyntaxError("Constant expected after '+' presign.");
3140 case TokenNameMINUS :
3143 case TokenNameDoubleLiteral :
3146 case TokenNameIntegerLiteral :
3150 throwSyntaxError("Constant expected after '-' presign.");
3153 case TokenNamenull :
3156 case TokenNamefalse :
3159 case TokenNametrue :
3162 case TokenNameIdentifier :
3163 // ident = identifier;
3164 char[] ident = scanner.getCurrentIdentifierSource();
3166 if (token == TokenNameLPAREN) {
3168 if (token != TokenNameRPAREN) {
3170 if (token != TokenNameRPAREN) {
3172 "')' expected after identifier '"
3174 + "' in postfix-expression.");
3180 case TokenNameStringLiteral :
3183 case TokenNameStringConstant :
3186 case TokenNameStringInterpolated :
3189 case TokenNameDoubleLiteral :
3192 case TokenNameIntegerLiteral :
3196 throwSyntaxError("Constant expected.");