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.phpeclipse.PHPeclipsePlugin;
18 import net.sourceforge.phpeclipse.phpeditor.PHPString;
19 import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
21 import org.eclipse.core.resources.IFile;
22 import org.eclipse.core.resources.IMarker;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.ui.texteditor.MarkerUtilities;
26 import test.PHPParserSuperclass;
29 extends PHPParserSuperclass
30 implements PHPKeywords, ITerminalSymbols {
32 public static final int ERROR = 2;
33 public static final int WARNING = 1;
34 public static final int INFO = 0;
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(1, 1, "", error);
263 * This method will throw the SyntaxError.
264 * It will add the good lines and columns to the Error
265 * @param error the error message
266 * @throws SyntaxError the error raised
268 private void throwSyntaxError(String error, int startRow) {
269 throw new SyntaxError(startRow, 0, " ", error);
273 * Method Declaration.
277 // private void getChar() {
278 // if (str.length() > chIndx) {
279 // ch = str.charAt(chIndx++);
284 // chIndx = str.length() + 1;
286 // // token = TokenNameEOF;
291 * gets the next token from input
293 private void getNextToken() throws CoreException {
295 token = scanner.getNextToken();
297 int currentEndPosition = scanner.getCurrentTokenEndPosition();
298 int currentStartPosition = scanner.getCurrentTokenStartPosition();
301 currentStartPosition + "," + currentEndPosition + ": ");
302 System.out.println(scanner.toStringAction(token));
304 } catch (InvalidInputException e) {
305 token = TokenNameERROR;
309 // boolean phpFound = false;
316 // while (str.length() > chIndx) {
317 // token = TokenNameERROR;
318 // ch = str.charAt(chIndx++);
324 // ch2 = str.charAt(chIndx++);
326 // ch2 = str.charAt(chIndx++);
327 // if (Character.isWhitespace(ch2)) {
332 // } else if (ch2 == 'p' || ch2 == 'P') {
333 // ch2 = str.charAt(chIndx++);
334 // if (ch2 == 'h' || ch2 == 'H') {
335 // ch2 = str.charAt(chIndx++);
336 // if (ch2 == 'p' || ch2 == 'P') {
354 // while (str.length() > chIndx) {
355 // ch = str.charAt(chIndx++);
356 // token = TokenNameERROR;
359 // columnCount = chIndx;
360 // continue; // while loop
362 // if (str.length() == chIndx) {
365 // if (!Character.isWhitespace(ch)) {
367 // if (str.length() > chIndx) {
368 // if (str.charAt(chIndx) == '{') {
370 // token = TokenNameDOLLAROPEN;
377 // if ((ch >= 'a' && ch <= 'z')
378 // || (ch >= 'A' && ch <= 'Z')
384 // if (ch >= '0' && ch <= '9') {
389 // if (str.length() > chIndx) {
390 // if (str.charAt(chIndx) == '/') {
393 // // read comment until end of line:
394 // while ((str.length() > chIndx)
395 // && (ch != '\n')) {
396 // ch = str.charAt(chIndx++);
398 // ch2 = str.charAt(chIndx);
401 // token = TokenNameHTML;
412 // } else if (str.charAt(chIndx) == '*') {
414 // // multi line comment:
415 // while (str.length() > chIndx) {
416 // if (str.charAt(chIndx) == '*'
417 // && (str.length() > (chIndx + 1))
418 // && str.charAt(chIndx + 1) == '/') {
422 // ch = str.charAt(chIndx++);
425 // columnCount = chIndx;
431 // } else if (ch == '#') {
432 // // read comment until end of line:
433 // while ((str.length() > chIndx) && (ch != '\n')) {
434 // ch = str.charAt(chIndx++);
436 // ch2 = str.charAt(chIndx);
439 // token = TokenNameHTML;
450 // } else if (ch == '"') {
453 // TokenNameStringInterpolated,
454 // "Open string character '\"' at end of file.");
456 // } else if (ch == '\'') {
459 // TokenNameStringConstant,
460 // "Open string character \"'\" at end of file.");
462 // } else if (ch == '`') {
465 // TokenNameStringConstant,
466 // "Open string character \"`\" at end of file.");
468 // "Other string delimiters prefered (found \"`\").",
477 // token = TokenNameLPAREN;
481 // token = TokenNameRPAREN;
485 // token = TokenNameLBRACE;
489 // token = TokenNameRBRACE;
493 // token = TokenNameLBRACKET;
497 // token = TokenNameRBRACKET;
501 // token = TokenNameCOMMA;
505 // token = TokenNameQUESTION;
506 // if (str.length() > chIndx) {
507 // if (str.charAt(chIndx) == '>') {
509 // token = TokenNameHTML;
519 // token = TokenNameAT;
522 // token = TokenNameTWIDDLE;
523 // if (str.length() > chIndx) {
524 // if (str.charAt(chIndx) == '=') {
526 // token = TokenNameTWIDDLE_EQUAL;
533 // token = TokenNameDOT;
534 // if (str.length() > chIndx) {
535 // if (str.charAt(chIndx) == '=') {
537 // token = TokenNameDOT_EQUAL;
545 // token = TokenNameStringLiteral;
549 // token = TokenNameREMAINDER;
550 // if (str.length() > chIndx) {
551 // if (str.charAt(chIndx) == '=') {
553 // token = TokenNameREMAINDER_EQUAL;
560 // token = TokenNameSEMICOLON;
564 // token = TokenNameXOR;
565 // if (str.length() > chIndx) {
566 // if (str.charAt(chIndx) == '=') {
568 // token = TokenNameXOR_EQUAL;
575 // token = TokenNameDIVIDE;
577 // if (str.length() > chIndx) {
578 // if (str.charAt(chIndx) == '=') {
580 // token = TokenNameDIVIDE_EQUAL;
588 // token = TokenNameMULTIPLY;
589 // if (str.length() > chIndx) {
590 // if (str.charAt(chIndx) == '*') {
592 // token = TokenNameXOR;
596 // if (str.charAt(chIndx) == '=') {
598 // token = TokenNameMULTIPLY_EQUAL;
606 // token = TokenNamePLUS;
607 // if (str.length() > chIndx) {
608 // if (str.charAt(chIndx) == '+') {
610 // token = TokenNamePLUS_PLUS;
614 // if (str.charAt(chIndx) == '=') {
616 // token = TokenNamePLUS_EQUAL;
623 // token = TokenNameMINUS;
624 // if (str.length() > chIndx) {
625 // if (str.charAt(chIndx) == '-') {
627 // token = TokenNameMINUS_MINUS;
631 // if (str.charAt(chIndx) == '=') {
633 // token = TokenNameMINUS_EQUAL;
637 // if (str.charAt(chIndx) == '>') {
639 // token = TokenNameMINUS_GREATER;
647 // token = TokenNameEQUAL;
649 // if (str.length() > chIndx) {
650 // ch = str.charAt(chIndx);
654 // token = TokenNameEQUAL_EQUAL;
655 // if (str.length() > chIndx) {
656 // ch = str.charAt(chIndx);
661 // TokenNameEQUAL_EQUAL_EQUAL;
668 // token = TokenNameEQUAL_GREATER;
676 // token = TokenNameNOT;
678 // if (str.length() > chIndx) {
679 // if (str.charAt(chIndx) == '=') {
681 // token = TokenNameNOT_EQUAL;
682 // if (str.length() > chIndx) {
683 // ch = str.charAt(chIndx);
688 // TokenNameNOT_EQUAL_EQUAL;
697 // token = TokenNameGREATER;
699 // if (str.length() > chIndx) {
700 // if (str.charAt(chIndx) == '=') {
702 // token = TokenNameGREATER_EQUAL;
705 // if (str.charAt(chIndx) == '>') {
707 // token = TokenNameRIGHT_SHIFT;
708 // if (str.length() > chIndx) {
709 // if (str.charAt(chIndx) == '=') {
712 // TokenNameRIGHT_SHIFT_EQUAL;
722 // token = TokenNameLESS;
724 // if (str.length() > chIndx) {
725 // if (str.charAt(chIndx) == '=') {
727 // token = TokenNameLESS_EQUAL;
731 // if (str.charAt(chIndx) == '<') {
733 // token = TokenNameLEFT_SHIFT;
734 // if (str.charAt(chIndx) == '<') {
736 // int startRow = rowCount;
737 // if (str.length() > chIndx) {
739 // ch = str.charAt(++chIndx);
740 // if ((ch >= 'a' && ch <= 'z')
741 // || (ch >= 'A' && ch <= 'Z')
746 // TokenNameStringConstant;
747 // while (str.length()
763 // .equals(identifier)) {
775 // "Open heredoc syntax after operator '<<<'.",
777 // } else if (str.charAt(chIndx) == '=') {
779 // token = TokenNameLEFT_SHIFT_EQUAL;
789 // token = TokenNameOR;
791 // if (str.length() > chIndx) {
792 // if (str.charAt(chIndx) == '|') {
794 // token = TokenNameOR_OR;
797 // if (str.charAt(chIndx) == '=') {
799 // token = TokenNameOR_EQUAL;
806 // token = TokenNameAND;
807 // if (str.length() > chIndx) {
808 // if (str.charAt(chIndx) == '&') {
810 // token = TokenNameAND_AND;
813 // if (str.charAt(chIndx) == '=') {
815 // token = TokenNameAND_EQUAL;
823 // token = TokenNameCOLON;
824 // if (str.length() > chIndx) {
825 // if (str.charAt(chIndx) == ':') {
827 // token = TokenNameCOLON_COLON;
832 // // token = TokenNameHASH;
836 // // token = TokenNameAT;
841 // "unexpected character: '" + ch + "'");
844 // if (token == TokenNameERROR) {
845 // throwSyntaxError("token not found");
852 // } catch (StringIndexOutOfBoundsException e) {
853 // // catched from charAt
856 // chIndx = str.length() + 1;
858 // token = TokenNameEOF;
861 // // if (phpList != null) {
862 // // if (currentPHPString < phpList.size()) {
863 // // token = TokenNameUNDEFINED;
864 // // temp = (PHPString) phpList.get(currentPHPString++);
865 // // this.str = temp.getPHPString();
866 // // this.token = TokenNameEOF;
867 // // this.chIndx = 0;
868 // // this.rowCount = temp.getLineNumber();
869 // // this.columnCount = 0;
870 // // getNextToken();
873 // // token = TokenNameUNDEFINED;
880 // * Get an identifier.
882 // private void getIdentifier() {
883 // // StringBuffer ident = new StringBuffer();
884 // int startPosition = chIndx - 1;
885 // // ident.append(ch);
888 // // attention recursive call:
890 // token = TokenNameVariable;
893 // token = TokenNameIdentifier;
898 // //this will read the buffer until the next character is a forbidden character for identifier
899 // while ((ch >= 'a' && ch <= 'z')
900 // || (ch >= 'A' && ch <= 'Z')
901 // || (ch >= '0' && ch <= '9')
903 // // ident.append(ch);
906 // int endPosition = chIndx--;
907 // int length = (--endPosition) - startPosition;
909 // identifier = str.substring(startPosition, endPosition);
910 // // System.out.println(identifier);
912 // // determine if this identitfer is a keyword
913 // // @todo improve this in future version
914 // Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
916 // token = i.intValue();
922 * if it's a <code>double</code> the number will be stored in <code>doubleNumber</code> and the token will have the
923 * value {@link Parser#TokenNameDOUBLE_NUMBER}<br />
924 * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
925 * value {@link Parser#TokenNameINT_NUMBER}
927 // private void getNumber() {
928 // StringBuffer inum = new StringBuffer();
930 // int numFormat = 10;
932 // // save first digit
933 // char firstCh = ch;
937 // // determine number conversions:
938 // if (firstCh == '0') {
967 // if (numFormat == 16) {
968 // while ((ch >= '0' && ch <= '9')
969 // || (ch >= 'a' && ch <= 'f')
970 // || (ch >= 'A' && ch <= 'F')) {
975 // while ((ch >= '0' && ch <= '9')
979 // if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
980 // if (ch == '.' && dFlag != ' ') {
983 // if ((dFlag == 'E') || (dFlag == 'e')) {
989 // if ((ch == '-') || (ch == '+')) {
1002 // if (dFlag != ' ') {
1003 // doubleNumber = new Double(inum.toString());
1004 // token = TokenNameDoubleLiteral;
1007 // longNumber = Long.valueOf(inum.toString(), numFormat);
1008 // token = TokenNameIntegerLiteral;
1012 // } catch (Throwable e) {
1013 // throwSyntaxError("Number format error: " + inum.toString());
1019 // * @param openChar the opening char ('\'', '"', '`')
1020 // * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
1021 // * @param errorMsg the error message in case of parse error in the string
1023 // private void getString(
1024 // final char openChar,
1025 // final int typeString,
1026 // final String errorMsg) {
1027 // StringBuffer sBuffer = new StringBuffer();
1028 // boolean openString = true;
1029 // int startRow = rowCount;
1030 // while (str.length() > chIndx) {
1031 // ch = str.charAt(chIndx++);
1032 // if (ch == '\\') {
1033 // sBuffer.append(ch);
1034 // if (str.length() > chIndx) {
1035 // ch = str.charAt(chIndx++);
1036 // sBuffer.append(ch);
1038 // } else if (ch == openChar) {
1039 // openString = false;
1041 // } else if (ch == '\n') {
1043 // columnCount = chIndx;
1045 // sBuffer.append(ch);
1048 // if (openString) {
1049 // if (typeString == TokenNameStringConstant) {
1050 // throwSyntaxError(errorMsg, startRow);
1052 // throwSyntaxError(errorMsg);
1055 // token = typeString;
1056 // stringValue = sBuffer.toString();
1059 // public void htmlParserTester(String input) {
1060 // int lineNumber = 1;
1061 // int startLineNumber = 1;
1062 // int startIndex = 0;
1065 // boolean phpMode = false;
1066 // boolean phpFound = false;
1068 // phpList = new ArrayList();
1069 // currentPHPString = 0;
1073 // while (i < input.length()) {
1074 // ch = input.charAt(i++);
1075 // if (ch == '\n') {
1078 // if ((!phpMode) && ch == '<') {
1079 // ch2 = input.charAt(i++);
1080 // if (ch2 == '?') {
1081 // ch2 = input.charAt(i++);
1082 // if (Character.isWhitespace(ch2)) {
1087 // startLineNumber = lineNumber;
1089 // } else if (ch2 == 'p') {
1090 // ch2 = input.charAt(i++);
1091 // if (ch2 == 'h') {
1092 // ch2 = input.charAt(i++);
1093 // if (ch2 == 'p') {
1097 // startLineNumber = lineNumber;
1103 // } else if (ch2 == 'P') {
1104 // ch2 = input.charAt(i++);
1105 // if (ch2 == 'H') {
1106 // ch2 = input.charAt(i++);
1107 // if (ch2 == 'P') {
1111 // startLineNumber = lineNumber;
1124 // if (ch == '/' && i < input.length()) {
1125 // ch2 = input.charAt(i++);
1126 // if (ch2 == '/') {
1127 // while (i < input.length()) {
1128 // ch = input.charAt(i++);
1129 // if (ch == '?' && i < input.length()) {
1130 // ch2 = input.charAt(i++);
1131 // if (ch2 == '>') {
1139 // startLineNumber));
1143 // } else if (ch == '\n') {
1149 // } else if (ch2 == '*') {
1150 // // multi-line comment
1151 // while (i < input.length()) {
1152 // ch = input.charAt(i++);
1153 // if (ch == '\n') {
1155 // } else if (ch == '*' && i < input.length()) {
1156 // ch2 = input.charAt(i++);
1157 // if (ch2 == '/') {
1167 // } else if (ch == '#') {
1168 // while (i < input.length()) {
1169 // ch = input.charAt(i++);
1170 // if (ch == '?' && i < input.length()) {
1171 // ch2 = input.charAt(i++);
1172 // if (ch2 == '>') {
1177 // input.substring(startIndex, i - 2),
1178 // startLineNumber));
1182 // } else if (ch == '\n') {
1188 // } else if (ch == '"') {
1190 // while (i < input.length()) {
1191 // ch = input.charAt(i++);
1192 // if (ch == '\n') {
1195 // ch == '\\' && i < input.length()) { // escape
1197 // } else if (ch == '"') {
1202 // } else if (ch == '\'') {
1204 // while (i < input.length()) {
1205 // ch = input.charAt(i++);
1206 // if (ch == '\n') {
1209 // ch == '\\' && i < input.length()) { // escape
1211 // } else if (ch == '\'') {
1218 // if (ch == '?' && i < input.length()) {
1219 // ch2 = input.charAt(i++);
1220 // if (ch2 == '>') {
1225 // input.substring(startIndex, i - 2),
1226 // startLineNumber));
1236 // "No PHP source code found.",
1242 // "Open PHP tag at end of file.",
1247 // input.substring(startIndex, i - 2),
1248 // startLineNumber));
1250 // // for (int j=0;j<phpList.size();j++) {
1251 // // String temp = ((PHPString)phpList.get(j)).getPHPString();
1252 // // int startIndx = temp.length()-10;
1253 // // if (startIndx<0) {
1254 // // startIndx = 0;
1256 // // System.out.println(temp.substring(startIndx)+"?>");
1258 // phpParserTester(null, 1);
1259 // // PHPString temp;
1260 // // for(int j=0;j<phpList.size();j++) {
1261 // // temp = (PHPString) phpList.get(j);
1262 // // parser.start(temp.getPHPString(), temp.getLineNumber());
1265 // } catch (CoreException e) {
1269 public void phpParserTester(String s, int rowCount) throws CoreException {
1272 if (phpList.size() != 0) {
1273 this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
1276 this.token = TokenNameEOF;
1278 // this.rowCount = rowCount;
1279 // this.columnCount = 0;
1280 this.phpEnd = false;
1281 this.phpMode = true;
1282 scanner.setSource(s.toCharArray());
1283 scanner.setPHPMode(true);
1287 if (token != TokenNameEOF && token != TokenNameERROR) {
1290 if (token != TokenNameEOF) {
1291 if (token == TokenNameERROR) {
1293 "Scanner error (Found unknown token: "
1294 + scanner.toStringAction(token)
1297 if (token == TokenNameRPAREN) {
1298 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1300 if (token == TokenNameRBRACE) {
1301 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1303 if (token == TokenNameRBRACKET) {
1304 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1307 if (token == TokenNameLPAREN) {
1308 throwSyntaxError("Read character '('; end-of-file not reached.");
1310 if (token == TokenNameLBRACE) {
1311 throwSyntaxError("Read character '{'; end-of-file not reached.");
1313 if (token == TokenNameLBRACKET) {
1314 throwSyntaxError("Read character '['; end-of-file not reached.");
1317 throwSyntaxError("End-of-file not reached.");
1320 } catch (SyntaxError err) {
1324 // setMarker(err.getMessage(), err.getLine(), ERROR);
1327 scanner.getCurrentTokenStartPosition(),
1328 scanner.getCurrentTokenEndPosition(),
1331 // if an error occured,
1332 // try to find keywords 'class' or 'function'
1333 // to parse the rest of the string
1334 while (token != TokenNameEOF && token != TokenNameERROR) {
1335 if (token == TokenNameclass || token == TokenNamefunction) {
1340 if (token == TokenNameEOF || token == TokenNameERROR) {
1349 * Parses a string with php tags
1350 * i.e. '<body> <?php phpinfo() ?> </body>'
1352 public void parse(String s) throws CoreException {
1354 this.token = TokenNameEOF;
1356 // this.rowCount = 1;
1357 // this.columnCount = 0;
1358 this.phpEnd = false;
1359 this.phpMode = false;
1360 /* scanner initialization */
1361 scanner.setSource(s.toCharArray());
1362 scanner.setPHPMode(false);
1366 if (token != TokenNameEOF && token != TokenNameERROR) {
1369 if (token != TokenNameEOF) {
1370 if (token == TokenNameERROR) {
1372 "Scanner error (Found unknown token: "
1373 + scanner.toStringAction(token)
1376 if (token == TokenNameRPAREN) {
1377 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
1379 if (token == TokenNameRBRACE) {
1380 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
1382 if (token == TokenNameRBRACKET) {
1383 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
1386 if (token == TokenNameLPAREN) {
1387 throwSyntaxError("Read character '('; end-of-file not reached.");
1389 if (token == TokenNameLBRACE) {
1390 throwSyntaxError("Read character '{'; end-of-file not reached.");
1392 if (token == TokenNameLBRACKET) {
1393 throwSyntaxError("Read character '['; end-of-file not reached.");
1396 throwSyntaxError("End-of-file not reached.");
1399 } catch (SyntaxError sytaxErr1) {
1400 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
1402 sytaxErr1.getMessage(),
1403 scanner.getCurrentTokenStartPosition(),
1404 scanner.getCurrentTokenEndPosition(),
1407 // if an error occured,
1408 // try to find keywords 'class' or 'function'
1409 // to parse the rest of the string
1410 while (token != TokenNameEOF && token != TokenNameERROR) {
1411 if (token == TokenNameclass || token == TokenNamefunction) {
1416 if (token == TokenNameEOF || token == TokenNameERROR) {
1419 } catch (SyntaxError sytaxErr2) {
1420 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
1422 sytaxErr2.getMessage(),
1423 scanner.getCurrentTokenStartPosition(),
1424 scanner.getCurrentTokenEndPosition(),
1433 public PHPOutlineInfo parseInfo(Object parent, String s) {
1434 PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
1435 // Stack stack = new Stack();
1436 // stack.push(outlineInfo.getDeclarations());
1439 this.token = TokenNameEOF;
1441 // this.rowCount = 1;
1442 // this.columnCount = 0;
1443 this.phpEnd = false;
1444 this.phpMode = false;
1445 scanner.setSource(s.toCharArray());
1446 scanner.setPHPMode(false);
1450 parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
1451 } catch (CoreException e) {
1456 private void parseDeclarations(
1457 PHPOutlineInfo outlineInfo,
1458 PHPSegmentWithChildren current,
1461 // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
1462 PHPSegmentWithChildren temp;
1465 IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
1467 while (token != TokenNameEOF && token != TokenNameERROR) {
1468 if (token == TokenNameVariable) {
1469 ident = scanner.getCurrentIdentifierSource();
1470 outlineInfo.addVariable(new String(ident));
1472 } else if (token == TokenNamevar) {
1474 if (token == TokenNameVariable
1475 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
1476 ident = scanner.getCurrentIdentifierSource();
1477 String variableName = new String(ident);
1478 outlineInfo.addVariable(variableName);
1480 if (token != TokenNameSEMICOLON) {
1483 ident = scanner.getCurrentTokenSource();
1484 if (token > TokenNameKEYWORD) {
1485 current.add(new PHPVarDeclaration(current, variableName,
1486 // chIndx - ident.length,
1487 scanner.getCurrentTokenStartPosition(), new String(ident)));
1490 case TokenNameVariable :
1491 current.add(new PHPVarDeclaration(current, variableName,
1492 // chIndx - ident.length,
1493 scanner.getCurrentTokenStartPosition(), new String(ident)));
1495 case TokenNameIdentifier :
1496 current.add(new PHPVarDeclaration(current, variableName,
1497 // chIndx - ident.length,
1498 scanner.getCurrentTokenStartPosition(), new String(ident)));
1500 case TokenNameDoubleLiteral :
1502 .add(new PHPVarDeclaration(
1504 variableName + doubleNumber,
1505 // chIndx - ident.length,
1506 scanner.getCurrentTokenStartPosition(), new String(ident)));
1508 case TokenNameIntegerLiteral :
1509 current.add(new PHPVarDeclaration(current, variableName,
1510 // chIndx - ident.length,
1511 scanner.getCurrentTokenStartPosition(), new String(ident)));
1513 case TokenNameStringInterpolated :
1514 case TokenNameStringLiteral :
1515 current.add(new PHPVarDeclaration(current, variableName,
1516 // chIndx - ident.length,
1517 scanner.getCurrentTokenStartPosition(), new String(ident)));
1519 case TokenNameStringConstant :
1520 current.add(new PHPVarDeclaration(current, variableName,
1521 // chIndx - ident.length,
1522 scanner.getCurrentTokenStartPosition(), new String(ident)));
1525 current.add(new PHPVarDeclaration(current, variableName,
1526 // chIndx - ident.length
1527 scanner.getCurrentTokenStartPosition()));
1533 ident = scanner.getCurrentIdentifierSource();
1535 current.add(new PHPVarDeclaration(current, variableName,
1536 // chIndx - ident.length
1537 scanner.getCurrentTokenStartPosition()));
1540 } else if (token == TokenNamefunction) {
1542 if (token == TokenNameAND) {
1545 if (token == TokenNameIdentifier
1546 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
1547 ident = scanner.getCurrentIdentifierSource();
1548 outlineInfo.addVariable(new String(ident));
1549 temp = new PHPFunctionDeclaration(current, new String(ident),
1550 // chIndx - ident.length
1551 scanner.getCurrentTokenStartPosition());
1554 parseDeclarations(outlineInfo, temp, true);
1556 } else if (token == TokenNameclass) {
1558 if (token == TokenNameIdentifier
1559 && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
1560 ident = scanner.getCurrentIdentifierSource();
1561 outlineInfo.addVariable(new String(ident));
1562 temp = new PHPClassDeclaration(current, new String(ident),
1563 // chIndx - ident.len
1564 scanner.getCurrentTokenStartPosition());
1566 // stack.push(temp);
1569 //skip tokens for classname, extends and others until we have the opening '{'
1570 while (token != TokenNameLBRACE
1571 && token != TokenNameEOF
1572 && token != TokenNameERROR) {
1575 parseDeclarations(outlineInfo, temp, true);
1578 } else if (token == TokenNameLBRACE) {
1581 } else if (token == TokenNameRBRACE) {
1584 if (counter == 0 && goBack) {
1588 token == TokenNamerequire
1589 || token == TokenNamerequire_once
1590 || token == TokenNameinclude
1591 || token == TokenNameinclude_once) {
1592 ident = scanner.getCurrentTokenSource();
1595 int startPosition = scanner.getCurrentTokenStartPosition();
1597 char[] expr = scanner.getCurrentTokenSource(startPosition);
1598 outlineInfo.addVariable(new String(ident));
1599 current.add(new PHPReqIncDeclaration(current, new String(ident),
1600 // chIndx - ident.length,
1601 startPosition, new String(expr)));
1607 } catch (CoreException e) {
1608 } catch (SyntaxError sytaxErr) {
1610 // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
1612 sytaxErr.getMessage(),
1613 scanner.getCurrentTokenStartPosition(),
1614 scanner.getCurrentTokenEndPosition(),
1616 } catch (CoreException e) {
1621 private void statementList() throws CoreException {
1624 if ((token == TokenNameRBRACE)
1625 || (token == TokenNamecase)
1626 || (token == TokenNamedefault)
1627 || (token == TokenNameelseif)
1628 || (token == TokenNameendif)
1629 || (token == TokenNameendfor)
1630 || (token == TokenNameendforeach)
1631 || (token == TokenNameendwhile)
1632 || (token == TokenNameendswitch)
1633 || (token == TokenNameEOF)
1634 || (token == TokenNameERROR)) {
1640 private void compoundStatement() throws CoreException {
1641 // '{' [statement-list] '}'
1642 if (token == TokenNameLBRACE) {
1645 throwSyntaxError("'{' expected in compound-statement.");
1647 if (token != TokenNameRBRACE) {
1650 if (token == TokenNameRBRACE) {
1653 throwSyntaxError("'}' expected in compound-statement.");
1657 private void statement() throws CoreException {
1658 // if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
1659 // char[] ident = scanner.getCurrentIdentifierSource();
1660 // String keyword = new String(ident);
1661 if (token == TokenNameinclude || token == TokenNameinclude_once) {
1664 if (token == TokenNameSEMICOLON) {
1667 if (token != TokenNameStopPHP) {
1668 throwSyntaxError("';' character after 'include' or 'include_once' expected.");
1673 } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
1677 if (token == TokenNameSEMICOLON) {
1680 if (token != TokenNameStopPHP) {
1681 throwSyntaxError("';' character after 'require' or 'require_once' expected.");
1686 } else if (token == TokenNameif) {
1688 if (token == TokenNameLPAREN) {
1691 throwSyntaxError("'(' expected after 'if' keyword.");
1694 if (token == TokenNameRPAREN) {
1697 throwSyntaxError("')' expected after 'if' condition.");
1702 } else if (token == TokenNameswitch) {
1704 if (token == TokenNameLPAREN) {
1707 throwSyntaxError("'(' expected after 'switch' keyword.");
1710 if (token == TokenNameRPAREN) {
1713 throwSyntaxError("')' expected after 'switch' condition.");
1717 } else if (token == TokenNamefor) {
1719 if (token == TokenNameLPAREN) {
1722 throwSyntaxError("'(' expected after 'for' keyword.");
1724 if (token == TokenNameSEMICOLON) {
1728 if (token == TokenNameSEMICOLON) {
1731 throwSyntaxError("';' expected after 'for'.");
1734 if (token == TokenNameSEMICOLON) {
1738 if (token == TokenNameSEMICOLON) {
1741 throwSyntaxError("';' expected after 'for'.");
1744 if (token == TokenNameRPAREN) {
1748 if (token == TokenNameRPAREN) {
1751 throwSyntaxError("')' expected after 'for'.");
1756 } else if (token == TokenNamewhile) {
1758 if (token == TokenNameLPAREN) {
1761 throwSyntaxError("'(' expected after 'while' keyword.");
1764 if (token == TokenNameRPAREN) {
1767 throwSyntaxError("')' expected after 'while' condition.");
1771 } else if (token == TokenNamedo) {
1773 if (token == TokenNameLBRACE) {
1776 throwSyntaxError("'{' expected after 'do' keyword.");
1778 if (token != TokenNameRBRACE) {
1781 if (token == TokenNameRBRACE) {
1784 throwSyntaxError("'}' expected after 'do' keyword.");
1786 if (token == TokenNamewhile) {
1788 if (token == TokenNameLPAREN) {
1791 throwSyntaxError("'(' expected after 'while' keyword.");
1794 if (token == TokenNameRPAREN) {
1797 throwSyntaxError("')' expected after 'while' condition.");
1800 throwSyntaxError("'while' expected after 'do' keyword.");
1802 if (token == TokenNameSEMICOLON) {
1805 if (token != TokenNameStopPHP) {
1806 throwSyntaxError("';' expected after do-while statement.");
1811 } else if (token == TokenNameforeach) {
1813 if (token == TokenNameLPAREN) {
1816 throwSyntaxError("'(' expected after 'foreach' keyword.");
1819 if (token == TokenNameas) {
1822 throwSyntaxError("'as' expected after 'foreach' exxpression.");
1825 if (token == TokenNameEQUAL_GREATER) {
1829 if (token == TokenNameRPAREN) {
1832 throwSyntaxError("')' expected after 'foreach' expression.");
1838 token == TokenNamecontinue
1839 || token == TokenNamebreak
1840 || token == TokenNamereturn) {
1842 if (token != TokenNameSEMICOLON) {
1845 if (token == TokenNameSEMICOLON) {
1848 if (token != TokenNameStopPHP) {
1849 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1855 } else if (token == TokenNameecho) {
1858 if (token == TokenNameSEMICOLON) {
1861 if (token != TokenNameStopPHP) {
1862 throwSyntaxError("';' expected after 'echo' statement.");
1867 // } else if (token == TokenNameprint) {
1870 // if (token == TokenNameSEMICOLON) {
1873 // if (token != TokenNameStopPHP) {
1874 // throwSyntaxError("';' expected after 'print' statement.");
1880 } else if (token == TokenNameglobal || token == TokenNamestatic) {
1883 if (token == TokenNameSEMICOLON) {
1886 if (token != TokenNameStopPHP) {
1887 throwSyntaxError("';' expected after 'global' or 'static' statement.");
1893 // } else if (token == TokenNameunset) {
1895 // if (token == TokenNameARGOPEN) {
1898 // throwSyntaxError("'(' expected after 'unset' keyword.");
1901 // if (token == TokenNameARGCLOSE) {
1904 // throwSyntaxError("')' expected after 'unset' statement.");
1906 // if (token == TokenNameSEMICOLON) {
1909 // if (token != TokenNameStopPHP) {
1910 // throwSyntaxError("';' expected after 'unset' statement.");
1916 // } else if (token == TokenNameexit || token == TokenNamedie) {
1918 // if (token != TokenNameSEMICOLON) {
1921 // if (token == TokenNameSEMICOLON) {
1924 // if (token != TokenNameStopPHP) {
1925 // throwSyntaxError("';' expected after 'exit' or 'die' statement.");
1931 } else if (token == TokenNamedefine) {
1933 if (token == TokenNameLPAREN) {
1936 throwSyntaxError("'(' expected after 'define' keyword.");
1939 if (token == TokenNameCOMMA) {
1942 throwSyntaxError("',' expected after first 'define' constant.");
1945 if (token == TokenNameCOMMA) {
1949 if (token == TokenNameRPAREN) {
1952 throwSyntaxError("')' expected after 'define' statement.");
1954 if (token == TokenNameSEMICOLON) {
1957 if (token != TokenNameStopPHP) {
1958 throwSyntaxError("';' expected after 'define' statement.");
1963 } else if (token == TokenNamefunction) {
1965 functionDefinition();
1967 } else if (token == TokenNameclass) {
1973 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
1974 } else if (token == TokenNameLBRACE) {
1975 // compoundStatement
1977 if (token != TokenNameRBRACE) {
1980 if (token == TokenNameRBRACE) {
1984 throwSyntaxError("'}' expected.");
1987 if (token != TokenNameSEMICOLON) {
1990 if (token == TokenNameSEMICOLON) {
1994 if (token != TokenNameStopPHP && token != TokenNameEOF) {
1996 "';' expected after expression (Found token: "
1997 + scanner.toStringAction(token)
2005 private void classDeclarator() throws CoreException {
2007 //identifier 'extends' identifier
2008 if (token == TokenNameIdentifier) {
2010 if (token == TokenNameextends) {
2012 if (token == TokenNameIdentifier) {
2015 throwSyntaxError("Class name expected after keyword 'extends'.");
2019 throwSyntaxError("Class name expected after keyword 'class'.");
2023 private void classBody() throws CoreException {
2024 //'{' [class-element-list] '}'
2025 if (token == TokenNameLBRACE) {
2027 if (token != TokenNameRBRACE) {
2030 if (token == TokenNameRBRACE) {
2033 throwSyntaxError("'}' expected at end of class body.");
2036 throwSyntaxError("'{' expected at start of class body.");
2040 private void classElementList() throws CoreException {
2043 } while (token == TokenNamefunction || token == TokenNamevar);
2046 private void classElement() throws CoreException {
2048 //function-definition
2049 if (token == TokenNamefunction) {
2051 functionDefinition();
2052 } else if (token == TokenNamevar) {
2056 throwSyntaxError("'function' or 'var' expected.");
2060 private void classProperty() throws CoreException {
2061 //'var' variable ';'
2062 //'var' variable '=' constant ';'
2064 if (token == TokenNameVariable) {
2066 if (token == TokenNameEQUAL) {
2071 throwSyntaxError("Variable expected after keyword 'var'.");
2073 if (token != TokenNameCOMMA) {
2078 if (token == TokenNameSEMICOLON) {
2081 throwSyntaxError("';' expected after variable declaration.");
2085 private void functionDefinition() throws CoreException {
2086 functionDeclarator();
2087 compoundStatement();
2090 private void functionDeclarator() throws CoreException {
2091 //identifier '(' [parameter-list] ')'
2092 if (token == TokenNameAND) {
2095 if (token == TokenNameIdentifier) {
2097 if (token == TokenNameLPAREN) {
2100 throwSyntaxError("'(' expected in function declaration.");
2102 if (token != TokenNameRPAREN) {
2105 if (token != TokenNameRPAREN) {
2106 throwSyntaxError("')' expected in function declaration.");
2113 private void parameterList() throws CoreException {
2114 //parameter-declaration
2115 //parameter-list ',' parameter-declaration
2117 parameterDeclaration();
2118 if (token != TokenNameCOMMA) {
2125 private void parameterDeclaration() throws CoreException {
2127 //variable-reference
2128 if (token == TokenNameAND) {
2130 if (token == TokenNameVariable) {
2133 throwSyntaxError("Variable expected after reference operator '&'.");
2136 //variable '=' constant
2137 if (token == TokenNameVariable) {
2139 if (token == TokenNameEQUAL) {
2147 private void labeledStatementList() throws CoreException {
2148 if (token != TokenNamecase && token != TokenNamedefault) {
2149 throwSyntaxError("'case' or 'default' expected.");
2152 if (token == TokenNamecase) {
2155 if (token == TokenNameCOLON) {
2157 if (token == TokenNamecase
2158 || token == TokenNamedefault) { // empty case statement ?
2162 } else if (token == TokenNameSEMICOLON) {
2164 // "':' expected after 'case' keyword (Found token: "
2165 // + scanner.toStringAction(token)
2170 "':' expected after 'case' keyword (Found token: "
2171 + scanner.toStringAction(token)
2173 scanner.getCurrentTokenStartPosition(),
2174 scanner.getCurrentTokenEndPosition(),
2177 if (token == TokenNamecase) { // empty case statement ?
2183 "':' character after 'case' constant expected (Found token: "
2184 + scanner.toStringAction(token)
2187 } else { // TokenNamedefault
2189 if (token == TokenNameCOLON) {
2193 throwSyntaxError("':' character after 'default' expected.");
2196 } while (token == TokenNamecase || token == TokenNamedefault);
2199 // public void labeledStatement() {
2200 // if (token == TokenNamecase) {
2203 // if (token == TokenNameDDOT) {
2207 // throwSyntaxError("':' character after 'case' constant expected.");
2210 // } else if (token == TokenNamedefault) {
2212 // if (token == TokenNameDDOT) {
2216 // throwSyntaxError("':' character after 'default' expected.");
2222 // public void expressionStatement() {
2225 // private void inclusionStatement() {
2228 // public void compoundStatement() {
2231 // public void selectionStatement() {
2234 // public void iterationStatement() {
2237 // public void jumpStatement() {
2240 // public void outputStatement() {
2243 // public void scopeStatement() {
2246 // public void flowStatement() {
2249 // public void definitionStatement() {
2252 private void ifStatement() throws CoreException {
2253 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
2254 if (token == TokenNameCOLON) {
2258 case TokenNameelse :
2260 if (token == TokenNameCOLON) {
2264 if (token == TokenNameif) { //'else if'
2266 elseifStatementList();
2268 throwSyntaxError("':' expected after 'else'.");
2272 case TokenNameelseif :
2274 elseifStatementList();
2278 if (token != TokenNameendif) {
2279 throwSyntaxError("'endif' expected.");
2282 if (token != TokenNameSEMICOLON) {
2283 throwSyntaxError("';' expected after if-statement.");
2287 // statement [else-statement]
2289 if (token == TokenNameelseif) {
2291 if (token == TokenNameLPAREN) {
2294 throwSyntaxError("'(' expected after 'elseif' keyword.");
2297 if (token == TokenNameRPAREN) {
2300 throwSyntaxError("')' expected after 'elseif' condition.");
2303 } else if (token == TokenNameelse) {
2310 private void elseifStatementList() throws CoreException {
2314 case TokenNameelse :
2316 if (token == TokenNameCOLON) {
2321 if (token == TokenNameif) { //'else if'
2324 throwSyntaxError("':' expected after 'else'.");
2328 case TokenNameelseif :
2337 private void elseifStatement() throws CoreException {
2338 if (token == TokenNameLPAREN) {
2341 if (token != TokenNameLPAREN) {
2342 throwSyntaxError("')' expected in else-if-statement.");
2345 if (token != TokenNameCOLON) {
2346 throwSyntaxError("':' expected in else-if-statement.");
2353 private void switchStatement() throws CoreException {
2354 if (token == TokenNameCOLON) {
2355 // ':' [labeled-statement-list] 'endswitch' ';'
2357 labeledStatementList();
2358 if (token != TokenNameendswitch) {
2359 throwSyntaxError("'endswitch' expected.");
2362 if (token != TokenNameSEMICOLON) {
2363 throwSyntaxError("';' expected after switch-statement.");
2367 // '{' [labeled-statement-list] '}'
2368 if (token != TokenNameLBRACE) {
2369 throwSyntaxError("'{' expected in switch statement.");
2372 if (token != TokenNameRBRACE) {
2373 labeledStatementList();
2375 if (token != TokenNameRBRACE) {
2376 throwSyntaxError("'}' expected in switch statement.");
2383 private void forStatement() throws CoreException {
2384 if (token == TokenNameCOLON) {
2387 if (token != TokenNameendfor) {
2388 throwSyntaxError("'endfor' expected.");
2391 if (token != TokenNameSEMICOLON) {
2392 throwSyntaxError("';' expected after for-statement.");
2400 private void whileStatement() throws CoreException {
2401 // ':' statement-list 'endwhile' ';'
2402 if (token == TokenNameCOLON) {
2405 if (token != TokenNameendwhile) {
2406 throwSyntaxError("'endwhile' expected.");
2409 if (token != TokenNameSEMICOLON) {
2410 throwSyntaxError("';' expected after while-statement.");
2418 private void foreachStatement() throws CoreException {
2419 if (token == TokenNameCOLON) {
2422 if (token != TokenNameendforeach) {
2423 throwSyntaxError("'endforeach' expected.");
2426 if (token != TokenNameSEMICOLON) {
2427 throwSyntaxError("';' expected after foreach-statement.");
2435 private void exitStatus() throws CoreException {
2436 if (token == TokenNameLPAREN) {
2439 throwSyntaxError("'(' expected in 'exit-status'.");
2441 if (token != TokenNameRPAREN) {
2444 if (token == TokenNameRPAREN) {
2447 throwSyntaxError("')' expected after 'exit-status'.");
2451 private void expressionList() throws CoreException {
2454 if (token == TokenNameCOMMA) {
2462 private void expression() throws CoreException {
2463 //todo: find a better way to get the expression
2464 // expression = new StringBuffer();
2465 // for (int i = chIndx; i < str.length(); i++) {
2466 // if (str.charAt(i) == ';') {
2469 // expression.append(str.charAt(i));
2472 // if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
2475 logicalinclusiveorExpression();
2476 // while (token != TokenNameSEMICOLON) {
2482 private void postfixExpression() throws CoreException {
2485 boolean castFlag = false;
2491 case TokenNamenull :
2494 case TokenNamefalse :
2497 case TokenNametrue :
2500 case TokenNameStringConstant :
2503 case TokenNameHEREDOC :
2504 case TokenNameStringInterpolated :
2505 case TokenNameStringLiteral :
2508 case TokenNameLPAREN :
2510 if (token == TokenNameIdentifier) {
2511 // check if identifier is a type:
2512 // ident = identifier;
2513 ident = scanner.getCurrentIdentifierSource();
2514 String str = new String(ident).toLowerCase();
2515 for (int i = 0; i < PHP_TYPES.length; i++) {
2516 if (PHP_TYPES[i].equals(str)) {
2523 if (token != TokenNameRPAREN) {
2524 throwSyntaxError(") expected after cast-type '" + str + "'.");
2534 if (token != TokenNameRPAREN) {
2535 throwSyntaxError(") expected in postfix-expression.");
2539 case TokenNameDoubleLiteral :
2542 case TokenNameIntegerLiteral :
2545 case TokenNameDOLLAR_LBRACE :
2548 if (token != TokenNameRBRACE) {
2549 throwSyntaxError("'}' expected after indirect variable token '${'.");
2553 case TokenNameVariable :
2554 ident = scanner.getCurrentIdentifierSource();
2556 if (token == TokenNameLBRACE) {
2559 if (token != TokenNameRBRACE) {
2561 "'}' expected after variable '"
2563 + "' in variable-expression.");
2566 } else if (token == TokenNameLPAREN) {
2568 if (token != TokenNameRPAREN) {
2570 if (token != TokenNameRPAREN) {
2572 "')' expected after variable '"
2574 + "' in postfix-expression.");
2580 case TokenNameIdentifier :
2581 ident = scanner.getCurrentIdentifierSource();
2583 if (token == TokenNameLPAREN) {
2585 if (token != TokenNameRPAREN) {
2587 if (token != TokenNameRPAREN) {
2589 "')' expected after identifier '"
2591 + "' in postfix-expression."
2593 + scanner.toStringAction(token)
2600 case TokenNameprint :
2603 // if (token == TokenNameSEMICOLON) {
2606 // if (token != TokenNameStopPHP) {
2607 // throwSyntaxError("';' expected after 'print' statement.");
2612 case TokenNamelist :
2614 if (token == TokenNameLPAREN) {
2616 if (token == TokenNameCOMMA) {
2620 if (token != TokenNameRPAREN) {
2621 throwSyntaxError("')' expected after 'list' keyword.");
2624 // if (token == TokenNameSET) {
2626 // logicalinclusiveorExpression();
2629 throwSyntaxError("'(' expected after 'list' keyword.");
2632 // case TokenNameexit :
2634 // if (token != TokenNameSEMICOLON) {
2637 // if (token == TokenNameSEMICOLON) {
2640 // if (token != TokenNameStopPHP) {
2641 // throwSyntaxError("';' expected after 'exit' expression.");
2646 // case TokenNamedie :
2648 // if (token != TokenNameSEMICOLON) {
2651 // if (token == TokenNameSEMICOLON) {
2654 // if (token != TokenNameStopPHP) {
2655 // throwSyntaxError("';' expected after 'die' expression.");
2660 // case TokenNamearray :
2662 // if (token == TokenNameARGOPEN) {
2664 // if (token == TokenNameCOMMA) {
2667 // expressionList();
2668 // if (token != TokenNameARGCLOSE) {
2669 // throwSyntaxError("')' expected after 'list' keyword.");
2672 // if (token == TokenNameSET) {
2674 // logicalinclusiveorExpression();
2677 // throwSyntaxError("'(' expected after 'list' keyword.");
2681 boolean while_flag = true;
2684 case TokenNameLBRACKET :
2687 if (token != TokenNameRBRACKET) {
2688 throwSyntaxError("] expected in postfix-expression.");
2692 case TokenNameCOLON_COLON : // ::
2693 case TokenNameMINUS_GREATER : // ->
2695 if (token > TokenNameKEYWORD) {
2696 ident = scanner.getCurrentIdentifierSource();
2698 // "Avoid using keyword '"
2699 // + new String(ident)
2700 // + "' as variable name.",
2704 "Avoid using keyword '"
2706 + "' as variable name.",
2707 scanner.getCurrentTokenStartPosition(),
2708 scanner.getCurrentTokenEndPosition(),
2712 case TokenNameVariable :
2713 ident = scanner.getCurrentIdentifierSource();
2715 // if (token == TokenNameARGOPEN) {
2717 // expressionList();
2718 // if (token != TokenNameARGCLOSE) {
2719 // throwSyntaxError(") expected after variable '" + ident + "'.");
2724 case TokenNameIdentifier :
2725 //ident = scanner.getCurrentIdentifierSource();
2728 case TokenNameLBRACE :
2731 if (token != TokenNameRBRACE) {
2732 throwSyntaxError("} expected in postfix-expression.");
2737 throwSyntaxError("Syntax error after '->' token.");
2739 token == TokenNameLBRACKET
2740 || token == TokenNameLPAREN
2741 || token == TokenNameLBRACE) {
2742 if (token == TokenNameLBRACKET) {
2745 if (token != TokenNameRBRACKET) {
2746 throwSyntaxError("] expected after '->'.");
2750 if (token == TokenNameLPAREN) {
2753 if (token != TokenNameRPAREN) {
2754 throwSyntaxError(") expected after '->'.");
2758 if (token == TokenNameLBRACE) {
2761 if (token != TokenNameRBRACE) {
2762 throwSyntaxError("} expected after '->'.");
2768 case TokenNamePLUS_PLUS :
2771 case TokenNameMINUS_MINUS :
2782 private void unaryExpression() throws CoreException {
2784 case TokenNamePLUS_PLUS :
2788 case TokenNameMINUS_MINUS :
2792 // '@' '&' '*' '+' '-' '~' '!'
2801 case TokenNameMULTIPLY :
2805 case TokenNamePLUS :
2809 case TokenNameMINUS :
2813 case TokenNameTWIDDLE :
2822 postfixExpression();
2826 private void castExpression() throws CoreException {
2827 // if (token == TokenNameARGOPEN) {
2830 // if (token != TokenNameARGCLOSE) {
2831 // throwSyntaxError(") expected after cast-expression.");
2838 private void typeName() throws CoreException {
2839 //'string' 'unset' 'array' 'object'
2841 //'real' 'double' 'float'
2843 String identifier = "";
2844 if (token == TokenNameIdentifier) {
2845 char[] ident = scanner.getCurrentIdentifierSource();
2846 identifier = new String(ident);
2847 String str = identifier.toLowerCase();
2849 for (int i = 0; i < PHP_TYPES.length; i++) {
2850 if (PHP_TYPES[i].equals(str)) {
2856 "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
2859 private void assignExpression() throws CoreException {
2861 if (token == TokenNameEQUAL) { // =
2863 logicalinclusiveorExpression();
2864 } else if (token == TokenNameDOT_EQUAL) { // .=
2866 logicalinclusiveorExpression();
2867 } else if (token == TokenNameEQUAL_GREATER) { // =>
2869 logicalinclusiveorExpression();
2870 } else if (token == TokenNamePLUS_EQUAL) { // +=
2872 logicalinclusiveorExpression();
2873 } else if (token == TokenNameMINUS_EQUAL) { // -=
2875 logicalinclusiveorExpression();
2876 } else if (token == TokenNameMULTIPLY_EQUAL) { // *=
2878 logicalinclusiveorExpression();
2879 } else if (token == TokenNameDIVIDE_EQUAL) { // *=
2881 logicalinclusiveorExpression();
2882 } else if (token == TokenNameREMAINDER_EQUAL) { // %=
2884 logicalinclusiveorExpression();
2885 } else if (token == TokenNameAND_EQUAL) { // &=
2887 logicalinclusiveorExpression();
2888 } else if (token == TokenNameOR_EQUAL) { // |=
2890 logicalinclusiveorExpression();
2891 } else if (token == TokenNameXOR_EQUAL) { // ^=
2893 logicalinclusiveorExpression();
2894 } else if (token == TokenNameLEFT_SHIFT_EQUAL) { // <<=
2896 logicalinclusiveorExpression();
2897 } else if (token == TokenNameRIGHT_SHIFT_EQUAL) { // >>=
2899 logicalinclusiveorExpression();
2900 } else if (token == TokenNameTWIDDLE_EQUAL) { // ~=
2902 logicalinclusiveorExpression();
2906 private void multiplicativeExpression() throws CoreException {
2909 if (token != TokenNameMULTIPLY
2910 && token != TokenNameDIVIDE
2911 && token != TokenNameREMAINDER) {
2918 private void concatenationExpression() throws CoreException {
2920 multiplicativeExpression();
2921 if (token != TokenNameDOT) {
2928 private void additiveExpression() throws CoreException {
2930 concatenationExpression();
2931 if (token != TokenNamePLUS && token != TokenNameMINUS) {
2938 private void shiftExpression() throws CoreException {
2940 additiveExpression();
2941 if (token != TokenNameLEFT_SHIFT && token != TokenNameRIGHT_SHIFT) {
2948 private void relationalExpression() throws CoreException {
2951 if (token != TokenNameLESS
2952 && token != TokenNameGREATER
2953 && token != TokenNameLESS_EQUAL
2954 && token != TokenNameGREATER_EQUAL) {
2961 private void identicalExpression() throws CoreException {
2963 relationalExpression();
2964 if (token != TokenNameEQUAL_EQUAL_EQUAL
2965 && token != TokenNameNOT_EQUAL_EQUAL) {
2972 private void equalityExpression() throws CoreException {
2974 identicalExpression();
2975 if (token != TokenNameEQUAL_EQUAL && token != TokenNameNOT_EQUAL) {
2982 private void ternaryExpression() throws CoreException {
2983 equalityExpression();
2984 if (token == TokenNameQUESTION) {
2987 if (token == TokenNameCOLON) {
2991 throwSyntaxError("':' expected in ternary operator '? :'.");
2996 private void andExpression() throws CoreException {
2998 ternaryExpression();
2999 if (token != TokenNameAND) {
3006 private void exclusiveorExpression() throws CoreException {
3009 if (token != TokenNameXOR) {
3016 private void inclusiveorExpression() throws CoreException {
3018 exclusiveorExpression();
3019 if (token != TokenNameOR) {
3026 private void booleanandExpression() throws CoreException {
3028 inclusiveorExpression();
3029 if (token != TokenNameAND_AND) {
3036 private void booleanorExpression() throws CoreException {
3038 booleanandExpression();
3039 if (token != TokenNameOR_OR) {
3046 private void logicalandExpression() throws CoreException {
3048 booleanorExpression();
3049 if (token != TokenNameAND) {
3056 private void logicalexclusiveorExpression() throws CoreException {
3058 logicalandExpression();
3059 if (token != TokenNameXOR) {
3066 private void logicalinclusiveorExpression() throws CoreException {
3068 logicalexclusiveorExpression();
3069 if (token != TokenNameOR) {
3076 // public void assignmentExpression() {
3077 // if (token == TokenNameVARIABLE) {
3079 // if (token == TokenNameSET) {
3081 // logicalinclusiveorExpression();
3084 // logicalinclusiveorExpression();
3088 private void variableList() throws CoreException {
3091 if (token == TokenNameCOMMA) {
3099 private void variable() throws CoreException {
3100 if (token == TokenNameDOLLAR_LBRACE) {
3104 if (token != TokenNameRBRACE) {
3105 throwSyntaxError("'}' expected after indirect variable token '${'.");
3109 if (token == TokenNameVariable) {
3111 if (token == TokenNameLBRACKET) {
3114 if (token != TokenNameRBRACKET) {
3115 throwSyntaxError("']' expected in variable-list.");
3118 } else if (token == TokenNameEQUAL) {
3123 throwSyntaxError("$-variable expected in variable-list.");
3129 * It will look for a value (after a '=' for example)
3130 * @throws CoreException
3132 private void constant() throws CoreException {
3135 case TokenNamePLUS :
3138 case TokenNameDoubleLiteral :
3141 case TokenNameIntegerLiteral :
3145 throwSyntaxError("Constant expected after '+' presign.");
3148 case TokenNameMINUS :
3151 case TokenNameDoubleLiteral :
3154 case TokenNameIntegerLiteral :
3158 throwSyntaxError("Constant expected after '-' presign.");
3161 case TokenNamenull :
3164 case TokenNamefalse :
3167 case TokenNametrue :
3170 case TokenNameIdentifier :
3171 // ident = identifier;
3172 char[] ident = scanner.getCurrentIdentifierSource();
3174 if (token == TokenNameLPAREN) {
3176 if (token != TokenNameRPAREN) {
3178 if (token != TokenNameRPAREN) {
3180 "')' expected after identifier '"
3182 + "' in postfix-expression.");
3188 case TokenNameStringLiteral :
3191 case TokenNameStringConstant :
3194 case TokenNameStringInterpolated :
3197 case TokenNameDoubleLiteral :
3200 case TokenNameIntegerLiteral :
3204 throwSyntaxError("Constant expected.");