1 /**********************************************************************
2 Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de
3 All rights reserved. This program and the accompanying material
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;
12 import java.util.ArrayList;
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
15 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
16 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
17 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
18 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
19 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
20 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
21 import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
22 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
23 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
24 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
25 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
26 import org.eclipse.core.resources.IFile;
27 public class Parser //extends PHPParserSuperclass
28 implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
29 //internal data for the automat
30 protected final static int StackIncrement = 255;
31 protected int stateStackTop;
32 protected int[] stack = new int[StackIncrement];
33 public int firstToken; // handle for multiple parsing goals
34 public int lastAct; //handle for multiple parsing goals
35 protected RecoveredElement currentElement;
36 public static boolean VERBOSE_RECOVERY = false;
37 protected boolean diet = false; //tells the scanner to jump over some
38 // parts of the code/expressions like
41 public Scanner scanner;
42 private ArrayList phpList;
43 private int currentPHPString;
44 private boolean phpEnd;
45 // private static HashMap keywordMap = null;
51 // row counter for syntax errors:
53 // column counter for syntax errors:
57 // // current identifier
61 private String stringValue;
62 /** Contains the current expression. */
63 // private StringBuffer expression;
64 //private boolean phpMode;
65 protected int modifiers;
66 protected int modifiersSourceStart;
68 this.currentPHPString = 0;
69 // PHPParserSuperclass.fileToParse = fileToParse;
72 this.token = TokenNameEOF;
75 // this.columnCount = 0;
78 this.initializeScanner();
80 public void setFileToParse(IFile fileToParse) {
81 this.currentPHPString = 0;
82 // PHPParserSuperclass.fileToParse = fileToParse;
85 this.token = TokenNameEOF;
87 this.initializeScanner();
90 * ClassDeclaration Constructor.
94 * Description of Parameter
97 public Parser(IFile fileToParse) {
98 // if (keywordMap == null) {
99 // keywordMap = new HashMap();
100 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
101 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
104 this.currentPHPString = 0;
105 // PHPParserSuperclass.fileToParse = fileToParse;
108 this.token = TokenNameEOF;
110 // this.rowCount = 1;
111 // this.columnCount = 0;
114 this.initializeScanner();
116 public void initializeScanner() {
117 this.scanner = new Scanner(false, false, false, false);
120 * Create marker for the parse error
122 // private void setMarker(String message, int charStart, int charEnd, int
124 // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
127 * This method will throw the SyntaxError. It will add the good lines and
128 * columns to the Error
132 * @throws SyntaxError
135 private void throwSyntaxError(String error) {
136 int problemStartPosition = scanner.getCurrentTokenStartPosition();
137 int problemEndPosition = scanner.getCurrentTokenEndPosition();
138 throwSyntaxError(error, problemStartPosition, problemEndPosition);
141 * This method will throw the SyntaxError. It will add the good lines and
142 * columns to the Error
146 * @throws SyntaxError
149 // private void throwSyntaxError(String error, int startRow) {
150 // throw new SyntaxError(startRow, 0, " ", error);
152 private void throwSyntaxError(String error, int problemStartPosition,
153 int problemEndPosition) {
155 .phpParsingError(new String[]{error}, problemStartPosition,
156 problemEndPosition, referenceContext,
157 compilationUnit.compilationResult);
158 throw new SyntaxError(1, 0, " ", error);
160 private void reportSyntaxError(String error, int problemStartPosition,
161 int problemEndPosition) {
163 .phpParsingError(new String[]{error}, problemStartPosition,
164 problemEndPosition, referenceContext,
165 compilationUnit.compilationResult);
167 private void reportSyntaxWarning(String error, int problemStartPosition,
168 int problemEndPosition) {
169 problemReporter.phpParsingWarning(new String[]{error},
170 problemStartPosition, problemEndPosition, referenceContext,
171 compilationUnit.compilationResult);
174 * Method Declaration.
178 // private void getChar() {
179 // if (str.length() > chIndx) {
180 // ch = str.charAt(chIndx++);
185 // chIndx = str.length() + 1;
187 // // token = TokenNameEOF;
191 * gets the next token from input
193 private void getNextToken() {
195 token = scanner.getNextToken();
197 int currentEndPosition = scanner.getCurrentTokenEndPosition();
198 int currentStartPosition = scanner.getCurrentTokenStartPosition();
200 .print(currentStartPosition + "," + currentEndPosition + ": ");
201 System.out.println(scanner.toStringAction(token));
203 } catch (InvalidInputException e) {
204 token = TokenNameERROR;
209 * Get a number. if it's a <code>double</code> the number will be stored in
210 * <code>doubleNumber</code> and the token will have the value
211 * {@link Parser#TokenNameDOUBLE_NUMBER}<br />
212 * if it's a <code>double</code> the number will be stored in <code>longNumber</code>
213 * and the token will have the value {@link Parser#TokenNameINT_NUMBER}
215 // private void getNumber() {
216 // StringBuffer inum = new StringBuffer();
218 // int numFormat = 10;
220 // // save first digit
221 // char firstCh = ch;
225 // // determine number conversions:
226 // if (firstCh == '0') {
255 // if (numFormat == 16) {
256 // while ((ch >= '0' && ch <= '9')
257 // || (ch >= 'a' && ch <= 'f')
258 // || (ch >= 'A' && ch <= 'F')) {
263 // while ((ch >= '0' && ch <= '9')
267 // if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
268 // if (ch == '.' && dFlag != ' ') {
271 // if ((dFlag == 'E') || (dFlag == 'e')) {
277 // if ((ch == '-') || (ch == '+')) {
290 // if (dFlag != ' ') {
291 // doubleNumber = new Double(inum.toString());
292 // token = TokenNameDoubleLiteral;
295 // longNumber = Long.valueOf(inum.toString(), numFormat);
296 // token = TokenNameIntegerLiteral;
300 // } catch (Throwable e) {
301 // throwSyntaxError("Number format error: " + inum.toString());
307 // * @param openChar the opening char ('\'', '"', '`')
308 // * @param typeString the type of string {@link
309 // #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
310 // * @param errorMsg the error message in case of parse error in the string
312 // private void getString(
313 // final char openChar,
314 // final int typeString,
315 // final String errorMsg) {
316 // StringBuffer sBuffer = new StringBuffer();
317 // boolean openString = true;
318 // int startRow = rowCount;
319 // while (str.length() > chIndx) {
320 // ch = str.charAt(chIndx++);
322 // sBuffer.append(ch);
323 // if (str.length() > chIndx) {
324 // ch = str.charAt(chIndx++);
325 // sBuffer.append(ch);
327 // } else if (ch == openChar) {
328 // openString = false;
330 // } else if (ch == '\n') {
332 // columnCount = chIndx;
334 // sBuffer.append(ch);
338 // if (typeString == TokenNameStringConstant) {
339 // throwSyntaxError(errorMsg, startRow);
341 // throwSyntaxError(errorMsg);
344 // token = typeString;
345 // stringValue = sBuffer.toString();
347 // public void htmlParserTester(String input) {
348 // int lineNumber = 1;
349 // int startLineNumber = 1;
350 // int startIndex = 0;
353 // boolean phpMode = false;
354 // boolean phpFound = false;
356 // phpList = new ArrayList();
357 // currentPHPString = 0;
361 // while (i < input.length()) {
362 // ch = input.charAt(i++);
366 // if ((!phpMode) && ch == '<') {
367 // ch2 = input.charAt(i++);
369 // ch2 = input.charAt(i++);
370 // if (Character.isWhitespace(ch2)) {
375 // startLineNumber = lineNumber;
377 // } else if (ch2 == 'p') {
378 // ch2 = input.charAt(i++);
380 // ch2 = input.charAt(i++);
385 // startLineNumber = lineNumber;
391 // } else if (ch2 == 'P') {
392 // ch2 = input.charAt(i++);
394 // ch2 = input.charAt(i++);
399 // startLineNumber = lineNumber;
412 // if (ch == '/' && i < input.length()) {
413 // ch2 = input.charAt(i++);
415 // while (i < input.length()) {
416 // ch = input.charAt(i++);
417 // if (ch == '?' && i < input.length()) {
418 // ch2 = input.charAt(i++);
427 // startLineNumber));
431 // } else if (ch == '\n') {
437 // } else if (ch2 == '*') {
438 // // multi-line comment
439 // while (i < input.length()) {
440 // ch = input.charAt(i++);
443 // } else if (ch == '*' && i < input.length()) {
444 // ch2 = input.charAt(i++);
455 // } else if (ch == '#') {
456 // while (i < input.length()) {
457 // ch = input.charAt(i++);
458 // if (ch == '?' && i < input.length()) {
459 // ch2 = input.charAt(i++);
465 // input.substring(startIndex, i - 2),
466 // startLineNumber));
470 // } else if (ch == '\n') {
476 // } else if (ch == '"') {
478 // while (i < input.length()) {
479 // ch = input.charAt(i++);
483 // ch == '\\' && i < input.length()) { // escape
485 // } else if (ch == '"') {
490 // } else if (ch == '\'') {
492 // while (i < input.length()) {
493 // ch = input.charAt(i++);
497 // ch == '\\' && i < input.length()) { // escape
499 // } else if (ch == '\'') {
506 // if (ch == '?' && i < input.length()) {
507 // ch2 = input.charAt(i++);
513 // input.substring(startIndex, i - 2),
514 // startLineNumber));
524 // "No PHP source code found.",
530 // "Open PHP tag at end of file.",
535 // input.substring(startIndex, i - 2),
536 // startLineNumber));
538 // // for (int j=0;j<phpList.size();j++) {
539 // // String temp = ((PHPString)phpList.get(j)).getPHPString();
540 // // int startIndx = temp.length()-10;
541 // // if (startIndx<0) {
544 // // System.out.println(temp.substring(startIndx)+"?>");
546 // phpParserTester(null, 1);
547 // // PHPString temp;
548 // // for(int j=0;j<phpList.size();j++) {
549 // // temp = (PHPString) phpList.get(j);
550 // // parser.start(temp.getPHPString(), temp.getLineNumber());
553 // } catch (CoreException e) {
556 // public void phpParserTester(String s, int rowCount) {
559 // if (phpList.size() != 0) {
560 // this.str = ((PHPString) phpList.get(currentPHPString++)).getPHPString();
563 // this.token = TokenNameEOF;
564 // // this.chIndx = 0;
565 // // this.rowCount = rowCount;
566 // // this.columnCount = 0;
567 // this.phpEnd = false;
568 // this.phpMode = true;
569 // scanner.setSource(s.toCharArray());
570 // scanner.setPHPMode(true);
574 // if (token != TokenNameEOF && token != TokenNameERROR) {
577 // if (token != TokenNameEOF) {
578 // if (token == TokenNameERROR) {
579 // throwSyntaxError("Scanner error (Found unknown token: "
580 // + scanner.toStringAction(token) + ")");
582 // if (token == TokenNameRPAREN) {
583 // throwSyntaxError("Too many closing ')'; end-of-file not reached.");
585 // if (token == TokenNameRBRACE) {
586 // throwSyntaxError("Too many closing '}'; end-of-file not reached.");
588 // if (token == TokenNameRBRACKET) {
589 // throwSyntaxError("Too many closing ']'; end-of-file not reached.");
591 // if (token == TokenNameLPAREN) {
592 // throwSyntaxError("Read character '('; end-of-file not reached.");
594 // if (token == TokenNameLBRACE) {
595 // throwSyntaxError("Read character '{'; end-of-file not reached.");
597 // if (token == TokenNameLBRACKET) {
598 // throwSyntaxError("Read character '['; end-of-file not reached.");
600 // throwSyntaxError("End-of-file not reached.");
603 // } catch (SyntaxError err) {
607 // // setMarker(err.getMessage(), err.getLine(), ERROR);
608 // // setMarker(err.getMessage(),
609 // // scanner.getCurrentTokenStartPosition(),
610 // // scanner.getCurrentTokenEndPosition(), ERROR);
612 // // if an error occured,
613 // // try to find keywords 'class' or 'function'
614 // // to parse the rest of the string
615 // while (token != TokenNameEOF && token != TokenNameERROR) {
616 // if (token == TokenNameabstract || token == TokenNamefinal
617 // || token == TokenNameclass || token == TokenNamefunction) {
622 // if (token == TokenNameEOF || token == TokenNameERROR) {
628 public void init(String s) {
630 this.token = TokenNameEOF;
632 // this.rowCount = 1;
633 // this.columnCount = 0;
635 // this.phpMode = false;
636 /* scanner initialization */
637 scanner.setSource(s.toCharArray());
638 scanner.setPHPMode(false);
640 protected void initialize(boolean phpMode) {
641 compilationUnit = null;
642 referenceContext = null;
644 this.token = TokenNameEOF;
646 // this.rowCount = 1;
647 // this.columnCount = 0;
649 // this.phpMode = phpMode;
650 scanner.setPHPMode(phpMode);
653 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
656 public void parse(String s) {
661 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
664 protected void parse() {
668 if (token != TokenNameEOF && token != TokenNameERROR) {
671 if (token != TokenNameEOF) {
672 if (token == TokenNameERROR) {
673 throwSyntaxError("Scanner error (Found unknown token: "
674 + scanner.toStringAction(token) + ")");
676 if (token == TokenNameRPAREN) {
677 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
679 if (token == TokenNameRBRACE) {
680 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
682 if (token == TokenNameRBRACKET) {
683 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
685 if (token == TokenNameLPAREN) {
686 throwSyntaxError("Read character '('; end-of-file not reached.");
688 if (token == TokenNameLBRACE) {
689 throwSyntaxError("Read character '{'; end-of-file not reached.");
691 if (token == TokenNameLBRACKET) {
692 throwSyntaxError("Read character '['; end-of-file not reached.");
694 throwSyntaxError("End-of-file not reached.");
697 } catch (SyntaxError sytaxErr1) {
698 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
700 // setMarker(sytaxErr1.getMessage(),
701 // scanner.getCurrentTokenStartPosition(),
702 // scanner.getCurrentTokenEndPosition(), ERROR);
704 // if an error occured,
705 // try to find keywords 'class' or 'function'
706 // to parse the rest of the string
707 while (token != TokenNameEOF && token != TokenNameERROR) {
708 if (token == TokenNameabstract || token == TokenNamefinal
709 || token == TokenNameclass || token == TokenNamefunction) {
714 if (token == TokenNameEOF || token == TokenNameERROR) {
717 } catch (SyntaxError sytaxErr2) {
718 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
720 // setMarker(sytaxErr2.getMessage(),
721 // scanner.getCurrentTokenStartPosition(),
722 // scanner.getCurrentTokenEndPosition(), ERROR);
728 // public PHPOutlineInfo parseInfo(Object parent, String s) {
729 // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
730 // // Stack stack = new Stack();
731 // // stack.push(outlineInfo.getDeclarations());
733 // this.token = TokenNameEOF;
734 // // this.chIndx = 0;
735 // // this.rowCount = 1;
736 // // this.columnCount = 0;
737 // this.phpEnd = false;
738 // this.phpMode = false;
739 // scanner.setSource(s.toCharArray());
740 // scanner.setPHPMode(false);
743 // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
745 // return outlineInfo;
747 private boolean isVariable() {
748 return token == TokenNameVariable; // || token == TokenNamethis;
750 // private void parseDeclarations(PHPOutlineInfo outlineInfo,
751 // OutlineableWithChildren current, boolean goBack) {
753 // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
754 // PHPSegmentWithChildren temp;
756 // IPreferenceStore store =
757 // PHPeclipsePlugin.getDefault().getPreferenceStore();
759 // while (token != TokenNameEOF && token != TokenNameERROR) {
760 // if (token == TokenNameVariable) {
761 // ident = scanner.getCurrentIdentifierSource();
762 // outlineInfo.addVariable(new String(ident));
764 // } else if (token == TokenNamevar) {
766 // if (token == TokenNameVariable
767 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
768 // ident = scanner.getCurrentIdentifierSource();
769 // //substring(1) added because PHPVarDeclaration doesn't
770 // // need the $ anymore
771 // String variableName = new String(ident).substring(1);
772 // outlineInfo.addVariable(variableName);
774 // if (token != TokenNameSEMICOLON) {
776 // ident = scanner.getCurrentTokenSource();
777 // if (token > TokenNameKEYWORD) {
778 // current.add(new PHPVarDeclaration(current, variableName,
779 // // chIndx - ident.length,
780 // scanner.getCurrentTokenStartPosition(), new String(ident)));
783 // case TokenNameVariable :
784 // case TokenNamethis :
785 // current.add(new PHPVarDeclaration(current, variableName,
788 // scanner.getCurrentTokenStartPosition(), new String(
791 // case TokenNameIdentifier :
792 // current.add(new PHPVarDeclaration(current, variableName,
795 // scanner.getCurrentTokenStartPosition(), new String(
798 // case TokenNameDoubleLiteral :
799 // current.add(new PHPVarDeclaration(current, variableName
803 // scanner.getCurrentTokenStartPosition(), new String(
806 // case TokenNameIntegerLiteral :
807 // current.add(new PHPVarDeclaration(current, variableName,
810 // scanner.getCurrentTokenStartPosition(), new String(
813 // case TokenNameStringInterpolated :
814 // case TokenNameStringLiteral :
815 // current.add(new PHPVarDeclaration(current, variableName,
818 // scanner.getCurrentTokenStartPosition(), new String(
821 // case TokenNameStringConstant :
822 // current.add(new PHPVarDeclaration(current, variableName,
825 // scanner.getCurrentTokenStartPosition(), new String(
829 // current.add(new PHPVarDeclaration(current, variableName,
832 // scanner.getCurrentTokenStartPosition()));
837 // ident = scanner.getCurrentIdentifierSource();
838 // current.add(new PHPVarDeclaration(current, variableName,
839 // // chIndx - ident.length
840 // scanner.getCurrentTokenStartPosition()));
843 // } else if (token == TokenNamefunction) {
845 // if (token == TokenNameAND) {
848 // if (token == TokenNameIdentifier
849 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
850 // ident = scanner.getCurrentIdentifierSource();
851 // outlineInfo.addVariable(new String(ident));
852 // temp = new PHPFunctionDeclaration(current, new String(ident),
853 // // chIndx - ident.length
854 // scanner.getCurrentTokenStartPosition());
855 // current.add(temp);
857 // parseDeclarations(outlineInfo, temp, true);
859 // } else if (token == TokenNameclass) {
861 // if (token == TokenNameIdentifier
862 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
863 // ident = scanner.getCurrentIdentifierSource();
864 // outlineInfo.addVariable(new String(ident));
865 // temp = new PHPClassDeclaration(current, new String(ident),
866 // // chIndx - ident.len
867 // scanner.getCurrentTokenStartPosition());
868 // current.add(temp);
869 // // stack.push(temp);
871 // //skip tokens for classname, extends and others until
872 // // we have the opening '{'
873 // while (token != TokenNameLBRACE && token != TokenNameEOF
874 // && token != TokenNameERROR) {
877 // parseDeclarations(outlineInfo, temp, true);
880 // } else if ((token == TokenNameLBRACE)
881 // || (token == TokenNameDOLLAR_LBRACE)) {
884 // } else if (token == TokenNameRBRACE) {
887 // if (counter == 0 && goBack) {
890 // } else if (token == TokenNamerequire || token == TokenNamerequire_once
891 // || token == TokenNameinclude || token == TokenNameinclude_once) {
892 // ident = scanner.getCurrentTokenSource();
894 // int startPosition = scanner.getCurrentTokenStartPosition();
896 // char[] expr = scanner.getCurrentTokenSource(startPosition);
897 // outlineInfo.addVariable(new String(ident));
898 // current.add(new PHPReqIncDeclaration(current, new String(ident),
899 // // chIndx - ident.length,
900 // startPosition, new String(expr)));
906 // } catch (SyntaxError sytaxErr) {
908 // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
909 // // setMarker(sytaxErr.getMessage(),
910 // // scanner.getCurrentTokenStartPosition(),
911 // // scanner.getCurrentTokenEndPosition(), ERROR);
912 // // } catch (CoreException e) {
916 private void statementList() {
918 statement(TokenNameEOF);
919 if ((token == TokenNameRBRACE) || (token == TokenNamecase)
920 || (token == TokenNamedefault) || (token == TokenNameelse)
921 || (token == TokenNameelseif) || (token == TokenNameendif)
922 || (token == TokenNameendfor) || (token == TokenNameendforeach)
923 || (token == TokenNameendwhile) || (token == TokenNameendswitch)
924 || (token == TokenNameEOF) || (token == TokenNameERROR)) {
929 private void functionBody(MethodDeclaration methodDecl) {
930 // '{' [statement-list] '}'
931 if (token == TokenNameLBRACE) {
934 throwSyntaxError("'{' expected in compound-statement.");
936 if (token != TokenNameRBRACE) {
939 if (token == TokenNameRBRACE) {
940 methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
943 throwSyntaxError("'}' expected in compound-statement.");
946 private void statement(int previousToken) {
947 // if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
949 // char[] ident = scanner.getCurrentIdentifierSource();
950 // String keyword = new String(ident);
951 // if (token == TokenNameAT) {
953 // if (token != TokenNamerequire && token != TokenNamerequire_once
954 // && token != TokenNameinclude && token != TokenNameinclude_once
955 // && token != TokenNameIdentifier && token != TokenNameVariable
956 // && token != TokenNameStringInterpolated) {
957 // throwSyntaxError("identifier expected after '@'.");
960 // if (token == TokenNameinclude || token == TokenNameinclude_once) {
962 // if (token == TokenNameLPAREN) {
964 // if (token == TokenNameSEMICOLON) {
967 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
968 // throwSyntaxError("';' expected after 'include' or 'include_once'.");
970 // // getNextToken();
973 // concatenationExpression();
976 // } else if (token == TokenNamerequire || token == TokenNamerequire_once)
980 // if (token == TokenNameLPAREN) {
982 // if (token == TokenNameSEMICOLON) {
985 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
986 // throwSyntaxError("';' expected after 'require' or 'require_once'.");
988 // // getNextToken();
991 // concatenationExpression();
995 if (token == TokenNameif) {
997 if (token == TokenNameLPAREN) {
1000 throwSyntaxError("'(' expected after 'if' keyword.");
1003 if (token == TokenNameRPAREN) {
1006 throwSyntaxError("')' expected after 'if' condition.");
1010 } else if (token == TokenNameswitch) {
1012 if (token == TokenNameLPAREN) {
1015 throwSyntaxError("'(' expected after 'switch' keyword.");
1018 if (token == TokenNameRPAREN) {
1021 throwSyntaxError("')' expected after 'switch' condition.");
1025 } else if (token == TokenNamefor) {
1027 if (token == TokenNameLPAREN) {
1030 throwSyntaxError("'(' expected after 'for' keyword.");
1032 if (token == TokenNameSEMICOLON) {
1036 if (token == TokenNameSEMICOLON) {
1039 throwSyntaxError("';' expected after 'for'.");
1042 if (token == TokenNameSEMICOLON) {
1046 if (token == TokenNameSEMICOLON) {
1049 throwSyntaxError("';' expected after 'for'.");
1052 if (token == TokenNameRPAREN) {
1056 if (token == TokenNameRPAREN) {
1059 throwSyntaxError("')' expected after 'for'.");
1064 } else if (token == TokenNamewhile) {
1066 if (token == TokenNameLPAREN) {
1069 throwSyntaxError("'(' expected after 'while' keyword.");
1072 if (token == TokenNameRPAREN) {
1075 throwSyntaxError("')' expected after 'while' condition.");
1079 } else if (token == TokenNamedo) {
1081 if (token == TokenNameLBRACE) {
1084 throwSyntaxError("'{' expected after 'do' keyword.");
1086 if (token != TokenNameRBRACE) {
1089 if (token == TokenNameRBRACE) {
1092 throwSyntaxError("'}' expected after 'do' keyword.");
1094 if (token == TokenNamewhile) {
1096 if (token == TokenNameLPAREN) {
1099 throwSyntaxError("'(' expected after 'while' keyword.");
1102 if (token == TokenNameRPAREN) {
1105 throwSyntaxError("')' expected after 'while' condition.");
1108 throwSyntaxError("'while' expected after 'do' keyword.");
1110 if (token == TokenNameSEMICOLON) {
1113 if (token != TokenNameINLINE_HTML) {
1114 throwSyntaxError("';' expected after do-while statement.");
1119 } else if (token == TokenNameforeach) {
1121 if (token == TokenNameLPAREN) {
1124 throwSyntaxError("'(' expected after 'foreach' keyword.");
1127 if (token == TokenNameas) {
1130 throwSyntaxError("'as' expected after 'foreach' exxpression.");
1134 foreach_optional_arg();
1135 if (token == TokenNameEQUAL_GREATER) {
1139 if (token == TokenNameRPAREN) {
1142 throwSyntaxError("')' expected after 'foreach' expression.");
1146 } else if (token == TokenNamecontinue || token == TokenNamebreak
1147 || token == TokenNamereturn) {
1149 if (token != TokenNameSEMICOLON) {
1152 if (token == TokenNameSEMICOLON) {
1155 if (token != TokenNameINLINE_HTML) {
1156 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
1161 } else if (token == TokenNameecho) {
1164 if (token == TokenNameSEMICOLON) {
1167 if (token != TokenNameINLINE_HTML) {
1168 throwSyntaxError("';' expected after 'echo' statement.");
1173 } else if (token == TokenNameINLINE_HTML) {
1176 // } else if (token == TokenNameprint) {
1179 // if (token == TokenNameSEMICOLON) {
1182 // if (token != TokenNameStopPHP) {
1183 // throwSyntaxError("';' expected after 'print' statement.");
1188 } else if (token == TokenNameglobal) {
1191 if (token == TokenNameSEMICOLON) {
1194 if (token != TokenNameINLINE_HTML) {
1195 throwSyntaxError("';' expected after 'global' statement.");
1200 } else if (token == TokenNamestatic) {
1203 if (token == TokenNameSEMICOLON) {
1206 if (token != TokenNameINLINE_HTML) {
1207 throwSyntaxError("';' expected after 'static' statement.");
1212 } else if (token == TokenNameunset) {
1214 if (token == TokenNameLPAREN) {
1217 throwSyntaxError("'(' expected after 'unset' statement.");
1220 if (token == TokenNameRPAREN) {
1223 throwSyntaxError("')' expected after 'unset' statement.");
1225 if (token == TokenNameSEMICOLON) {
1228 if (token != TokenNameINLINE_HTML) {
1229 throwSyntaxError("';' expected after 'unset' statement.");
1234 } else if (token == TokenNamefunction) {
1235 MethodDeclaration methodDecl = new MethodDeclaration(
1236 this.compilationUnit.compilationResult);
1237 methodDecl.declarationSourceStart = scanner
1238 .getCurrentTokenStartPosition();
1240 functionDefinition(methodDecl);
1242 } else if (token == TokenNametry) {
1244 if (token != TokenNameLBRACE) {
1245 throwSyntaxError("'{' expected in 'try' statement.");
1249 if (token != TokenNameRBRACE) {
1250 throwSyntaxError("'}' expected in 'try' statement.");
1254 } else if (token == TokenNamecatch) {
1256 if (token != TokenNameLPAREN) {
1257 throwSyntaxError("'(' expected in 'catch' statement.");
1260 fully_qualified_class_name();
1261 if (token != TokenNameVariable) {
1262 throwSyntaxError("Variable expected in 'catch' statement.");
1265 if (token != TokenNameRPAREN) {
1266 throwSyntaxError("')' expected in 'catch' statement.");
1269 if (token != TokenNameLBRACE) {
1270 throwSyntaxError("'{' expected in 'catch' statement.");
1274 if (token != TokenNameRBRACE) {
1275 throwSyntaxError("'}' expected in 'catch' statement.");
1278 additional_catches();
1280 } else if (token == TokenNamethrow) {
1283 if (token == TokenNameSEMICOLON) {
1286 throwSyntaxError("';' expected after 'throw' exxpression.");
1289 } else if (token == TokenNamefinal || token == TokenNameabstract
1290 || token == TokenNameclass || token == TokenNameinterface) {
1291 TypeDeclaration typeDecl = new TypeDeclaration(
1292 this.compilationUnit.compilationResult);
1293 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
1294 // default super class
1295 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
1296 compilationUnit.types.add(typeDecl);
1298 pushOnAstStack(typeDecl);
1299 unticked_class_declaration_statement(typeDecl);
1300 // classBody(typeDecl);
1307 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
1308 } else if (token == TokenNameLBRACE) {
1310 if (token != TokenNameRBRACE) {
1313 if (token == TokenNameRBRACE) {
1317 throwSyntaxError("'}' expected.");
1320 if (token != TokenNameSEMICOLON) {
1323 if (token == TokenNameSEMICOLON) {
1327 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
1328 throwSyntaxError("';' expected after expression (Found token: "
1329 + scanner.toStringAction(token) + ")");
1335 private void additional_catches() {
1336 while (token == TokenNamecatch) {
1338 if (token != TokenNameLPAREN) {
1339 throwSyntaxError("'(' expected in 'catch' statement.");
1342 fully_qualified_class_name();
1343 if (token != TokenNameVariable) {
1344 throwSyntaxError("Variable expected in 'catch' statement.");
1347 if (token != TokenNameRPAREN) {
1348 throwSyntaxError("')' expected in 'catch' statement.");
1351 if (token != TokenNameLBRACE) {
1352 throwSyntaxError("'{' expected in 'catch' statement.");
1356 if (token != TokenNameRBRACE) {
1357 throwSyntaxError("'}' expected in 'catch' statement.");
1363 private void foreach_variable() {
1366 if (token == TokenNameAND) {
1371 private void foreach_optional_arg() {
1373 //| T_DOUBLE_ARROW foreach_variable
1374 if (token == TokenNameEQUAL_GREATER) {
1380 private void global_var_list() {
1382 // global_var_list ',' global_var
1386 if (token != TokenNameCOMMA) {
1392 private void global_var() {
1396 //| '$' '{' expr '}'
1397 if (token == TokenNameVariable) {
1399 } else if (token == TokenNameDOLLAR) {
1401 if (token == TokenNameLPAREN) {
1404 if (token != TokenNameLPAREN) {
1405 throwSyntaxError("')' expected in global variable.");
1413 private void static_var_list() {
1415 // static_var_list ',' T_VARIABLE
1416 //| static_var_list ',' T_VARIABLE '=' static_scalar
1418 //| T_VARIABLE '=' static_scalar
1420 if (token == TokenNameVariable) {
1422 if (token == TokenNameEQUAL) {
1426 if (token != TokenNameCOMMA) {
1435 private void unset_variables() {
1438 // | unset_variables ',' unset_variable
1443 if (token != TokenNameCOMMA) {
1449 private final void initializeModifiers() {
1451 this.modifiersSourceStart = -1;
1453 private final void checkAndSetModifiers(int flag) {
1454 this.modifiers |= flag;
1455 if (this.modifiersSourceStart < 0)
1456 this.modifiersSourceStart = this.scanner.startPosition;
1458 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1459 initializeModifiers();
1460 if (token == TokenNameinterface) {
1461 // interface_entry T_STRING
1462 // interface_extends_list
1463 // '{' class_statement_list '}'
1464 checkAndSetModifiers(AccInterface);
1466 typeDecl.modifiers = this.modifiers;
1467 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1468 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1469 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1470 typeDecl.name = scanner.getCurrentIdentifierSource();
1471 if (token > TokenNameKEYWORD) {
1472 throwSyntaxError("Don't use a keyword for interface declaration ["
1473 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1474 typeDecl.sourceEnd);
1477 interface_extends_list();
1479 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1480 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1481 typeDecl.name = new char[]{' '};
1482 throwSyntaxError("Interface name expected after keyword 'interface'.",
1483 typeDecl.sourceStart, typeDecl.sourceEnd);
1487 // class_entry_type T_STRING extends_from
1489 // '{' class_statement_list'}'
1491 typeDecl.modifiers = this.modifiers;
1493 //identifier 'extends' identifier
1494 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1495 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1496 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1497 typeDecl.name = scanner.getCurrentIdentifierSource();
1498 if (token > TokenNameKEYWORD) {
1499 throwSyntaxError("Don't use a keyword for class declaration ["
1500 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1501 typeDecl.sourceEnd);
1506 // | T_EXTENDS fully_qualified_class_name
1507 if (token == TokenNameextends) {
1509 if (token == TokenNameIdentifier) {
1512 throwSyntaxError("Class name expected after keyword 'extends'.",
1513 scanner.getCurrentTokenStartPosition(), scanner
1514 .getCurrentTokenEndPosition());
1519 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1520 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1521 typeDecl.name = new char[]{' '};
1522 throwSyntaxError("Class name expected after keyword 'class'.",
1523 typeDecl.sourceStart, typeDecl.sourceEnd);
1527 // '{' class_statement_list '}'
1528 if (token == TokenNameLBRACE) {
1530 if (token != TokenNameRBRACE) {
1531 class_statement_list();
1533 if (token == TokenNameRBRACE) {
1534 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1537 throwSyntaxError("'}' expected at end of class body.");
1540 throwSyntaxError("'{' expected at start of class body.");
1543 private void class_entry_type() {
1545 // | T_ABSTRACT T_CLASS
1546 // | T_FINAL T_CLASS
1547 if (token == TokenNameclass) {
1549 } else if (token == TokenNameabstract) {
1550 checkAndSetModifiers(AccAbstract);
1552 if (token != TokenNameclass) {
1553 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1556 } else if (token == TokenNamefinal) {
1557 checkAndSetModifiers(AccFinal);
1559 if (token != TokenNameclass) {
1560 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1564 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1567 private void interface_extends_list() {
1569 // | T_EXTENDS interface_list
1570 if (token == TokenNameextends) {
1575 private void implements_list() {
1577 // | T_IMPLEMENTS interface_list
1578 if (token == TokenNameimplements) {
1583 private void interface_list() {
1585 // fully_qualified_class_name
1586 //| interface_list ',' fully_qualified_class_name
1588 if (token == TokenNameIdentifier) {
1591 throwSyntaxError("Interface name expected after keyword 'implements'.");
1593 if (token != TokenNameCOMMA) {
1599 // private void classBody(TypeDeclaration typeDecl) {
1600 // //'{' [class-element-list] '}'
1601 // if (token == TokenNameLBRACE) {
1603 // if (token != TokenNameRBRACE) {
1604 // class_statement_list();
1606 // if (token == TokenNameRBRACE) {
1607 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1610 // throwSyntaxError("'}' expected at end of class body.");
1613 // throwSyntaxError("'{' expected at start of class body.");
1616 private void class_statement_list() {
1619 } while (token == TokenNamepublic || token == TokenNameprotected
1620 || token == TokenNameprivate || token == TokenNamestatic
1621 || token == TokenNameabstract || token == TokenNamefinal
1622 || token == TokenNamefunction || token == TokenNamevar
1623 || token == TokenNameconst);
1625 private void class_statement() {
1627 // variable_modifiers class_variable_declaration ';'
1628 // | class_constant_declaration ';'
1629 // | method_modifiers T_FUNCTION is_reference T_STRING
1630 // '(' parameter_list ')' method_body
1631 initializeModifiers();
1632 if (token == TokenNamevar) {
1633 checkAndSetModifiers(AccPublic);
1634 problemReporter.phpVarDeprecatedWarning(scanner
1635 .getCurrentTokenStartPosition(),
1636 scanner.getCurrentTokenEndPosition(), referenceContext,
1637 compilationUnit.compilationResult);
1639 class_variable_declaration();
1640 } else if (token == TokenNameconst) {
1641 class_constant_declaration();
1642 if (token != TokenNameSEMICOLON) {
1643 throwSyntaxError("';' expected after class const declaration.");
1647 boolean hasModifiers = member_modifiers();
1648 if (token == TokenNamefunction) {
1649 if (!hasModifiers) {
1650 checkAndSetModifiers(AccPublic);
1652 MethodDeclaration methodDecl = new MethodDeclaration(
1653 this.compilationUnit.compilationResult);
1654 methodDecl.declarationSourceStart = scanner
1655 .getCurrentTokenStartPosition();
1656 methodDecl.modifiers = this.modifiers;
1658 functionDefinition(methodDecl);
1660 if (!hasModifiers) {
1661 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1663 class_variable_declaration();
1666 // if (token == TokenNamefunction) {
1667 // MethodDeclaration methodDecl = new MethodDeclaration(
1668 // this.compilationUnit.compilationResult);
1669 // methodDecl.declarationSourceStart = scanner
1670 // .getCurrentTokenStartPosition();
1672 // functionDefinition(methodDecl);
1673 // } else if (token == TokenNamevar) {
1677 // throwSyntaxError("'function' or 'var' expected.");
1680 private void class_constant_declaration() {
1681 // class_constant_declaration ',' T_STRING '=' static_scalar
1682 // | T_CONST T_STRING '=' static_scalar
1683 if (token != TokenNameconst) {
1684 throwSyntaxError("'const' keyword expected in class declaration.");
1689 if (token != TokenNameIdentifier) {
1690 throwSyntaxError("Identifier expected in class const declaration.");
1693 if (token != TokenNameEQUAL) {
1694 throwSyntaxError("'=' expected in class const declaration.");
1698 if (token != TokenNameCOMMA) {
1699 break; // while(true)-loop
1704 // private void variable_modifiers() {
1705 // // variable_modifiers:
1706 // // non_empty_member_modifiers
1708 // initializeModifiers();
1709 // if (token == TokenNamevar) {
1710 // checkAndSetModifiers(AccPublic);
1711 // reportSyntaxError(
1712 // "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected'
1713 // modifier for field declarations.",
1714 // scanner.getCurrentTokenStartPosition(), scanner
1715 // .getCurrentTokenEndPosition());
1718 // if (!member_modifiers()) {
1719 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1720 // field declarations.");
1724 // private void method_modifiers() {
1725 // //method_modifiers:
1727 // //| non_empty_member_modifiers
1728 // initializeModifiers();
1729 // if (!member_modifiers()) {
1730 // checkAndSetModifiers(AccPublic);
1733 private boolean member_modifiers() {
1740 boolean foundToken = false;
1742 if (token == TokenNamepublic) {
1743 checkAndSetModifiers(AccPublic);
1746 } else if (token == TokenNameprotected) {
1747 checkAndSetModifiers(AccProtected);
1750 } else if (token == TokenNameprivate) {
1751 checkAndSetModifiers(AccPrivate);
1754 } else if (token == TokenNamestatic) {
1755 checkAndSetModifiers(AccStatic);
1758 } else if (token == TokenNameabstract) {
1759 checkAndSetModifiers(AccAbstract);
1762 } else if (token == TokenNamefinal) {
1763 checkAndSetModifiers(AccFinal);
1772 private void class_variable_declaration() {
1773 // class_variable_declaration:
1774 // class_variable_declaration ',' T_VARIABLE
1775 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1777 // | T_VARIABLE '=' static_scalar
1779 if (token == TokenNameVariable) {
1781 if (token == TokenNameEQUAL) {
1786 // if (token == TokenNamethis) {
1787 // throwSyntaxError("'$this' not allowed after keyword 'public'
1788 // 'protected' 'private' 'var'.");
1790 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1792 if (token != TokenNameCOMMA) {
1797 if (token != TokenNameSEMICOLON) {
1798 throwSyntaxError("';' expected after field declaration.");
1802 private void functionDefinition(MethodDeclaration methodDecl) {
1803 boolean isAbstract = false;
1805 compilationUnit.types.add(methodDecl);
1807 AstNode node = astStack[astPtr];
1808 if (node instanceof TypeDeclaration) {
1809 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1810 if (typeDecl.methods == null) {
1811 typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1813 AbstractMethodDeclaration[] newMethods;
1818 newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1819 1, typeDecl.methods.length);
1820 newMethods[0] = methodDecl;
1821 typeDecl.methods = newMethods;
1823 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1825 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1830 functionDeclarator(methodDecl);
1831 if (token == TokenNameSEMICOLON) {
1833 throwSyntaxError("Body declaration expected for method: "
1834 + new String(methodDecl.selector));
1839 functionBody(methodDecl);
1841 private void functionDeclarator(MethodDeclaration methodDecl) {
1842 //identifier '(' [parameter-list] ')'
1843 if (token == TokenNameAND) {
1846 if (token == TokenNameIdentifier) {
1847 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1848 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1849 methodDecl.selector = scanner.getCurrentIdentifierSource();
1851 if (token == TokenNameLPAREN) {
1854 throwSyntaxError("'(' expected in function declaration.");
1856 if (token != TokenNameRPAREN) {
1859 if (token != TokenNameRPAREN) {
1860 throwSyntaxError("')' expected in function declaration.");
1862 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1866 if (token > TokenNameKEYWORD) {
1867 throwSyntaxError("Don't use keyword for function declaration [" + token
1870 throwSyntaxError("Function name expected after keyword 'function'.");
1874 private void parameter_list() {
1875 // non_empty_parameter_list
1877 non_empty_parameter_list(true);
1879 private void non_empty_parameter_list(boolean empty_allowed) {
1880 // optional_class_type T_VARIABLE
1881 // | optional_class_type '&' T_VARIABLE
1882 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1883 // | optional_class_type T_VARIABLE '=' static_scalar
1884 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1885 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1886 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1888 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1890 if (token == TokenNameIdentifier || token == TokenNameVariable
1891 || token == TokenNameAND) {
1893 if (token == TokenNameIdentifier) {
1896 if (token == TokenNameAND) {
1899 if (token == TokenNameVariable) {
1901 if (token == TokenNameEQUAL) {
1906 throwSyntaxError("Variable expected in parameter list.");
1908 if (token != TokenNameCOMMA) {
1915 if (!empty_allowed) {
1916 throwSyntaxError("Identifier expected in parameter list.");
1919 private void optional_class_type() {
1923 private void parameterDeclaration() {
1925 //variable-reference
1926 if (token == TokenNameAND) {
1931 throwSyntaxError("Variable expected after reference operator '&'.");
1934 //variable '=' constant
1935 if (token == TokenNameVariable) {
1937 if (token == TokenNameEQUAL) {
1943 // if (token == TokenNamethis) {
1944 // throwSyntaxError("Reserved word '$this' not allowed in parameter
1948 private void labeledStatementList() {
1949 if (token != TokenNamecase && token != TokenNamedefault) {
1950 throwSyntaxError("'case' or 'default' expected.");
1953 if (token == TokenNamecase) {
1955 expr(); //constant();
1956 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1958 if (token == TokenNamecase || token == TokenNamedefault) { // empty
1966 // else if (token == TokenNameSEMICOLON) {
1968 // "':' expected after 'case' keyword (Found token: " +
1969 // scanner.toStringAction(token) + ")",
1970 // scanner.getCurrentTokenStartPosition(),
1971 // scanner.getCurrentTokenEndPosition(),
1974 // if (token == TokenNamecase) { // empty case statement ?
1980 throwSyntaxError("':' character after 'case' constant expected (Found token: "
1981 + scanner.toStringAction(token) + ")");
1983 } else { // TokenNamedefault
1985 if (token == TokenNameCOLON) {
1989 throwSyntaxError("':' character after 'default' expected.");
1992 } while (token == TokenNamecase || token == TokenNamedefault);
1994 // public void labeledStatement() {
1995 // if (token == TokenNamecase) {
1998 // if (token == TokenNameDDOT) {
2002 // throwSyntaxError("':' character after 'case' constant expected.");
2005 // } else if (token == TokenNamedefault) {
2007 // if (token == TokenNameDDOT) {
2011 // throwSyntaxError("':' character after 'default' expected.");
2016 // public void expressionStatement() {
2018 // private void inclusionStatement() {
2020 // public void compoundStatement() {
2022 // public void selectionStatement() {
2025 // public void iterationStatement() {
2028 // public void jumpStatement() {
2031 // public void outputStatement() {
2034 // public void scopeStatement() {
2037 // public void flowStatement() {
2040 // public void definitionStatement() {
2042 private void ifStatement() {
2043 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
2044 if (token == TokenNameCOLON) {
2046 if (token != TokenNameendif) {
2049 case TokenNameelse :
2051 if (token == TokenNameCOLON) {
2053 if (token != TokenNameendif) {
2057 if (token == TokenNameif) { //'else if'
2059 elseifStatementList();
2061 throwSyntaxError("':' expected after 'else'.");
2065 case TokenNameelseif :
2067 elseifStatementList();
2071 if (token != TokenNameendif) {
2072 throwSyntaxError("'endif' expected.");
2075 if (token != TokenNameSEMICOLON) {
2076 throwSyntaxError("';' expected after if-statement.");
2080 // statement [else-statement]
2081 statement(TokenNameEOF);
2082 if (token == TokenNameelseif) {
2084 if (token == TokenNameLPAREN) {
2087 throwSyntaxError("'(' expected after 'elseif' keyword.");
2090 if (token == TokenNameRPAREN) {
2093 throwSyntaxError("')' expected after 'elseif' condition.");
2096 } else if (token == TokenNameelse) {
2098 statement(TokenNameEOF);
2102 private void elseifStatementList() {
2106 case TokenNameelse :
2108 if (token == TokenNameCOLON) {
2110 if (token != TokenNameendif) {
2115 if (token == TokenNameif) { //'else if'
2118 throwSyntaxError("':' expected after 'else'.");
2122 case TokenNameelseif :
2130 private void elseifStatement() {
2131 if (token == TokenNameLPAREN) {
2134 if (token != TokenNameRPAREN) {
2135 throwSyntaxError("')' expected in else-if-statement.");
2138 if (token != TokenNameCOLON) {
2139 throwSyntaxError("':' expected in else-if-statement.");
2142 if (token != TokenNameendif) {
2147 private void switchStatement() {
2148 if (token == TokenNameCOLON) {
2149 // ':' [labeled-statement-list] 'endswitch' ';'
2151 labeledStatementList();
2152 if (token != TokenNameendswitch) {
2153 throwSyntaxError("'endswitch' expected.");
2156 if (token != TokenNameSEMICOLON) {
2157 throwSyntaxError("';' expected after switch-statement.");
2161 // '{' [labeled-statement-list] '}'
2162 if (token != TokenNameLBRACE) {
2163 throwSyntaxError("'{' expected in switch statement.");
2166 if (token != TokenNameRBRACE) {
2167 labeledStatementList();
2169 if (token != TokenNameRBRACE) {
2170 throwSyntaxError("'}' expected in switch statement.");
2175 private void forStatement() {
2176 if (token == TokenNameCOLON) {
2179 if (token != TokenNameendfor) {
2180 throwSyntaxError("'endfor' expected.");
2183 if (token != TokenNameSEMICOLON) {
2184 throwSyntaxError("';' expected after for-statement.");
2188 statement(TokenNameEOF);
2191 private void whileStatement() {
2192 // ':' statement-list 'endwhile' ';'
2193 if (token == TokenNameCOLON) {
2196 if (token != TokenNameendwhile) {
2197 throwSyntaxError("'endwhile' expected.");
2200 if (token != TokenNameSEMICOLON) {
2201 throwSyntaxError("';' expected after while-statement.");
2205 statement(TokenNameEOF);
2208 private void foreachStatement() {
2209 if (token == TokenNameCOLON) {
2212 if (token != TokenNameendforeach) {
2213 throwSyntaxError("'endforeach' expected.");
2216 if (token != TokenNameSEMICOLON) {
2217 throwSyntaxError("';' expected after foreach-statement.");
2221 statement(TokenNameEOF);
2224 // private void exitStatus() {
2225 // if (token == TokenNameLPAREN) {
2228 // throwSyntaxError("'(' expected in 'exit-status'.");
2230 // if (token != TokenNameRPAREN) {
2233 // if (token == TokenNameRPAREN) {
2236 // throwSyntaxError("')' expected after 'exit-status'.");
2239 private void expressionList() {
2242 if (token == TokenNameCOMMA) {
2249 private void expr() {
2251 // | expr_without_variable
2252 // if (token!=TokenNameEOF) {
2253 if (Scanner.TRACE) {
2254 System.out.println("TRACE: expr()");
2256 expr_without_variable(true);
2259 private void expr_without_variable(boolean only_variable) {
2260 // internal_functions_in_yacc
2269 // | T_INC rw_variable
2270 // | T_DEC rw_variable
2271 // | T_INT_CAST expr
2272 // | T_DOUBLE_CAST expr
2273 // | T_STRING_CAST expr
2274 // | T_ARRAY_CAST expr
2275 // | T_OBJECT_CAST expr
2276 // | T_BOOL_CAST expr
2277 // | T_UNSET_CAST expr
2278 // | T_EXIT exit_expr
2280 // | T_ARRAY '(' array_pair_list ')'
2281 // | '`' encaps_list '`'
2282 // | T_LIST '(' assignment_list ')' '=' expr
2283 // | T_NEW class_name_reference ctor_arguments
2284 // | variable '=' expr
2285 // | variable '=' '&' variable
2286 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2287 // | variable T_PLUS_EQUAL expr
2288 // | variable T_MINUS_EQUAL expr
2289 // | variable T_MUL_EQUAL expr
2290 // | variable T_DIV_EQUAL expr
2291 // | variable T_CONCAT_EQUAL expr
2292 // | variable T_MOD_EQUAL expr
2293 // | variable T_AND_EQUAL expr
2294 // | variable T_OR_EQUAL expr
2295 // | variable T_XOR_EQUAL expr
2296 // | variable T_SL_EQUAL expr
2297 // | variable T_SR_EQUAL expr
2298 // | rw_variable T_INC
2299 // | rw_variable T_DEC
2300 // | expr T_BOOLEAN_OR expr
2301 // | expr T_BOOLEAN_AND expr
2302 // | expr T_LOGICAL_OR expr
2303 // | expr T_LOGICAL_AND expr
2304 // | expr T_LOGICAL_XOR expr
2316 // | expr T_IS_IDENTICAL expr
2317 // | expr T_IS_NOT_IDENTICAL expr
2318 // | expr T_IS_EQUAL expr
2319 // | expr T_IS_NOT_EQUAL expr
2321 // | expr T_IS_SMALLER_OR_EQUAL expr
2323 // | expr T_IS_GREATER_OR_EQUAL expr
2324 // | expr T_INSTANCEOF class_name_reference
2325 // | expr '?' expr ':' expr
2326 if (Scanner.TRACE) {
2327 System.out.println("TRACE: expr_without_variable() PART 1");
2330 case TokenNameisset :
2331 case TokenNameempty :
2332 case TokenNameeval :
2333 case TokenNameinclude :
2334 case TokenNameinclude_once :
2335 case TokenNamerequire :
2336 case TokenNamerequire_once :
2337 internal_functions_in_yacc();
2340 case TokenNameLPAREN :
2343 if (token == TokenNameRPAREN) {
2346 throwSyntaxError("')' expected in expression.");
2356 // | T_INT_CAST expr
2357 // | T_DOUBLE_CAST expr
2358 // | T_STRING_CAST expr
2359 // | T_ARRAY_CAST expr
2360 // | T_OBJECT_CAST expr
2361 // | T_BOOL_CAST expr
2362 // | T_UNSET_CAST expr
2363 case TokenNameclone :
2364 case TokenNameprint :
2366 case TokenNamePLUS :
2367 case TokenNameMINUS :
2369 case TokenNameTWIDDLE :
2370 case TokenNameintCAST :
2371 case TokenNamedoubleCAST :
2372 case TokenNamestringCAST :
2373 case TokenNamearrayCAST :
2374 case TokenNameobjectCAST :
2375 case TokenNameboolCAST :
2376 case TokenNameunsetCAST :
2380 case TokenNameexit :
2386 //| T_STRING_VARNAME
2388 //| '"' encaps_list '"'
2389 //| '\'' encaps_list '\''
2390 //| T_START_HEREDOC encaps_list T_END_HEREDOC
2391 // | '`' encaps_list '`'
2393 case TokenNameIntegerLiteral :
2394 case TokenNameDoubleLiteral :
2395 case TokenNameStringLiteral :
2396 case TokenNameStringConstant :
2397 case TokenNameStringInterpolated :
2398 case TokenNameFILE :
2399 case TokenNameLINE :
2400 case TokenNameCLASS_C :
2401 case TokenNameMETHOD_C :
2402 case TokenNameFUNC_C :
2405 case TokenNameHEREDOC :
2408 case TokenNamearray :
2409 // T_ARRAY '(' array_pair_list ')'
2411 if (token == TokenNameLPAREN) {
2413 if (token == TokenNameRPAREN) {
2418 if (token != TokenNameRPAREN) {
2419 throwSyntaxError("')' expected after keyword 'array'"
2420 + "(Found token: " + scanner.toStringAction(token) + ")");
2424 throwSyntaxError("'(' expected after keyword 'array'"
2425 + "(Found token: " + scanner.toStringAction(token) + ")");
2428 case TokenNamelist :
2429 // | T_LIST '(' assignment_list ')' '=' expr
2431 if (token == TokenNameLPAREN) {
2434 if (token != TokenNameRPAREN) {
2435 throwSyntaxError("')' expected after 'list' keyword.");
2438 if (token != TokenNameEQUAL) {
2439 throwSyntaxError("'=' expected after 'list' keyword.");
2444 throwSyntaxError("'(' expected after 'list' keyword.");
2448 // | T_NEW class_name_reference ctor_arguments
2450 class_name_reference();
2453 // | T_INC rw_variable
2454 // | T_DEC rw_variable
2455 case TokenNamePLUS_PLUS :
2456 case TokenNameMINUS_MINUS :
2460 // | variable '=' expr
2461 // | variable '=' '&' variable
2462 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2463 // | variable T_PLUS_EQUAL expr
2464 // | variable T_MINUS_EQUAL expr
2465 // | variable T_MUL_EQUAL expr
2466 // | variable T_DIV_EQUAL expr
2467 // | variable T_CONCAT_EQUAL expr
2468 // | variable T_MOD_EQUAL expr
2469 // | variable T_AND_EQUAL expr
2470 // | variable T_OR_EQUAL expr
2471 // | variable T_XOR_EQUAL expr
2472 // | variable T_SL_EQUAL expr
2473 // | variable T_SR_EQUAL expr
2474 // | rw_variable T_INC
2475 // | rw_variable T_DEC
2476 case TokenNameIdentifier :
2477 case TokenNameVariable :
2478 case TokenNameDOLLAR :
2481 case TokenNameEQUAL :
2483 if (token == TokenNameAND) {
2485 if (token == TokenNamenew) {
2487 throwSyntaxError("not yet implemented (= & new)");
2488 // class_name_reference();
2489 // ctor_arguments();
2497 case TokenNamePLUS_EQUAL :
2498 case TokenNameMINUS_EQUAL :
2499 case TokenNameMULTIPLY_EQUAL :
2500 case TokenNameDIVIDE_EQUAL :
2501 case TokenNameDOT_EQUAL :
2502 case TokenNameREMAINDER_EQUAL :
2503 case TokenNameAND_EQUAL :
2504 case TokenNameOR_EQUAL :
2505 case TokenNameXOR_EQUAL :
2506 case TokenNameRIGHT_SHIFT_EQUAL :
2507 case TokenNameLEFT_SHIFT_EQUAL :
2511 case TokenNamePLUS_PLUS :
2512 case TokenNameMINUS_MINUS :
2516 if (!only_variable) {
2517 throwSyntaxError("Variable expression not allowed (found token '"
2518 + scanner.toStringAction(token) + "').");
2523 if (token != TokenNameINLINE_HTML) {
2524 throwSyntaxError("Error in expression (found token '"
2525 + scanner.toStringAction(token) + "').");
2529 if (Scanner.TRACE) {
2530 System.out.println("TRACE: expr_without_variable() PART 2");
2532 // | expr T_BOOLEAN_OR expr
2533 // | expr T_BOOLEAN_AND expr
2534 // | expr T_LOGICAL_OR expr
2535 // | expr T_LOGICAL_AND expr
2536 // | expr T_LOGICAL_XOR expr
2548 // | expr T_IS_IDENTICAL expr
2549 // | expr T_IS_NOT_IDENTICAL expr
2550 // | expr T_IS_EQUAL expr
2551 // | expr T_IS_NOT_EQUAL expr
2553 // | expr T_IS_SMALLER_OR_EQUAL expr
2555 // | expr T_IS_GREATER_OR_EQUAL expr
2558 case TokenNameOR_OR :
2559 case TokenNameAND_AND :
2567 case TokenNamePLUS :
2568 case TokenNameMINUS :
2569 case TokenNameMULTIPLY :
2570 case TokenNameDIVIDE :
2571 case TokenNameREMAINDER :
2572 case TokenNameLEFT_SHIFT :
2573 case TokenNameRIGHT_SHIFT :
2574 case TokenNameEQUAL_EQUAL_EQUAL :
2575 case TokenNameNOT_EQUAL_EQUAL :
2576 case TokenNameEQUAL_EQUAL :
2577 case TokenNameNOT_EQUAL :
2578 case TokenNameLESS :
2579 case TokenNameLESS_EQUAL :
2580 case TokenNameGREATER :
2581 case TokenNameGREATER_EQUAL :
2585 // | expr T_INSTANCEOF class_name_reference
2586 // | expr '?' expr ':' expr
2587 case TokenNameinstanceof :
2589 class_name_reference();
2591 case TokenNameQUESTION :
2594 if (token == TokenNameCOLON) {
2604 private void class_name_reference() {
2605 // class_name_reference:
2607 //| dynamic_class_name_reference
2608 if (Scanner.TRACE) {
2609 System.out.println("TRACE: class_name_reference()");
2611 if (token == TokenNameIdentifier) {
2614 dynamic_class_name_reference();
2617 private void dynamic_class_name_reference() {
2618 //dynamic_class_name_reference:
2619 // base_variable T_OBJECT_OPERATOR object_property
2620 // dynamic_class_name_variable_properties
2622 if (Scanner.TRACE) {
2623 System.out.println("TRACE: dynamic_class_name_reference()");
2626 if (token == TokenNameMINUS_GREATER) {
2629 dynamic_class_name_variable_properties();
2632 private void dynamic_class_name_variable_properties() {
2633 // dynamic_class_name_variable_properties:
2634 // dynamic_class_name_variable_properties
2635 // dynamic_class_name_variable_property
2637 if (Scanner.TRACE) {
2638 System.out.println("TRACE: dynamic_class_name_variable_properties()");
2640 while (token == TokenNameMINUS_GREATER) {
2641 dynamic_class_name_variable_property();
2644 private void dynamic_class_name_variable_property() {
2645 // dynamic_class_name_variable_property:
2646 // T_OBJECT_OPERATOR object_property
2647 if (Scanner.TRACE) {
2648 System.out.println("TRACE: dynamic_class_name_variable_property()");
2650 if (token == TokenNameMINUS_GREATER) {
2655 private void ctor_arguments() {
2658 //| '(' function_call_parameter_list ')'
2659 if (token == TokenNameLPAREN) {
2661 if (token == TokenNameRPAREN) {
2665 non_empty_function_call_parameter_list();
2666 if (token != TokenNameRPAREN) {
2667 throwSyntaxError("')' expected in ctor_arguments.");
2672 private void assignment_list() {
2674 // assignment_list ',' assignment_list_element
2675 //| assignment_list_element
2677 assignment_list_element();
2678 if (token != TokenNameCOMMA) {
2684 private void assignment_list_element() {
2685 //assignment_list_element:
2687 //| T_LIST '(' assignment_list ')'
2689 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2692 if (token == TokenNamelist) {
2694 if (token == TokenNameLPAREN) {
2697 if (token != TokenNameRPAREN) {
2698 throwSyntaxError("')' expected after 'list' keyword.");
2702 throwSyntaxError("'(' expected after 'list' keyword.");
2707 private void array_pair_list() {
2710 //| non_empty_array_pair_list possible_comma
2711 non_empty_array_pair_list();
2712 if (token == TokenNameCOMMA) {
2716 private void non_empty_array_pair_list() {
2717 //non_empty_array_pair_list:
2718 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2719 //| non_empty_array_pair_list ',' expr
2720 //| expr T_DOUBLE_ARROW expr
2722 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2723 //| non_empty_array_pair_list ',' '&' w_variable
2724 //| expr T_DOUBLE_ARROW '&' w_variable
2728 if (token == TokenNameAND) {
2732 } else if (token == TokenNameEQUAL_GREATER) {
2734 if (token == TokenNameAND) {
2741 if (token != TokenNameCOMMA) {
2745 if (token == TokenNameRPAREN) {
2750 // private void variableList() {
2753 // if (token == TokenNameCOMMA) {
2760 private void variable_without_objects() {
2761 // variable_without_objects:
2762 // reference_variable
2763 // | simple_indirect_reference reference_variable
2764 if (Scanner.TRACE) {
2765 System.out.println("TRACE: variable_without_objects()");
2767 while (token == TokenNameDOLLAR) {
2770 reference_variable();
2772 private void function_call() {
2774 // T_STRING '(' function_call_parameter_list ')'
2775 //| class_constant '(' function_call_parameter_list ')'
2776 //| static_member '(' function_call_parameter_list ')'
2777 //| variable_without_objects '(' function_call_parameter_list ')'
2778 if (Scanner.TRACE) {
2779 System.out.println("TRACE: function_call()");
2781 if (token == TokenNameIdentifier) {
2784 case TokenNamePAAMAYIM_NEKUDOTAYIM :
2787 if (token == TokenNameIdentifier) {
2792 variable_without_objects();
2797 variable_without_objects();
2799 if (token != TokenNameLPAREN) {
2800 // TODO is this ok ?
2802 // throwSyntaxError("'(' expected in function call.");
2805 if (token == TokenNameRPAREN) {
2809 non_empty_function_call_parameter_list();
2810 if (token != TokenNameRPAREN) {
2811 throwSyntaxError("')' expected in function call.");
2815 // private void function_call_parameter_list() {
2816 // function_call_parameter_list:
2817 // non_empty_function_call_parameter_list { $$ = $1; }
2820 private void non_empty_function_call_parameter_list() {
2821 //non_empty_function_call_parameter_list:
2822 // expr_without_variable
2825 // | non_empty_function_call_parameter_list ',' expr_without_variable
2826 // | non_empty_function_call_parameter_list ',' variable
2827 // | non_empty_function_call_parameter_list ',' '&' w_variable
2828 if (Scanner.TRACE) {
2829 System.out.println("TRACE: non_empty_function_call_parameter_list()");
2832 if (token == TokenNameAND) {
2836 // if (token == TokenNameIdentifier || token == TokenNameVariable
2837 // || token == TokenNameDOLLAR) {
2840 expr_without_variable(true);
2843 if (token != TokenNameCOMMA) {
2849 private void fully_qualified_class_name() {
2850 if (token == TokenNameIdentifier) {
2853 throwSyntaxError("Class name expected.");
2856 private void static_member() {
2858 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2859 // variable_without_objects
2860 if (Scanner.TRACE) {
2861 System.out.println("TRACE: static_member()");
2863 fully_qualified_class_name();
2864 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2865 throwSyntaxError("'::' expected after class name (static_member).");
2868 variable_without_objects();
2870 private void base_variable_with_function_calls() {
2871 // base_variable_with_function_calls:
2874 boolean functionCall = false;
2875 if (Scanner.TRACE) {
2876 System.out.println("TRACE: base_variable_with_function_calls()");
2878 if (token == TokenNameIdentifier) {
2879 functionCall = true;
2880 } else if (token == TokenNameVariable) {
2881 int tempToken = token;
2882 int tempPosition = scanner.currentPosition;
2884 if (token == TokenNameLPAREN) {
2885 functionCall = true;
2888 scanner.currentPosition = tempPosition;
2889 scanner.phpMode = true;
2897 private void base_variable() {
2899 // reference_variable
2900 // | simple_indirect_reference reference_variable
2902 if (Scanner.TRACE) {
2903 System.out.println("TRACE: base_variable()");
2905 if (token == TokenNameIdentifier) {
2908 while (token == TokenNameDOLLAR) {
2911 reference_variable();
2914 // private void simple_indirect_reference() {
2915 // // simple_indirect_reference:
2917 // //| simple_indirect_reference '$'
2919 private void reference_variable() {
2920 // reference_variable:
2921 // reference_variable '[' dim_offset ']'
2922 // | reference_variable '{' expr '}'
2923 // | compound_variable
2924 if (Scanner.TRACE) {
2925 System.out.println("TRACE: reference_variable()");
2927 compound_variable();
2929 if (token == TokenNameLBRACE) {
2932 if (token != TokenNameRBRACE) {
2933 throwSyntaxError("'}' expected in reference variable.");
2936 } else if (token == TokenNameLBRACKET) {
2938 if (token != TokenNameRBRACKET) {
2941 if (token != TokenNameRBRACKET) {
2942 throwSyntaxError("']' expected in reference variable.");
2951 private void compound_variable() {
2952 // compound_variable:
2954 // | '$' '{' expr '}'
2955 if (Scanner.TRACE) {
2956 System.out.println("TRACE: compound_variable()");
2958 if (token == TokenNameVariable) {
2961 // because of simple_indirect_reference
2962 while (token == TokenNameDOLLAR) {
2965 if (token != TokenNameLBRACE) {
2966 throwSyntaxError("'{' expected after compound variable token '$'.");
2970 if (token != TokenNameRBRACE) {
2971 throwSyntaxError("'}' expected after compound variable token '$'.");
2976 // private void dim_offset() {
2982 private void object_property() {
2985 //| variable_without_objects
2986 if (Scanner.TRACE) {
2987 System.out.println("TRACE: object_property()");
2989 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2990 variable_without_objects();
2995 private void object_dim_list() {
2997 // object_dim_list '[' dim_offset ']'
2998 //| object_dim_list '{' expr '}'
3000 if (Scanner.TRACE) {
3001 System.out.println("TRACE: object_dim_list()");
3005 if (token == TokenNameLBRACE) {
3008 if (token != TokenNameRBRACE) {
3009 throwSyntaxError("'}' expected in object_dim_list.");
3012 } else if (token == TokenNameLBRACKET) {
3014 if (token == TokenNameRBRACKET) {
3019 if (token != TokenNameRBRACKET) {
3020 throwSyntaxError("']' expected in object_dim_list.");
3028 private void variable_name() {
3032 if (Scanner.TRACE) {
3033 System.out.println("TRACE: variable_name()");
3035 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3036 if (token > TokenNameKEYWORD) {
3037 // TODO show a warning "Keyword used as variable" ?
3041 if (token != TokenNameLBRACE) {
3042 throwSyntaxError("'{' expected in variable name.");
3046 if (token != TokenNameRBRACE) {
3047 throwSyntaxError("'}' expected in variable name.");
3051 private void r_variable() {
3054 private void w_variable() {
3057 private void rw_variable() {
3060 private void variable() {
3062 // base_variable_with_function_calls T_OBJECT_OPERATOR
3063 // object_property method_or_not variable_properties
3064 // | base_variable_with_function_calls
3065 base_variable_with_function_calls();
3066 if (token == TokenNameMINUS_GREATER) {
3070 variable_properties();
3072 // if (token == TokenNameDOLLAR_LBRACE) {
3076 // if (token != TokenNameRBRACE) {
3077 // throwSyntaxError("'}' expected after indirect variable token '${'.");
3081 // if (token == TokenNameVariable) {
3083 // if (token == TokenNameLBRACKET) {
3086 // if (token != TokenNameRBRACKET) {
3087 // throwSyntaxError("']' expected in variable-list.");
3090 // } else if (token == TokenNameEQUAL) {
3095 // throwSyntaxError("$-variable expected in variable-list.");
3099 private void variable_properties() {
3100 // variable_properties:
3101 // variable_properties variable_property
3103 while (token == TokenNameMINUS_GREATER) {
3104 variable_property();
3107 private void variable_property() {
3108 // variable_property:
3109 // T_OBJECT_OPERATOR object_property method_or_not
3110 if (Scanner.TRACE) {
3111 System.out.println("TRACE: variable_property()");
3113 if (token == TokenNameMINUS_GREATER) {
3118 throwSyntaxError("'->' expected in variable_property.");
3121 private void method_or_not() {
3123 // '(' function_call_parameter_list ')'
3125 if (Scanner.TRACE) {
3126 System.out.println("TRACE: method_or_not()");
3128 if (token == TokenNameLPAREN) {
3130 if (token == TokenNameRPAREN) {
3134 non_empty_function_call_parameter_list();
3135 if (token != TokenNameRPAREN) {
3136 throwSyntaxError("')' expected in method_or_not.");
3141 private void exit_expr() {
3145 if (token != TokenNameLPAREN) {
3149 if (token == TokenNameRPAREN) {
3154 if (token != TokenNameRPAREN) {
3155 throwSyntaxError("')' expected after keyword 'exit'");
3159 private void internal_functions_in_yacc() {
3161 case TokenNameisset :
3162 // T_ISSET '(' isset_variables ')'
3164 if (token != TokenNameLPAREN) {
3165 throwSyntaxError("'(' expected after keyword 'isset'");
3169 if (token != TokenNameRPAREN) {
3170 throwSyntaxError("')' expected after keyword 'isset'");
3174 case TokenNameempty :
3175 // T_EMPTY '(' variable ')'
3177 if (token != TokenNameLPAREN) {
3178 throwSyntaxError("'(' expected after keyword 'empty'");
3182 if (token != TokenNameRPAREN) {
3183 throwSyntaxError("')' expected after keyword 'empty'");
3187 case TokenNameinclude :
3192 case TokenNameinclude_once :
3193 // T_INCLUDE_ONCE expr
3197 case TokenNameeval :
3198 // T_EVAL '(' expr ')'
3200 if (token != TokenNameLPAREN) {
3201 throwSyntaxError("'(' expected after keyword 'eval'");
3205 if (token != TokenNameRPAREN) {
3206 throwSyntaxError("')' expected after keyword 'eval'");
3210 case TokenNamerequire :
3215 case TokenNamerequire_once :
3216 // T_REQUIRE_ONCE expr
3222 private void isset_variables() {
3224 // | isset_variables ','
3225 if (token == TokenNameRPAREN) {
3226 throwSyntaxError("Variable expected after keyword 'isset'");
3230 if (token == TokenNameCOMMA) {
3237 private boolean common_scalar() {
3241 // | T_CONSTANT_ENCAPSED_STRING
3248 case TokenNameIntegerLiteral :
3251 case TokenNameDoubleLiteral :
3254 case TokenNameStringLiteral :
3257 case TokenNameStringConstant :
3260 case TokenNameStringInterpolated :
3263 case TokenNameFILE :
3266 case TokenNameLINE :
3269 case TokenNameCLASS_C :
3272 case TokenNameMETHOD_C :
3275 case TokenNameFUNC_C :
3281 private void scalar() {
3284 //| T_STRING_VARNAME
3287 //| '"' encaps_list '"'
3288 //| '\'' encaps_list '\''
3289 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3290 throwSyntaxError("Not yet implemented (scalar).");
3292 private void static_scalar() {
3293 // static_scalar: /* compile-time evaluated scalars */
3296 // | '+' static_scalar
3297 // | '-' static_scalar
3298 // | T_ARRAY '(' static_array_pair_list ')'
3299 // | static_class_constant
3300 if (common_scalar()) {
3304 case TokenNameIdentifier :
3306 // static_class_constant:
3307 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3308 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3310 if (token == TokenNameIdentifier) {
3313 throwSyntaxError("Identifier expected after '::' operator.");
3317 case TokenNamePLUS :
3321 case TokenNameMINUS :
3325 case TokenNamearray :
3327 if (token != TokenNameLPAREN) {
3328 throwSyntaxError("'(' expected after keyword 'array'");
3331 if (token == TokenNameRPAREN) {
3335 non_empty_static_array_pair_list();
3336 if (token != TokenNameRPAREN) {
3337 throwSyntaxError("')' expected after keyword 'array'");
3341 // case TokenNamenull :
3344 // case TokenNamefalse :
3347 // case TokenNametrue :
3351 throwSyntaxError("Static scalar/constant expected.");
3354 private void non_empty_static_array_pair_list() {
3355 // non_empty_static_array_pair_list:
3356 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3358 //| non_empty_static_array_pair_list ',' static_scalar
3359 //| static_scalar T_DOUBLE_ARROW static_scalar
3363 if (token == TokenNameEQUAL_GREATER) {
3367 if (token != TokenNameCOMMA) {
3371 if (token == TokenNameRPAREN) {
3376 public void reportSyntaxError() { //int act, int currentKind, int
3378 /* remember current scanner position */
3379 int startPos = scanner.startPosition;
3380 int currentPos = scanner.currentPosition;
3381 // String[] expectings;
3382 // String tokenName = name[symbol_index[currentKind]];
3383 //fetch all "accurate" possible terminals that could recover the error
3384 // int start, end = start = asi(stack[stateStackTop]);
3385 // while (asr[end] != 0)
3387 // int length = end - start;
3388 // expectings = new String[length];
3389 // if (length != 0) {
3390 // char[] indexes = new char[length];
3391 // System.arraycopy(asr, start, indexes, 0, length);
3392 // for (int i = 0; i < length; i++) {
3393 // expectings[i] = name[symbol_index[indexes[i]]];
3396 //if the pb is an EOF, try to tell the user that they are some
3397 // if (tokenName.equals(UNEXPECTED_EOF)) {
3398 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3399 // char[] tokenSource;
3401 // tokenSource = this.scanner.getCurrentTokenSource();
3402 // } catch (Exception e) {
3403 // tokenSource = new char[] {};
3405 // problemReporter().parseError(
3406 // this.scanner.startPosition,
3407 // this.scanner.currentPosition - 1,
3412 // } else { //the next test is HEAVILY grammar DEPENDENT.
3413 // if ((length == 14)
3414 // && (expectings[0] == "=") //$NON-NLS-1$
3415 // && (expectings[1] == "*=") //$NON-NLS-1$
3416 // && (expressionPtr > -1)) {
3417 // switch(currentKind) {
3418 // case TokenNameSEMICOLON:
3419 // case TokenNamePLUS:
3420 // case TokenNameMINUS:
3421 // case TokenNameDIVIDE:
3422 // case TokenNameREMAINDER:
3423 // case TokenNameMULTIPLY:
3424 // case TokenNameLEFT_SHIFT:
3425 // case TokenNameRIGHT_SHIFT:
3426 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3427 // case TokenNameLESS:
3428 // case TokenNameGREATER:
3429 // case TokenNameLESS_EQUAL:
3430 // case TokenNameGREATER_EQUAL:
3431 // case TokenNameEQUAL_EQUAL:
3432 // case TokenNameNOT_EQUAL:
3433 // case TokenNameXOR:
3434 // case TokenNameAND:
3435 // case TokenNameOR:
3436 // case TokenNameOR_OR:
3437 // case TokenNameAND_AND:
3438 // // the ; is not the expected token ==> it ends a statement when an
3439 // expression is not ended
3440 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3442 // case TokenNameRBRACE :
3443 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3446 // char[] tokenSource;
3448 // tokenSource = this.scanner.getCurrentTokenSource();
3449 // } catch (Exception e) {
3450 // tokenSource = new char[] {};
3452 // problemReporter().parseError(
3453 // this.scanner.startPosition,
3454 // this.scanner.currentPosition - 1,
3458 // this.checkAndReportBracketAnomalies(problemReporter());
3463 tokenSource = this.scanner.getCurrentTokenSource();
3464 } catch (Exception e) {
3465 tokenSource = new char[]{};
3467 // problemReporter().parseError(
3468 // this.scanner.startPosition,
3469 // this.scanner.currentPosition - 1,
3473 this.checkAndReportBracketAnomalies(problemReporter());
3476 /* reset scanner where it was */
3477 scanner.startPosition = startPos;
3478 scanner.currentPosition = currentPos;
3480 public static final int RoundBracket = 0;
3481 public static final int SquareBracket = 1;
3482 public static final int CurlyBracket = 2;
3483 public static final int BracketKinds = 3;
3484 protected int[] nestedMethod; //the ptr is nestedType
3485 protected int nestedType, dimensions;
3487 final static int AstStackIncrement = 100;
3488 protected int astPtr;
3489 protected AstNode[] astStack = new AstNode[AstStackIncrement];
3490 protected int astLengthPtr;
3491 protected int[] astLengthStack;
3492 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3493 public CompilationUnitDeclaration compilationUnit; /*
3494 * the result from parse()
3496 protected ReferenceContext referenceContext;
3497 protected ProblemReporter problemReporter;
3498 // protected CompilationResult compilationResult;
3500 * Returns this parser's problem reporter initialized with its reference
3501 * context. Also it is assumed that a problem is going to be reported, so
3502 * initializes the compilation result's line positions.
3504 public ProblemReporter problemReporter() {
3505 if (scanner.recordLineSeparator) {
3506 compilationUnit.compilationResult.lineSeparatorPositions = scanner
3509 problemReporter.referenceContext = referenceContext;
3510 return problemReporter;
3513 * Reconsider the entire source looking for inconsistencies in {} () []
3515 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3516 scanner.wasAcr = false;
3517 boolean anomaliesDetected = false;
3519 char[] source = scanner.source;
3520 int[] leftCount = {0, 0, 0};
3521 int[] rightCount = {0, 0, 0};
3522 int[] depths = {0, 0, 0};
3523 int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3524 int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3525 int[][] rightPositions = new int[][]{new int[10], new int[10],
3527 int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3528 scanner.currentPosition = scanner.initialPosition; //starting
3530 // (first-zero-based
3532 while (scanner.currentPosition < scanner.eofPosition) { //loop for
3537 // ---------Consume white space and handles
3538 // startPosition---------
3539 boolean isWhiteSpace;
3541 scanner.startPosition = scanner.currentPosition;
3542 // if (((scanner.currentCharacter =
3543 // source[scanner.currentPosition++]) == '\\') &&
3544 // (source[scanner.currentPosition] == 'u')) {
3545 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3547 if (scanner.recordLineSeparator
3548 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3549 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3550 // only record line positions we have not
3552 scanner.pushLineSeparator();
3555 isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3557 } while (isWhiteSpace
3558 && (scanner.currentPosition < scanner.eofPosition));
3559 // -------consume token until } is found---------
3560 switch (scanner.currentCharacter) {
3563 int index = leftCount[CurlyBracket]++;
3564 if (index == leftPositions[CurlyBracket].length) {
3565 System.arraycopy(leftPositions[CurlyBracket], 0,
3566 (leftPositions[CurlyBracket] = new int[index * 2]), 0,
3569 .arraycopy(leftDepths[CurlyBracket], 0,
3570 (leftDepths[CurlyBracket] = new int[index * 2]), 0,
3573 leftPositions[CurlyBracket][index] = scanner.startPosition;
3574 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3579 int index = rightCount[CurlyBracket]++;
3580 if (index == rightPositions[CurlyBracket].length) {
3581 System.arraycopy(rightPositions[CurlyBracket], 0,
3582 (rightPositions[CurlyBracket] = new int[index * 2]), 0,
3584 System.arraycopy(rightDepths[CurlyBracket], 0,
3585 (rightDepths[CurlyBracket] = new int[index * 2]), 0,
3588 rightPositions[CurlyBracket][index] = scanner.startPosition;
3589 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3594 int index = leftCount[RoundBracket]++;
3595 if (index == leftPositions[RoundBracket].length) {
3596 System.arraycopy(leftPositions[RoundBracket], 0,
3597 (leftPositions[RoundBracket] = new int[index * 2]), 0,
3600 .arraycopy(leftDepths[RoundBracket], 0,
3601 (leftDepths[RoundBracket] = new int[index * 2]), 0,
3604 leftPositions[RoundBracket][index] = scanner.startPosition;
3605 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3610 int index = rightCount[RoundBracket]++;
3611 if (index == rightPositions[RoundBracket].length) {
3612 System.arraycopy(rightPositions[RoundBracket], 0,
3613 (rightPositions[RoundBracket] = new int[index * 2]), 0,
3615 System.arraycopy(rightDepths[RoundBracket], 0,
3616 (rightDepths[RoundBracket] = new int[index * 2]), 0,
3619 rightPositions[RoundBracket][index] = scanner.startPosition;
3620 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3625 int index = leftCount[SquareBracket]++;
3626 if (index == leftPositions[SquareBracket].length) {
3627 System.arraycopy(leftPositions[SquareBracket], 0,
3628 (leftPositions[SquareBracket] = new int[index * 2]), 0,
3630 System.arraycopy(leftDepths[SquareBracket], 0,
3631 (leftDepths[SquareBracket] = new int[index * 2]), 0,
3634 leftPositions[SquareBracket][index] = scanner.startPosition;
3635 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3640 int index = rightCount[SquareBracket]++;
3641 if (index == rightPositions[SquareBracket].length) {
3642 System.arraycopy(rightPositions[SquareBracket], 0,
3643 (rightPositions[SquareBracket] = new int[index * 2]), 0,
3645 System.arraycopy(rightDepths[SquareBracket], 0,
3646 (rightDepths[SquareBracket] = new int[index * 2]), 0,
3649 rightPositions[SquareBracket][index] = scanner.startPosition;
3650 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3655 if (scanner.getNextChar('\\')) {
3656 scanner.scanEscapeCharacter();
3657 } else { // consume next character
3658 scanner.unicodeAsBackSlash = false;
3659 // if (((scanner.currentCharacter =
3660 // source[scanner.currentPosition++]) ==
3662 // (source[scanner.currentPosition] ==
3664 // scanner.getNextUnicodeChar();
3666 if (scanner.withoutUnicodePtr != 0) {
3667 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3671 scanner.getNextChar('\'');
3675 // consume next character
3676 scanner.unicodeAsBackSlash = false;
3677 // if (((scanner.currentCharacter =
3678 // source[scanner.currentPosition++]) == '\\') &&
3679 // (source[scanner.currentPosition] == 'u')) {
3680 // scanner.getNextUnicodeChar();
3682 if (scanner.withoutUnicodePtr != 0) {
3683 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3686 while (scanner.currentCharacter != '"') {
3687 if (scanner.currentCharacter == '\r') {
3688 if (source[scanner.currentPosition] == '\n')
3689 scanner.currentPosition++;
3690 break; // the string cannot go further that
3693 if (scanner.currentCharacter == '\n') {
3694 break; // the string cannot go further that
3697 if (scanner.currentCharacter == '\\') {
3698 scanner.scanEscapeCharacter();
3700 // consume next character
3701 scanner.unicodeAsBackSlash = false;
3702 // if (((scanner.currentCharacter =
3703 // source[scanner.currentPosition++]) == '\\')
3704 // && (source[scanner.currentPosition] == 'u'))
3706 // scanner.getNextUnicodeChar();
3708 if (scanner.withoutUnicodePtr != 0) {
3709 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3717 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3720 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3721 && (source[scanner.currentPosition] == 'u')) {
3722 //-------------unicode traitement
3724 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3725 scanner.currentPosition++;
3726 while (source[scanner.currentPosition] == 'u') {
3727 scanner.currentPosition++;
3730 .getNumericValue(source[scanner.currentPosition++])) > 15
3733 .getNumericValue(source[scanner.currentPosition++])) > 15
3736 .getNumericValue(source[scanner.currentPosition++])) > 15
3739 .getNumericValue(source[scanner.currentPosition++])) > 15
3740 || c4 < 0) { //error don't
3743 scanner.currentCharacter = 'A';
3744 } //something different from \n and \r
3746 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3749 while (scanner.currentCharacter != '\r'
3750 && scanner.currentCharacter != '\n') {
3752 scanner.startPosition = scanner.currentPosition;
3753 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3754 && (source[scanner.currentPosition] == 'u')) {
3755 //-------------unicode traitement
3757 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3758 scanner.currentPosition++;
3759 while (source[scanner.currentPosition] == 'u') {
3760 scanner.currentPosition++;
3763 .getNumericValue(source[scanner.currentPosition++])) > 15
3766 .getNumericValue(source[scanner.currentPosition++])) > 15
3769 .getNumericValue(source[scanner.currentPosition++])) > 15
3772 .getNumericValue(source[scanner.currentPosition++])) > 15
3773 || c4 < 0) { //error don't
3776 scanner.currentCharacter = 'A';
3777 } //something different from \n
3780 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3784 if (scanner.recordLineSeparator
3785 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3786 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3787 // only record line positions we
3788 // have not recorded yet
3789 scanner.pushLineSeparator();
3790 if (this.scanner.taskTags != null) {
3791 this.scanner.checkTaskTag(this.scanner
3792 .getCurrentTokenStartPosition(), this.scanner
3793 .getCurrentTokenEndPosition());
3799 if (test > 0) { //traditional and annotation
3801 boolean star = false;
3802 // consume next character
3803 scanner.unicodeAsBackSlash = false;
3804 // if (((scanner.currentCharacter =
3805 // source[scanner.currentPosition++]) ==
3807 // (source[scanner.currentPosition] ==
3809 // scanner.getNextUnicodeChar();
3811 if (scanner.withoutUnicodePtr != 0) {
3812 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3815 if (scanner.currentCharacter == '*') {
3819 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3820 && (source[scanner.currentPosition] == 'u')) {
3821 //-------------unicode traitement
3823 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3824 scanner.currentPosition++;
3825 while (source[scanner.currentPosition] == 'u') {
3826 scanner.currentPosition++;
3829 .getNumericValue(source[scanner.currentPosition++])) > 15
3832 .getNumericValue(source[scanner.currentPosition++])) > 15
3835 .getNumericValue(source[scanner.currentPosition++])) > 15
3838 .getNumericValue(source[scanner.currentPosition++])) > 15
3839 || c4 < 0) { //error don't
3842 scanner.currentCharacter = 'A';
3843 } //something different from * and /
3845 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3848 //loop until end of comment */
3849 while ((scanner.currentCharacter != '/') || (!star)) {
3850 star = scanner.currentCharacter == '*';
3852 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3853 && (source[scanner.currentPosition] == 'u')) {
3854 //-------------unicode traitement
3856 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3857 scanner.currentPosition++;
3858 while (source[scanner.currentPosition] == 'u') {
3859 scanner.currentPosition++;
3862 .getNumericValue(source[scanner.currentPosition++])) > 15
3865 .getNumericValue(source[scanner.currentPosition++])) > 15
3868 .getNumericValue(source[scanner.currentPosition++])) > 15
3871 .getNumericValue(source[scanner.currentPosition++])) > 15
3872 || c4 < 0) { //error don't
3875 scanner.currentCharacter = 'A';
3876 } //something different from * and
3879 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3883 if (this.scanner.taskTags != null) {
3884 this.scanner.checkTaskTag(this.scanner
3885 .getCurrentTokenStartPosition(), this.scanner
3886 .getCurrentTokenEndPosition());
3893 if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3894 scanner.scanIdentifierOrKeyword(false);
3897 if (Character.isDigit(scanner.currentCharacter)) {
3898 scanner.scanNumber(false);
3902 //-----------------end switch while
3903 // try--------------------
3904 } catch (IndexOutOfBoundsException e) {
3905 break; // read until EOF
3906 } catch (InvalidInputException e) {
3907 return false; // no clue
3910 if (scanner.recordLineSeparator) {
3911 // compilationUnit.compilationResult.lineSeparatorPositions =
3912 // scanner.getLineEnds();
3914 // check placement anomalies against other kinds of brackets
3915 for (int kind = 0; kind < BracketKinds; kind++) {
3916 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3917 int start = leftPositions[kind][leftIndex]; // deepest
3919 // find matching closing bracket
3920 int depth = leftDepths[kind][leftIndex];
3922 for (int i = 0; i < rightCount[kind]; i++) {
3923 int pos = rightPositions[kind][i];
3924 // want matching bracket further in source with same
3926 if ((pos > start) && (depth == rightDepths[kind][i])) {
3931 if (end < 0) { // did not find a good closing match
3932 problemReporter.unmatchedBracket(start, referenceContext,
3933 compilationUnit.compilationResult);
3936 // check if even number of opening/closing other brackets
3937 // in between this pair of brackets
3939 for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3940 for (int i = 0; i < leftCount[otherKind]; i++) {
3941 int pos = leftPositions[otherKind][i];
3942 if ((pos > start) && (pos < end))
3945 for (int i = 0; i < rightCount[otherKind]; i++) {
3946 int pos = rightPositions[otherKind][i];
3947 if ((pos > start) && (pos < end))
3951 problemReporter.unmatchedBracket(start, referenceContext,
3952 compilationUnit.compilationResult); //bracket
3958 // too many opening brackets ?
3959 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3960 anomaliesDetected = true;
3961 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind]
3962 - i - 1], referenceContext, compilationUnit.compilationResult);
3964 // too many closing brackets ?
3965 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3966 anomaliesDetected = true;
3967 problemReporter.unmatchedBracket(rightPositions[kind][i],
3968 referenceContext, compilationUnit.compilationResult);
3970 if (anomaliesDetected)
3973 return anomaliesDetected;
3974 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
3975 return anomaliesDetected;
3976 } catch (NullPointerException e) { // jdk1.2.2 jit bug
3977 return anomaliesDetected;
3980 protected void pushOnAstLengthStack(int pos) {
3982 astLengthStack[++astLengthPtr] = pos;
3983 } catch (IndexOutOfBoundsException e) {
3984 int oldStackLength = astLengthStack.length;
3985 int[] oldPos = astLengthStack;
3986 astLengthStack = new int[oldStackLength + StackIncrement];
3987 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3988 astLengthStack[astLengthPtr] = pos;
3991 protected void pushOnAstStack(AstNode node) {
3993 * add a new obj on top of the ast stack
3996 astStack[++astPtr] = node;
3997 } catch (IndexOutOfBoundsException e) {
3998 int oldStackLength = astStack.length;
3999 AstNode[] oldStack = astStack;
4000 astStack = new AstNode[oldStackLength + AstStackIncrement];
4001 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
4002 astPtr = oldStackLength;
4003 astStack[astPtr] = node;
4006 astLengthStack[++astLengthPtr] = 1;
4007 } catch (IndexOutOfBoundsException e) {
4008 int oldStackLength = astLengthStack.length;
4009 int[] oldPos = astLengthStack;
4010 astLengthStack = new int[oldStackLength + AstStackIncrement];
4011 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
4012 astLengthStack[astLengthPtr] = 1;