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+1);
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;
208 public void init(String s) {
210 this.token = TokenNameEOF;
212 // this.rowCount = 1;
213 // this.columnCount = 0;
215 // this.phpMode = false;
216 /* scanner initialization */
217 scanner.setSource(s.toCharArray());
218 scanner.setPHPMode(false);
220 protected void initialize(boolean phpMode) {
221 compilationUnit = null;
222 referenceContext = null;
224 this.token = TokenNameEOF;
226 // this.rowCount = 1;
227 // this.columnCount = 0;
229 // this.phpMode = phpMode;
230 scanner.setPHPMode(phpMode);
233 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
236 public void parse(String s) {
241 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
244 protected void parse() {
248 if (token != TokenNameEOF && token != TokenNameERROR) {
251 if (token != TokenNameEOF) {
252 if (token == TokenNameERROR) {
253 throwSyntaxError("Scanner error (Found unknown token: "
254 + scanner.toStringAction(token) + ")");
256 if (token == TokenNameRPAREN) {
257 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
259 if (token == TokenNameRBRACE) {
260 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
262 if (token == TokenNameRBRACKET) {
263 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
265 if (token == TokenNameLPAREN) {
266 throwSyntaxError("Read character '('; end-of-file not reached.");
268 if (token == TokenNameLBRACE) {
269 throwSyntaxError("Read character '{'; end-of-file not reached.");
271 if (token == TokenNameLBRACKET) {
272 throwSyntaxError("Read character '['; end-of-file not reached.");
274 throwSyntaxError("End-of-file not reached.");
277 } catch (SyntaxError sytaxErr1) {
278 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
280 // setMarker(sytaxErr1.getMessage(),
281 // scanner.getCurrentTokenStartPosition(),
282 // scanner.getCurrentTokenEndPosition(), ERROR);
284 // if an error occured,
285 // try to find keywords 'class' or 'function'
286 // to parse the rest of the string
287 while (token != TokenNameEOF && token != TokenNameERROR) {
288 if (token == TokenNameabstract || token == TokenNamefinal
289 || token == TokenNameclass || token == TokenNamefunction) {
294 if (token == TokenNameEOF || token == TokenNameERROR) {
297 } catch (SyntaxError sytaxErr2) {
298 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
300 // setMarker(sytaxErr2.getMessage(),
301 // scanner.getCurrentTokenStartPosition(),
302 // scanner.getCurrentTokenEndPosition(), ERROR);
308 // public PHPOutlineInfo parseInfo(Object parent, String s) {
309 // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
310 // // Stack stack = new Stack();
311 // // stack.push(outlineInfo.getDeclarations());
313 // this.token = TokenNameEOF;
314 // // this.chIndx = 0;
315 // // this.rowCount = 1;
316 // // this.columnCount = 0;
317 // this.phpEnd = false;
318 // this.phpMode = false;
319 // scanner.setSource(s.toCharArray());
320 // scanner.setPHPMode(false);
323 // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
325 // return outlineInfo;
327 private boolean isVariable() {
328 return token == TokenNameVariable; // || token == TokenNamethis;
330 // private void parseDeclarations(PHPOutlineInfo outlineInfo,
331 // OutlineableWithChildren current, boolean goBack) {
333 // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
334 // PHPSegmentWithChildren temp;
336 // IPreferenceStore store =
337 // PHPeclipsePlugin.getDefault().getPreferenceStore();
339 // while (token != TokenNameEOF && token != TokenNameERROR) {
340 // if (token == TokenNameVariable) {
341 // ident = scanner.getCurrentIdentifierSource();
342 // outlineInfo.addVariable(new String(ident));
344 // } else if (token == TokenNamevar) {
346 // if (token == TokenNameVariable
347 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
348 // ident = scanner.getCurrentIdentifierSource();
349 // //substring(1) added because PHPVarDeclaration doesn't
350 // // need the $ anymore
351 // String variableName = new String(ident).substring(1);
352 // outlineInfo.addVariable(variableName);
354 // if (token != TokenNameSEMICOLON) {
356 // ident = scanner.getCurrentTokenSource();
357 // if (token > TokenNameKEYWORD) {
358 // current.add(new PHPVarDeclaration(current, variableName,
359 // // chIndx - ident.length,
360 // scanner.getCurrentTokenStartPosition(), new String(ident)));
363 // case TokenNameVariable :
364 // case TokenNamethis :
365 // current.add(new PHPVarDeclaration(current, variableName,
368 // scanner.getCurrentTokenStartPosition(), new String(
371 // case TokenNameIdentifier :
372 // current.add(new PHPVarDeclaration(current, variableName,
375 // scanner.getCurrentTokenStartPosition(), new String(
378 // case TokenNameDoubleLiteral :
379 // current.add(new PHPVarDeclaration(current, variableName
383 // scanner.getCurrentTokenStartPosition(), new String(
386 // case TokenNameIntegerLiteral :
387 // current.add(new PHPVarDeclaration(current, variableName,
390 // scanner.getCurrentTokenStartPosition(), new String(
393 // case TokenNameStringInterpolated :
394 // case TokenNameStringLiteral :
395 // current.add(new PHPVarDeclaration(current, variableName,
398 // scanner.getCurrentTokenStartPosition(), new String(
401 // case TokenNameStringConstant :
402 // current.add(new PHPVarDeclaration(current, variableName,
405 // scanner.getCurrentTokenStartPosition(), new String(
409 // current.add(new PHPVarDeclaration(current, variableName,
412 // scanner.getCurrentTokenStartPosition()));
417 // ident = scanner.getCurrentIdentifierSource();
418 // current.add(new PHPVarDeclaration(current, variableName,
419 // // chIndx - ident.length
420 // scanner.getCurrentTokenStartPosition()));
423 // } else if (token == TokenNamefunction) {
425 // if (token == TokenNameAND) {
428 // if (token == TokenNameIdentifier
429 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
430 // ident = scanner.getCurrentIdentifierSource();
431 // outlineInfo.addVariable(new String(ident));
432 // temp = new PHPFunctionDeclaration(current, new String(ident),
433 // // chIndx - ident.length
434 // scanner.getCurrentTokenStartPosition());
435 // current.add(temp);
437 // parseDeclarations(outlineInfo, temp, true);
439 // } else if (token == TokenNameclass) {
441 // if (token == TokenNameIdentifier
442 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
443 // ident = scanner.getCurrentIdentifierSource();
444 // outlineInfo.addVariable(new String(ident));
445 // temp = new PHPClassDeclaration(current, new String(ident),
446 // // chIndx - ident.len
447 // scanner.getCurrentTokenStartPosition());
448 // current.add(temp);
449 // // stack.push(temp);
451 // //skip tokens for classname, extends and others until
452 // // we have the opening '{'
453 // while (token != TokenNameLBRACE && token != TokenNameEOF
454 // && token != TokenNameERROR) {
457 // parseDeclarations(outlineInfo, temp, true);
460 // } else if ((token == TokenNameLBRACE)
461 // || (token == TokenNameDOLLAR_LBRACE)) {
464 // } else if (token == TokenNameRBRACE) {
467 // if (counter == 0 && goBack) {
470 // } else if (token == TokenNamerequire || token == TokenNamerequire_once
471 // || token == TokenNameinclude || token == TokenNameinclude_once) {
472 // ident = scanner.getCurrentTokenSource();
474 // int startPosition = scanner.getCurrentTokenStartPosition();
476 // char[] expr = scanner.getCurrentTokenSource(startPosition);
477 // outlineInfo.addVariable(new String(ident));
478 // current.add(new PHPReqIncDeclaration(current, new String(ident),
479 // // chIndx - ident.length,
480 // startPosition, new String(expr)));
486 // } catch (SyntaxError sytaxErr) {
488 // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
489 // // setMarker(sytaxErr.getMessage(),
490 // // scanner.getCurrentTokenStartPosition(),
491 // // scanner.getCurrentTokenEndPosition(), ERROR);
492 // // } catch (CoreException e) {
496 private void statementList() {
498 statement(TokenNameEOF);
499 if ((token == TokenNameRBRACE) || (token == TokenNamecase)
500 || (token == TokenNamedefault) || (token == TokenNameelse)
501 || (token == TokenNameelseif) || (token == TokenNameendif)
502 || (token == TokenNameendfor) || (token == TokenNameendforeach)
503 || (token == TokenNameendwhile) || (token == TokenNameendswitch)
504 || (token == TokenNameEOF) || (token == TokenNameERROR)) {
509 private void functionBody(MethodDeclaration methodDecl) {
510 // '{' [statement-list] '}'
511 if (token == TokenNameLBRACE) {
514 throwSyntaxError("'{' expected in compound-statement.");
516 if (token != TokenNameRBRACE) {
519 if (token == TokenNameRBRACE) {
520 methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
523 throwSyntaxError("'}' expected in compound-statement.");
526 private void statement(int previousToken) {
527 // if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
529 // char[] ident = scanner.getCurrentIdentifierSource();
530 // String keyword = new String(ident);
531 // if (token == TokenNameAT) {
533 // if (token != TokenNamerequire && token != TokenNamerequire_once
534 // && token != TokenNameinclude && token != TokenNameinclude_once
535 // && token != TokenNameIdentifier && token != TokenNameVariable
536 // && token != TokenNameStringInterpolated) {
537 // throwSyntaxError("identifier expected after '@'.");
540 // if (token == TokenNameinclude || token == TokenNameinclude_once) {
542 // if (token == TokenNameLPAREN) {
544 // if (token == TokenNameSEMICOLON) {
547 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
548 // throwSyntaxError("';' expected after 'include' or 'include_once'.");
550 // // getNextToken();
553 // concatenationExpression();
556 // } else if (token == TokenNamerequire || token == TokenNamerequire_once)
560 // if (token == TokenNameLPAREN) {
562 // if (token == TokenNameSEMICOLON) {
565 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
566 // throwSyntaxError("';' expected after 'require' or 'require_once'.");
568 // // getNextToken();
571 // concatenationExpression();
575 if (token == TokenNameif) {
577 if (token == TokenNameLPAREN) {
580 throwSyntaxError("'(' expected after 'if' keyword.");
583 if (token == TokenNameRPAREN) {
586 throwSyntaxError("')' expected after 'if' condition.");
590 } else if (token == TokenNameswitch) {
592 if (token == TokenNameLPAREN) {
595 throwSyntaxError("'(' expected after 'switch' keyword.");
598 if (token == TokenNameRPAREN) {
601 throwSyntaxError("')' expected after 'switch' condition.");
605 } else if (token == TokenNamefor) {
607 if (token == TokenNameLPAREN) {
610 throwSyntaxError("'(' expected after 'for' keyword.");
612 if (token == TokenNameSEMICOLON) {
616 if (token == TokenNameSEMICOLON) {
619 throwSyntaxError("';' expected after 'for'.");
622 if (token == TokenNameSEMICOLON) {
626 if (token == TokenNameSEMICOLON) {
629 throwSyntaxError("';' expected after 'for'.");
632 if (token == TokenNameRPAREN) {
636 if (token == TokenNameRPAREN) {
639 throwSyntaxError("')' expected after 'for'.");
644 } else if (token == TokenNamewhile) {
646 if (token == TokenNameLPAREN) {
649 throwSyntaxError("'(' expected after 'while' keyword.");
652 if (token == TokenNameRPAREN) {
655 throwSyntaxError("')' expected after 'while' condition.");
659 } else if (token == TokenNamedo) {
661 if (token == TokenNameLBRACE) {
664 throwSyntaxError("'{' expected after 'do' keyword.");
666 if (token != TokenNameRBRACE) {
669 if (token == TokenNameRBRACE) {
672 throwSyntaxError("'}' expected after 'do' keyword.");
674 if (token == TokenNamewhile) {
676 if (token == TokenNameLPAREN) {
679 throwSyntaxError("'(' expected after 'while' keyword.");
682 if (token == TokenNameRPAREN) {
685 throwSyntaxError("')' expected after 'while' condition.");
688 throwSyntaxError("'while' expected after 'do' keyword.");
690 if (token == TokenNameSEMICOLON) {
693 if (token != TokenNameINLINE_HTML) {
694 throwSyntaxError("';' expected after do-while statement.");
699 } else if (token == TokenNameforeach) {
701 if (token == TokenNameLPAREN) {
704 throwSyntaxError("'(' expected after 'foreach' keyword.");
707 if (token == TokenNameas) {
710 throwSyntaxError("'as' expected after 'foreach' exxpression.");
714 foreach_optional_arg();
715 if (token == TokenNameEQUAL_GREATER) {
719 if (token == TokenNameRPAREN) {
722 throwSyntaxError("')' expected after 'foreach' expression.");
726 } else if (token == TokenNamecontinue || token == TokenNamebreak
727 || token == TokenNamereturn) {
729 if (token != TokenNameSEMICOLON) {
732 if (token == TokenNameSEMICOLON) {
735 if (token != TokenNameINLINE_HTML) {
736 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
741 } else if (token == TokenNameecho) {
744 if (token == TokenNameSEMICOLON) {
747 if (token != TokenNameINLINE_HTML) {
748 throwSyntaxError("';' expected after 'echo' statement.");
753 } else if (token == TokenNameINLINE_HTML) {
756 // } else if (token == TokenNameprint) {
759 // if (token == TokenNameSEMICOLON) {
762 // if (token != TokenNameStopPHP) {
763 // throwSyntaxError("';' expected after 'print' statement.");
768 } else if (token == TokenNameglobal) {
771 if (token == TokenNameSEMICOLON) {
774 if (token != TokenNameINLINE_HTML) {
775 throwSyntaxError("';' expected after 'global' statement.");
780 } else if (token == TokenNamestatic) {
783 if (token == TokenNameSEMICOLON) {
786 if (token != TokenNameINLINE_HTML) {
787 throwSyntaxError("';' expected after 'static' statement.");
792 } else if (token == TokenNameunset) {
794 if (token == TokenNameLPAREN) {
797 throwSyntaxError("'(' expected after 'unset' statement.");
800 if (token == TokenNameRPAREN) {
803 throwSyntaxError("')' expected after 'unset' statement.");
805 if (token == TokenNameSEMICOLON) {
808 if (token != TokenNameINLINE_HTML) {
809 throwSyntaxError("';' expected after 'unset' statement.");
814 } else if (token == TokenNamefunction) {
815 MethodDeclaration methodDecl = new MethodDeclaration(
816 this.compilationUnit.compilationResult);
817 methodDecl.declarationSourceStart = scanner
818 .getCurrentTokenStartPosition();
820 functionDefinition(methodDecl);
822 } else if (token == TokenNametry) {
824 if (token != TokenNameLBRACE) {
825 throwSyntaxError("'{' expected in 'try' statement.");
829 if (token != TokenNameRBRACE) {
830 throwSyntaxError("'}' expected in 'try' statement.");
834 } else if (token == TokenNamecatch) {
836 if (token != TokenNameLPAREN) {
837 throwSyntaxError("'(' expected in 'catch' statement.");
840 fully_qualified_class_name();
841 if (token != TokenNameVariable) {
842 throwSyntaxError("Variable expected in 'catch' statement.");
845 if (token != TokenNameRPAREN) {
846 throwSyntaxError("')' expected in 'catch' statement.");
849 if (token != TokenNameLBRACE) {
850 throwSyntaxError("'{' expected in 'catch' statement.");
854 if (token != TokenNameRBRACE) {
855 throwSyntaxError("'}' expected in 'catch' statement.");
858 additional_catches();
860 } else if (token == TokenNamethrow) {
863 if (token == TokenNameSEMICOLON) {
866 throwSyntaxError("';' expected after 'throw' exxpression.");
869 } else if (token == TokenNamefinal || token == TokenNameabstract
870 || token == TokenNameclass || token == TokenNameinterface) {
871 TypeDeclaration typeDecl = new TypeDeclaration(
872 this.compilationUnit.compilationResult);
873 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
874 // default super class
875 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
876 compilationUnit.types.add(typeDecl);
878 pushOnAstStack(typeDecl);
879 unticked_class_declaration_statement(typeDecl);
880 // classBody(typeDecl);
887 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
888 } else if (token == TokenNameLBRACE) {
890 if (token != TokenNameRBRACE) {
893 if (token == TokenNameRBRACE) {
897 throwSyntaxError("'}' expected.");
900 if (token != TokenNameSEMICOLON) {
903 if (token == TokenNameSEMICOLON) {
907 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
908 throwSyntaxError("';' expected after expression (Found token: "
909 + scanner.toStringAction(token) + ")");
915 private void additional_catches() {
916 while (token == TokenNamecatch) {
918 if (token != TokenNameLPAREN) {
919 throwSyntaxError("'(' expected in 'catch' statement.");
922 fully_qualified_class_name();
923 if (token != TokenNameVariable) {
924 throwSyntaxError("Variable expected in 'catch' statement.");
927 if (token != TokenNameRPAREN) {
928 throwSyntaxError("')' expected in 'catch' statement.");
931 if (token != TokenNameLBRACE) {
932 throwSyntaxError("'{' expected in 'catch' statement.");
936 if (token != TokenNameRBRACE) {
937 throwSyntaxError("'}' expected in 'catch' statement.");
942 private void foreach_variable() {
945 if (token == TokenNameAND) {
950 private void foreach_optional_arg() {
952 //| T_DOUBLE_ARROW foreach_variable
953 if (token == TokenNameEQUAL_GREATER) {
958 private void global_var_list() {
960 // global_var_list ',' global_var
964 if (token != TokenNameCOMMA) {
970 private void global_var() {
975 if (token == TokenNameVariable) {
977 } else if (token == TokenNameDOLLAR) {
979 if (token == TokenNameLPAREN) {
982 if (token != TokenNameLPAREN) {
983 throwSyntaxError("')' expected in global variable.");
991 private void static_var_list() {
993 // static_var_list ',' T_VARIABLE
994 //| static_var_list ',' T_VARIABLE '=' static_scalar
996 //| T_VARIABLE '=' static_scalar
998 if (token == TokenNameVariable) {
1000 if (token == TokenNameEQUAL) {
1004 if (token != TokenNameCOMMA) {
1013 private void unset_variables() {
1016 // | unset_variables ',' unset_variable
1021 if (token != TokenNameCOMMA) {
1027 private final void initializeModifiers() {
1029 this.modifiersSourceStart = -1;
1031 private final void checkAndSetModifiers(int flag) {
1032 this.modifiers |= flag;
1033 if (this.modifiersSourceStart < 0)
1034 this.modifiersSourceStart = this.scanner.startPosition;
1036 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1037 initializeModifiers();
1038 if (token == TokenNameinterface) {
1039 // interface_entry T_STRING
1040 // interface_extends_list
1041 // '{' class_statement_list '}'
1042 checkAndSetModifiers(AccInterface);
1044 typeDecl.modifiers = this.modifiers;
1045 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1046 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1047 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1048 typeDecl.name = scanner.getCurrentIdentifierSource();
1049 if (token > TokenNameKEYWORD) {
1050 throwSyntaxError("Don't use a keyword for interface declaration ["
1051 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1052 typeDecl.sourceEnd);
1055 interface_extends_list();
1057 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1058 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1059 typeDecl.name = new char[]{' '};
1060 throwSyntaxError("Interface name expected after keyword 'interface'.",
1061 typeDecl.sourceStart, typeDecl.sourceEnd);
1065 // class_entry_type T_STRING extends_from
1067 // '{' class_statement_list'}'
1069 typeDecl.modifiers = this.modifiers;
1071 //identifier 'extends' identifier
1072 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1073 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1074 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1075 typeDecl.name = scanner.getCurrentIdentifierSource();
1076 if (token > TokenNameKEYWORD) {
1077 throwSyntaxError("Don't use a keyword for class declaration ["
1078 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1079 typeDecl.sourceEnd);
1084 // | T_EXTENDS fully_qualified_class_name
1085 if (token == TokenNameextends) {
1086 interface_extends_list();
1088 // if (token != TokenNameIdentifier) {
1089 // throwSyntaxError("Class name expected after keyword 'extends'.",
1090 // scanner.getCurrentTokenStartPosition(), scanner
1091 // .getCurrentTokenEndPosition());
1096 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1097 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1098 typeDecl.name = new char[]{' '};
1099 throwSyntaxError("Class name expected after keyword 'class'.",
1100 typeDecl.sourceStart, typeDecl.sourceEnd);
1104 // '{' class_statement_list '}'
1105 if (token == TokenNameLBRACE) {
1107 if (token != TokenNameRBRACE) {
1108 class_statement_list();
1110 if (token == TokenNameRBRACE) {
1111 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1114 throwSyntaxError("'}' expected at end of class body.");
1117 throwSyntaxError("'{' expected at start of class body.");
1120 private void class_entry_type() {
1122 // | T_ABSTRACT T_CLASS
1123 // | T_FINAL T_CLASS
1124 if (token == TokenNameclass) {
1126 } else if (token == TokenNameabstract) {
1127 checkAndSetModifiers(AccAbstract);
1129 if (token != TokenNameclass) {
1130 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1133 } else if (token == TokenNamefinal) {
1134 checkAndSetModifiers(AccFinal);
1136 if (token != TokenNameclass) {
1137 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1141 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1144 private void interface_extends_list() {
1146 // | T_EXTENDS interface_list
1147 if (token == TokenNameextends) {
1152 private void implements_list() {
1154 // | T_IMPLEMENTS interface_list
1155 if (token == TokenNameimplements) {
1160 private void interface_list() {
1162 // fully_qualified_class_name
1163 //| interface_list ',' fully_qualified_class_name
1165 if (token == TokenNameIdentifier) {
1168 throwSyntaxError("Interface name expected after keyword 'implements'.");
1170 if (token != TokenNameCOMMA) {
1176 // private void classBody(TypeDeclaration typeDecl) {
1177 // //'{' [class-element-list] '}'
1178 // if (token == TokenNameLBRACE) {
1180 // if (token != TokenNameRBRACE) {
1181 // class_statement_list();
1183 // if (token == TokenNameRBRACE) {
1184 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1187 // throwSyntaxError("'}' expected at end of class body.");
1190 // throwSyntaxError("'{' expected at start of class body.");
1193 private void class_statement_list() {
1196 } while (token == TokenNamepublic || token == TokenNameprotected
1197 || token == TokenNameprivate || token == TokenNamestatic
1198 || token == TokenNameabstract || token == TokenNamefinal
1199 || token == TokenNamefunction || token == TokenNamevar
1200 || token == TokenNameconst);
1202 private void class_statement() {
1204 // variable_modifiers class_variable_declaration ';'
1205 // | class_constant_declaration ';'
1206 // | method_modifiers T_FUNCTION is_reference T_STRING
1207 // '(' parameter_list ')' method_body
1208 initializeModifiers();
1209 if (token == TokenNamevar) {
1210 checkAndSetModifiers(AccPublic);
1211 problemReporter.phpVarDeprecatedWarning(scanner
1212 .getCurrentTokenStartPosition(),
1213 scanner.getCurrentTokenEndPosition(), referenceContext,
1214 compilationUnit.compilationResult);
1216 class_variable_declaration();
1217 } else if (token == TokenNameconst) {
1218 class_constant_declaration();
1219 if (token != TokenNameSEMICOLON) {
1220 throwSyntaxError("';' expected after class const declaration.");
1224 boolean hasModifiers = member_modifiers();
1225 if (token == TokenNamefunction) {
1226 if (!hasModifiers) {
1227 checkAndSetModifiers(AccPublic);
1229 MethodDeclaration methodDecl = new MethodDeclaration(
1230 this.compilationUnit.compilationResult);
1231 methodDecl.declarationSourceStart = scanner
1232 .getCurrentTokenStartPosition();
1233 methodDecl.modifiers = this.modifiers;
1235 functionDefinition(methodDecl);
1237 if (!hasModifiers) {
1238 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1240 class_variable_declaration();
1243 // if (token == TokenNamefunction) {
1244 // MethodDeclaration methodDecl = new MethodDeclaration(
1245 // this.compilationUnit.compilationResult);
1246 // methodDecl.declarationSourceStart = scanner
1247 // .getCurrentTokenStartPosition();
1249 // functionDefinition(methodDecl);
1250 // } else if (token == TokenNamevar) {
1254 // throwSyntaxError("'function' or 'var' expected.");
1257 private void class_constant_declaration() {
1258 // class_constant_declaration ',' T_STRING '=' static_scalar
1259 // | T_CONST T_STRING '=' static_scalar
1260 if (token != TokenNameconst) {
1261 throwSyntaxError("'const' keyword expected in class declaration.");
1266 if (token != TokenNameIdentifier) {
1267 throwSyntaxError("Identifier expected in class const declaration.");
1270 if (token != TokenNameEQUAL) {
1271 throwSyntaxError("'=' expected in class const declaration.");
1275 if (token != TokenNameCOMMA) {
1276 break; // while(true)-loop
1281 // private void variable_modifiers() {
1282 // // variable_modifiers:
1283 // // non_empty_member_modifiers
1285 // initializeModifiers();
1286 // if (token == TokenNamevar) {
1287 // checkAndSetModifiers(AccPublic);
1288 // reportSyntaxError(
1289 // "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected'
1290 // modifier for field declarations.",
1291 // scanner.getCurrentTokenStartPosition(), scanner
1292 // .getCurrentTokenEndPosition());
1295 // if (!member_modifiers()) {
1296 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1297 // field declarations.");
1301 // private void method_modifiers() {
1302 // //method_modifiers:
1304 // //| non_empty_member_modifiers
1305 // initializeModifiers();
1306 // if (!member_modifiers()) {
1307 // checkAndSetModifiers(AccPublic);
1310 private boolean member_modifiers() {
1317 boolean foundToken = false;
1319 if (token == TokenNamepublic) {
1320 checkAndSetModifiers(AccPublic);
1323 } else if (token == TokenNameprotected) {
1324 checkAndSetModifiers(AccProtected);
1327 } else if (token == TokenNameprivate) {
1328 checkAndSetModifiers(AccPrivate);
1331 } else if (token == TokenNamestatic) {
1332 checkAndSetModifiers(AccStatic);
1335 } else if (token == TokenNameabstract) {
1336 checkAndSetModifiers(AccAbstract);
1339 } else if (token == TokenNamefinal) {
1340 checkAndSetModifiers(AccFinal);
1349 private void class_variable_declaration() {
1350 // class_variable_declaration:
1351 // class_variable_declaration ',' T_VARIABLE
1352 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1354 // | T_VARIABLE '=' static_scalar
1356 if (token == TokenNameVariable) {
1358 if (token == TokenNameEQUAL) {
1363 // if (token == TokenNamethis) {
1364 // throwSyntaxError("'$this' not allowed after keyword 'public'
1365 // 'protected' 'private' 'var'.");
1367 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1369 if (token != TokenNameCOMMA) {
1374 if (token != TokenNameSEMICOLON) {
1375 throwSyntaxError("';' expected after field declaration.");
1379 private void functionDefinition(MethodDeclaration methodDecl) {
1380 boolean isAbstract = false;
1382 compilationUnit.types.add(methodDecl);
1384 AstNode node = astStack[astPtr];
1385 if (node instanceof TypeDeclaration) {
1386 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1387 if (typeDecl.methods == null) {
1388 typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1390 AbstractMethodDeclaration[] newMethods;
1395 newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1396 1, typeDecl.methods.length);
1397 newMethods[0] = methodDecl;
1398 typeDecl.methods = newMethods;
1400 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1402 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1407 functionDeclarator(methodDecl);
1408 if (token == TokenNameSEMICOLON) {
1410 throwSyntaxError("Body declaration expected for method: "
1411 + new String(methodDecl.selector));
1416 functionBody(methodDecl);
1418 private void functionDeclarator(MethodDeclaration methodDecl) {
1419 //identifier '(' [parameter-list] ')'
1420 if (token == TokenNameAND) {
1423 if (token == TokenNameIdentifier) {
1424 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1425 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1426 methodDecl.selector = scanner.getCurrentIdentifierSource();
1428 if (token == TokenNameLPAREN) {
1431 throwSyntaxError("'(' expected in function declaration.");
1433 if (token != TokenNameRPAREN) {
1436 if (token != TokenNameRPAREN) {
1437 throwSyntaxError("')' expected in function declaration.");
1439 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1443 if (token > TokenNameKEYWORD) {
1444 throwSyntaxError("Don't use keyword for function declaration [" + token
1447 throwSyntaxError("Function name expected after keyword 'function'.");
1451 private void parameter_list() {
1452 // non_empty_parameter_list
1454 non_empty_parameter_list(true);
1456 private void non_empty_parameter_list(boolean empty_allowed) {
1457 // optional_class_type T_VARIABLE
1458 // | optional_class_type '&' T_VARIABLE
1459 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1460 // | optional_class_type T_VARIABLE '=' static_scalar
1461 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1462 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1463 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1465 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1467 if (token == TokenNameIdentifier || token == TokenNameVariable
1468 || token == TokenNameAND) {
1470 if (token == TokenNameIdentifier) {
1473 if (token == TokenNameAND) {
1476 if (token == TokenNameVariable) {
1478 if (token == TokenNameEQUAL) {
1483 throwSyntaxError("Variable expected in parameter list.");
1485 if (token != TokenNameCOMMA) {
1492 if (!empty_allowed) {
1493 throwSyntaxError("Identifier expected in parameter list.");
1496 private void optional_class_type() {
1500 private void parameterDeclaration() {
1502 //variable-reference
1503 if (token == TokenNameAND) {
1508 throwSyntaxError("Variable expected after reference operator '&'.");
1511 //variable '=' constant
1512 if (token == TokenNameVariable) {
1514 if (token == TokenNameEQUAL) {
1520 // if (token == TokenNamethis) {
1521 // throwSyntaxError("Reserved word '$this' not allowed in parameter
1525 private void labeledStatementList() {
1526 if (token != TokenNamecase && token != TokenNamedefault) {
1527 throwSyntaxError("'case' or 'default' expected.");
1530 if (token == TokenNamecase) {
1532 expr(); //constant();
1533 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1535 if (token == TokenNamecase || token == TokenNamedefault) { // empty
1543 // else if (token == TokenNameSEMICOLON) {
1545 // "':' expected after 'case' keyword (Found token: " +
1546 // scanner.toStringAction(token) + ")",
1547 // scanner.getCurrentTokenStartPosition(),
1548 // scanner.getCurrentTokenEndPosition(),
1551 // if (token == TokenNamecase) { // empty case statement ?
1557 throwSyntaxError("':' character after 'case' constant expected (Found token: "
1558 + scanner.toStringAction(token) + ")");
1560 } else { // TokenNamedefault
1562 if (token == TokenNameCOLON) {
1566 throwSyntaxError("':' character after 'default' expected.");
1569 } while (token == TokenNamecase || token == TokenNamedefault);
1571 // public void labeledStatement() {
1572 // if (token == TokenNamecase) {
1575 // if (token == TokenNameDDOT) {
1579 // throwSyntaxError("':' character after 'case' constant expected.");
1582 // } else if (token == TokenNamedefault) {
1584 // if (token == TokenNameDDOT) {
1588 // throwSyntaxError("':' character after 'default' expected.");
1593 // public void expressionStatement() {
1595 // private void inclusionStatement() {
1597 // public void compoundStatement() {
1599 // public void selectionStatement() {
1602 // public void iterationStatement() {
1605 // public void jumpStatement() {
1608 // public void outputStatement() {
1611 // public void scopeStatement() {
1614 // public void flowStatement() {
1617 // public void definitionStatement() {
1619 private void ifStatement() {
1620 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1621 if (token == TokenNameCOLON) {
1623 if (token != TokenNameendif) {
1626 case TokenNameelse :
1628 if (token == TokenNameCOLON) {
1630 if (token != TokenNameendif) {
1634 if (token == TokenNameif) { //'else if'
1636 elseifStatementList();
1638 throwSyntaxError("':' expected after 'else'.");
1642 case TokenNameelseif :
1644 elseifStatementList();
1648 if (token != TokenNameendif) {
1649 throwSyntaxError("'endif' expected.");
1652 if (token != TokenNameSEMICOLON) {
1653 throwSyntaxError("';' expected after if-statement.");
1657 // statement [else-statement]
1658 statement(TokenNameEOF);
1659 if (token == TokenNameelseif) {
1661 if (token == TokenNameLPAREN) {
1664 throwSyntaxError("'(' expected after 'elseif' keyword.");
1667 if (token == TokenNameRPAREN) {
1670 throwSyntaxError("')' expected after 'elseif' condition.");
1673 } else if (token == TokenNameelse) {
1675 statement(TokenNameEOF);
1679 private void elseifStatementList() {
1683 case TokenNameelse :
1685 if (token == TokenNameCOLON) {
1687 if (token != TokenNameendif) {
1692 if (token == TokenNameif) { //'else if'
1695 throwSyntaxError("':' expected after 'else'.");
1699 case TokenNameelseif :
1707 private void elseifStatement() {
1708 if (token == TokenNameLPAREN) {
1711 if (token != TokenNameRPAREN) {
1712 throwSyntaxError("')' expected in else-if-statement.");
1715 if (token != TokenNameCOLON) {
1716 throwSyntaxError("':' expected in else-if-statement.");
1719 if (token != TokenNameendif) {
1724 private void switchStatement() {
1725 if (token == TokenNameCOLON) {
1726 // ':' [labeled-statement-list] 'endswitch' ';'
1728 labeledStatementList();
1729 if (token != TokenNameendswitch) {
1730 throwSyntaxError("'endswitch' expected.");
1733 if (token != TokenNameSEMICOLON) {
1734 throwSyntaxError("';' expected after switch-statement.");
1738 // '{' [labeled-statement-list] '}'
1739 if (token != TokenNameLBRACE) {
1740 throwSyntaxError("'{' expected in switch statement.");
1743 if (token != TokenNameRBRACE) {
1744 labeledStatementList();
1746 if (token != TokenNameRBRACE) {
1747 throwSyntaxError("'}' expected in switch statement.");
1752 private void forStatement() {
1753 if (token == TokenNameCOLON) {
1756 if (token != TokenNameendfor) {
1757 throwSyntaxError("'endfor' expected.");
1760 if (token != TokenNameSEMICOLON) {
1761 throwSyntaxError("';' expected after for-statement.");
1765 statement(TokenNameEOF);
1768 private void whileStatement() {
1769 // ':' statement-list 'endwhile' ';'
1770 if (token == TokenNameCOLON) {
1773 if (token != TokenNameendwhile) {
1774 throwSyntaxError("'endwhile' expected.");
1777 if (token != TokenNameSEMICOLON) {
1778 throwSyntaxError("';' expected after while-statement.");
1782 statement(TokenNameEOF);
1785 private void foreachStatement() {
1786 if (token == TokenNameCOLON) {
1789 if (token != TokenNameendforeach) {
1790 throwSyntaxError("'endforeach' expected.");
1793 if (token != TokenNameSEMICOLON) {
1794 throwSyntaxError("';' expected after foreach-statement.");
1798 statement(TokenNameEOF);
1801 // private void exitStatus() {
1802 // if (token == TokenNameLPAREN) {
1805 // throwSyntaxError("'(' expected in 'exit-status'.");
1807 // if (token != TokenNameRPAREN) {
1810 // if (token == TokenNameRPAREN) {
1813 // throwSyntaxError("')' expected after 'exit-status'.");
1816 private void expressionList() {
1819 if (token == TokenNameCOMMA) {
1826 private void expr() {
1828 // | expr_without_variable
1829 // if (token!=TokenNameEOF) {
1830 if (Scanner.TRACE) {
1831 System.out.println("TRACE: expr()");
1833 expr_without_variable(true);
1836 private void expr_without_variable(boolean only_variable) {
1837 // internal_functions_in_yacc
1846 // | T_INC rw_variable
1847 // | T_DEC rw_variable
1848 // | T_INT_CAST expr
1849 // | T_DOUBLE_CAST expr
1850 // | T_STRING_CAST expr
1851 // | T_ARRAY_CAST expr
1852 // | T_OBJECT_CAST expr
1853 // | T_BOOL_CAST expr
1854 // | T_UNSET_CAST expr
1855 // | T_EXIT exit_expr
1857 // | T_ARRAY '(' array_pair_list ')'
1858 // | '`' encaps_list '`'
1859 // | T_LIST '(' assignment_list ')' '=' expr
1860 // | T_NEW class_name_reference ctor_arguments
1861 // | variable '=' expr
1862 // | variable '=' '&' variable
1863 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
1864 // | variable T_PLUS_EQUAL expr
1865 // | variable T_MINUS_EQUAL expr
1866 // | variable T_MUL_EQUAL expr
1867 // | variable T_DIV_EQUAL expr
1868 // | variable T_CONCAT_EQUAL expr
1869 // | variable T_MOD_EQUAL expr
1870 // | variable T_AND_EQUAL expr
1871 // | variable T_OR_EQUAL expr
1872 // | variable T_XOR_EQUAL expr
1873 // | variable T_SL_EQUAL expr
1874 // | variable T_SR_EQUAL expr
1875 // | rw_variable T_INC
1876 // | rw_variable T_DEC
1877 // | expr T_BOOLEAN_OR expr
1878 // | expr T_BOOLEAN_AND expr
1879 // | expr T_LOGICAL_OR expr
1880 // | expr T_LOGICAL_AND expr
1881 // | expr T_LOGICAL_XOR expr
1893 // | expr T_IS_IDENTICAL expr
1894 // | expr T_IS_NOT_IDENTICAL expr
1895 // | expr T_IS_EQUAL expr
1896 // | expr T_IS_NOT_EQUAL expr
1898 // | expr T_IS_SMALLER_OR_EQUAL expr
1900 // | expr T_IS_GREATER_OR_EQUAL expr
1901 // | expr T_INSTANCEOF class_name_reference
1902 // | expr '?' expr ':' expr
1903 if (Scanner.TRACE) {
1904 System.out.println("TRACE: expr_without_variable() PART 1");
1907 case TokenNameisset :
1908 case TokenNameempty :
1909 case TokenNameeval :
1910 case TokenNameinclude :
1911 case TokenNameinclude_once :
1912 case TokenNamerequire :
1913 case TokenNamerequire_once :
1914 internal_functions_in_yacc();
1917 case TokenNameLPAREN :
1920 if (token == TokenNameRPAREN) {
1923 throwSyntaxError("')' expected in expression.");
1933 // | T_INT_CAST expr
1934 // | T_DOUBLE_CAST expr
1935 // | T_STRING_CAST expr
1936 // | T_ARRAY_CAST expr
1937 // | T_OBJECT_CAST expr
1938 // | T_BOOL_CAST expr
1939 // | T_UNSET_CAST expr
1940 case TokenNameclone :
1941 case TokenNameprint :
1943 case TokenNamePLUS :
1944 case TokenNameMINUS :
1946 case TokenNameTWIDDLE :
1947 case TokenNameintCAST :
1948 case TokenNamedoubleCAST :
1949 case TokenNamestringCAST :
1950 case TokenNamearrayCAST :
1951 case TokenNameobjectCAST :
1952 case TokenNameboolCAST :
1953 case TokenNameunsetCAST :
1957 case TokenNameexit :
1963 //| T_STRING_VARNAME
1965 //| T_START_HEREDOC encaps_list T_END_HEREDOC
1966 // | '`' encaps_list '`'
1968 // | '`' encaps_list '`'
1969 case TokenNameEncapsedString0 :
1970 scanner.encapsedStringStack.push(new Character('`'));
1973 if (token == TokenNameEncapsedString0) {
1976 if (token != TokenNameEncapsedString0) {
1977 throwSyntaxError("\'`\' expected at end of string"
1978 + "(Found token: " + scanner.toStringAction(token) + " )");
1982 scanner.encapsedStringStack.pop();
1986 // | '\'' encaps_list '\''
1987 case TokenNameEncapsedString1 :
1988 scanner.encapsedStringStack.push(new Character('\''));
1991 if (token == TokenNameEncapsedString1) {
1994 if (token != TokenNameEncapsedString1) {
1995 throwSyntaxError("\'\'\' expected at end of string"
1996 + "(Found token: " + scanner.toStringAction(token) + " )");
2000 scanner.encapsedStringStack.pop();
2004 //| '"' encaps_list '"'
2005 case TokenNameEncapsedString2 :
2006 scanner.encapsedStringStack.push(new Character('"'));
2009 if (token == TokenNameEncapsedString2) {
2012 if (token != TokenNameEncapsedString2) {
2013 throwSyntaxError("'\"' expected at end of string"
2014 + "(Found token: " + scanner.toStringAction(token) + " )");
2018 scanner.encapsedStringStack.pop();
2022 case TokenNameIntegerLiteral :
2023 case TokenNameDoubleLiteral :
2024 case TokenNameStringLiteral :
2025 case TokenNameStringConstant :
2026 case TokenNameStringInterpolated :
2027 case TokenNameFILE :
2028 case TokenNameLINE :
2029 case TokenNameCLASS_C :
2030 case TokenNameMETHOD_C :
2031 case TokenNameFUNC_C :
2034 case TokenNameHEREDOC :
2037 case TokenNamearray :
2038 // T_ARRAY '(' array_pair_list ')'
2040 if (token == TokenNameLPAREN) {
2042 if (token == TokenNameRPAREN) {
2047 if (token != TokenNameRPAREN) {
2048 throwSyntaxError("')' expected after keyword 'array'"
2049 + "(Found token: " + scanner.toStringAction(token) + ")");
2053 throwSyntaxError("'(' expected after keyword 'array'"
2054 + "(Found token: " + scanner.toStringAction(token) + ")");
2057 case TokenNamelist :
2058 // | T_LIST '(' assignment_list ')' '=' expr
2060 if (token == TokenNameLPAREN) {
2063 if (token != TokenNameRPAREN) {
2064 throwSyntaxError("')' expected after 'list' keyword.");
2067 if (token != TokenNameEQUAL) {
2068 throwSyntaxError("'=' expected after 'list' keyword.");
2073 throwSyntaxError("'(' expected after 'list' keyword.");
2077 // | T_NEW class_name_reference ctor_arguments
2079 class_name_reference();
2082 // | T_INC rw_variable
2083 // | T_DEC rw_variable
2084 case TokenNamePLUS_PLUS :
2085 case TokenNameMINUS_MINUS :
2089 // | variable '=' expr
2090 // | variable '=' '&' variable
2091 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2092 // | variable T_PLUS_EQUAL expr
2093 // | variable T_MINUS_EQUAL expr
2094 // | variable T_MUL_EQUAL expr
2095 // | variable T_DIV_EQUAL expr
2096 // | variable T_CONCAT_EQUAL expr
2097 // | variable T_MOD_EQUAL expr
2098 // | variable T_AND_EQUAL expr
2099 // | variable T_OR_EQUAL expr
2100 // | variable T_XOR_EQUAL expr
2101 // | variable T_SL_EQUAL expr
2102 // | variable T_SR_EQUAL expr
2103 // | rw_variable T_INC
2104 // | rw_variable T_DEC
2105 case TokenNameIdentifier :
2106 case TokenNameVariable :
2107 case TokenNameDOLLAR :
2110 case TokenNameEQUAL :
2112 if (token == TokenNameAND) {
2114 if (token == TokenNamenew) {
2115 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2117 class_name_reference();
2126 case TokenNamePLUS_EQUAL :
2127 case TokenNameMINUS_EQUAL :
2128 case TokenNameMULTIPLY_EQUAL :
2129 case TokenNameDIVIDE_EQUAL :
2130 case TokenNameDOT_EQUAL :
2131 case TokenNameREMAINDER_EQUAL :
2132 case TokenNameAND_EQUAL :
2133 case TokenNameOR_EQUAL :
2134 case TokenNameXOR_EQUAL :
2135 case TokenNameRIGHT_SHIFT_EQUAL :
2136 case TokenNameLEFT_SHIFT_EQUAL :
2140 case TokenNamePLUS_PLUS :
2141 case TokenNameMINUS_MINUS :
2145 if (!only_variable) {
2146 throwSyntaxError("Variable expression not allowed (found token '"
2147 + scanner.toStringAction(token) + "').");
2152 if (token != TokenNameINLINE_HTML) {
2153 throwSyntaxError("Error in expression (found token '"
2154 + scanner.toStringAction(token) + "').");
2158 if (Scanner.TRACE) {
2159 System.out.println("TRACE: expr_without_variable() PART 2");
2161 // | expr T_BOOLEAN_OR expr
2162 // | expr T_BOOLEAN_AND expr
2163 // | expr T_LOGICAL_OR expr
2164 // | expr T_LOGICAL_AND expr
2165 // | expr T_LOGICAL_XOR expr
2177 // | expr T_IS_IDENTICAL expr
2178 // | expr T_IS_NOT_IDENTICAL expr
2179 // | expr T_IS_EQUAL expr
2180 // | expr T_IS_NOT_EQUAL expr
2182 // | expr T_IS_SMALLER_OR_EQUAL expr
2184 // | expr T_IS_GREATER_OR_EQUAL expr
2187 case TokenNameOR_OR :
2188 case TokenNameAND_AND :
2196 case TokenNamePLUS :
2197 case TokenNameMINUS :
2198 case TokenNameMULTIPLY :
2199 case TokenNameDIVIDE :
2200 case TokenNameREMAINDER :
2201 case TokenNameLEFT_SHIFT :
2202 case TokenNameRIGHT_SHIFT :
2203 case TokenNameEQUAL_EQUAL_EQUAL :
2204 case TokenNameNOT_EQUAL_EQUAL :
2205 case TokenNameEQUAL_EQUAL :
2206 case TokenNameNOT_EQUAL :
2207 case TokenNameLESS :
2208 case TokenNameLESS_EQUAL :
2209 case TokenNameGREATER :
2210 case TokenNameGREATER_EQUAL :
2214 // | expr T_INSTANCEOF class_name_reference
2215 // | expr '?' expr ':' expr
2216 case TokenNameinstanceof :
2218 class_name_reference();
2220 case TokenNameQUESTION :
2223 if (token == TokenNameCOLON) {
2233 private void class_name_reference() {
2234 // class_name_reference:
2236 //| dynamic_class_name_reference
2237 if (Scanner.TRACE) {
2238 System.out.println("TRACE: class_name_reference()");
2240 if (token == TokenNameIdentifier) {
2243 dynamic_class_name_reference();
2246 private void dynamic_class_name_reference() {
2247 //dynamic_class_name_reference:
2248 // base_variable T_OBJECT_OPERATOR object_property
2249 // dynamic_class_name_variable_properties
2251 if (Scanner.TRACE) {
2252 System.out.println("TRACE: dynamic_class_name_reference()");
2255 if (token == TokenNameMINUS_GREATER) {
2258 dynamic_class_name_variable_properties();
2261 private void dynamic_class_name_variable_properties() {
2262 // dynamic_class_name_variable_properties:
2263 // dynamic_class_name_variable_properties
2264 // dynamic_class_name_variable_property
2266 if (Scanner.TRACE) {
2267 System.out.println("TRACE: dynamic_class_name_variable_properties()");
2269 while (token == TokenNameMINUS_GREATER) {
2270 dynamic_class_name_variable_property();
2273 private void dynamic_class_name_variable_property() {
2274 // dynamic_class_name_variable_property:
2275 // T_OBJECT_OPERATOR object_property
2276 if (Scanner.TRACE) {
2277 System.out.println("TRACE: dynamic_class_name_variable_property()");
2279 if (token == TokenNameMINUS_GREATER) {
2284 private void ctor_arguments() {
2287 //| '(' function_call_parameter_list ')'
2288 if (token == TokenNameLPAREN) {
2290 if (token == TokenNameRPAREN) {
2294 non_empty_function_call_parameter_list();
2295 if (token != TokenNameRPAREN) {
2296 throwSyntaxError("')' expected in ctor_arguments.");
2301 private void assignment_list() {
2303 // assignment_list ',' assignment_list_element
2304 //| assignment_list_element
2306 assignment_list_element();
2307 if (token != TokenNameCOMMA) {
2313 private void assignment_list_element() {
2314 //assignment_list_element:
2316 //| T_LIST '(' assignment_list ')'
2318 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2321 if (token == TokenNamelist) {
2323 if (token == TokenNameLPAREN) {
2326 if (token != TokenNameRPAREN) {
2327 throwSyntaxError("')' expected after 'list' keyword.");
2331 throwSyntaxError("'(' expected after 'list' keyword.");
2336 private void array_pair_list() {
2339 //| non_empty_array_pair_list possible_comma
2340 non_empty_array_pair_list();
2341 if (token == TokenNameCOMMA) {
2345 private void non_empty_array_pair_list() {
2346 //non_empty_array_pair_list:
2347 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2348 //| non_empty_array_pair_list ',' expr
2349 //| expr T_DOUBLE_ARROW expr
2351 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2352 //| non_empty_array_pair_list ',' '&' w_variable
2353 //| expr T_DOUBLE_ARROW '&' w_variable
2356 if (token == TokenNameAND) {
2361 if (token == TokenNameAND) {
2364 } else if (token == TokenNameEQUAL_GREATER) {
2366 if (token == TokenNameAND) {
2374 if (token != TokenNameCOMMA) {
2378 if (token == TokenNameRPAREN) {
2383 // private void variableList() {
2386 // if (token == TokenNameCOMMA) {
2393 private void variable_without_objects() {
2394 // variable_without_objects:
2395 // reference_variable
2396 // | simple_indirect_reference reference_variable
2397 if (Scanner.TRACE) {
2398 System.out.println("TRACE: variable_without_objects()");
2400 while (token == TokenNameDOLLAR) {
2403 reference_variable();
2405 private void function_call() {
2407 // T_STRING '(' function_call_parameter_list ')'
2408 //| class_constant '(' function_call_parameter_list ')'
2409 //| static_member '(' function_call_parameter_list ')'
2410 //| variable_without_objects '(' function_call_parameter_list ')'
2411 if (Scanner.TRACE) {
2412 System.out.println("TRACE: function_call()");
2414 if (token == TokenNameIdentifier) {
2417 case TokenNamePAAMAYIM_NEKUDOTAYIM :
2420 if (token == TokenNameIdentifier) {
2425 variable_without_objects();
2430 variable_without_objects();
2432 if (token != TokenNameLPAREN) {
2433 // TODO is this ok ?
2435 // throwSyntaxError("'(' expected in function call.");
2438 if (token == TokenNameRPAREN) {
2442 non_empty_function_call_parameter_list();
2443 if (token != TokenNameRPAREN) {
2444 throwSyntaxError("')' expected in function call.");
2448 // private void function_call_parameter_list() {
2449 // function_call_parameter_list:
2450 // non_empty_function_call_parameter_list { $$ = $1; }
2453 private void non_empty_function_call_parameter_list() {
2454 //non_empty_function_call_parameter_list:
2455 // expr_without_variable
2458 // | non_empty_function_call_parameter_list ',' expr_without_variable
2459 // | non_empty_function_call_parameter_list ',' variable
2460 // | non_empty_function_call_parameter_list ',' '&' w_variable
2461 if (Scanner.TRACE) {
2462 System.out.println("TRACE: non_empty_function_call_parameter_list()");
2465 if (token == TokenNameAND) {
2469 // if (token == TokenNameIdentifier || token == TokenNameVariable
2470 // || token == TokenNameDOLLAR) {
2473 expr_without_variable(true);
2476 if (token != TokenNameCOMMA) {
2482 private void fully_qualified_class_name() {
2483 if (token == TokenNameIdentifier) {
2486 throwSyntaxError("Class name expected.");
2489 private void static_member() {
2491 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2492 // variable_without_objects
2493 if (Scanner.TRACE) {
2494 System.out.println("TRACE: static_member()");
2496 fully_qualified_class_name();
2497 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2498 throwSyntaxError("'::' expected after class name (static_member).");
2501 variable_without_objects();
2503 private void base_variable_with_function_calls() {
2504 // base_variable_with_function_calls:
2507 boolean functionCall = false;
2508 if (Scanner.TRACE) {
2509 System.out.println("TRACE: base_variable_with_function_calls()");
2511 // if (token == TokenNameIdentifier) {
2512 // functionCall = true;
2513 // } else if (token == TokenNameVariable) {
2514 // int tempToken = token;
2515 // int tempPosition = scanner.currentPosition;
2517 // if (token == TokenNameLPAREN) {
2518 // functionCall = true;
2520 // token = tempToken;
2521 // scanner.currentPosition = tempPosition;
2522 // scanner.phpMode = true;
2524 // if (functionCall) {
2530 private void base_variable() {
2532 // reference_variable
2533 // | simple_indirect_reference reference_variable
2535 if (Scanner.TRACE) {
2536 System.out.println("TRACE: base_variable()");
2538 if (token == TokenNameIdentifier) {
2541 while (token == TokenNameDOLLAR) {
2544 reference_variable();
2547 // private void simple_indirect_reference() {
2548 // // simple_indirect_reference:
2550 // //| simple_indirect_reference '$'
2552 private void reference_variable() {
2553 // reference_variable:
2554 // reference_variable '[' dim_offset ']'
2555 // | reference_variable '{' expr '}'
2556 // | compound_variable
2557 if (Scanner.TRACE) {
2558 System.out.println("TRACE: reference_variable()");
2560 compound_variable();
2562 if (token == TokenNameLBRACE) {
2565 if (token != TokenNameRBRACE) {
2566 throwSyntaxError("'}' expected in reference variable.");
2569 } else if (token == TokenNameLBRACKET) {
2571 if (token != TokenNameRBRACKET) {
2574 if (token != TokenNameRBRACKET) {
2575 throwSyntaxError("']' expected in reference variable.");
2584 private void compound_variable() {
2585 // compound_variable:
2587 // | '$' '{' expr '}'
2588 if (Scanner.TRACE) {
2589 System.out.println("TRACE: compound_variable()");
2591 if (token == TokenNameVariable) {
2594 // because of simple_indirect_reference
2595 while (token == TokenNameDOLLAR) {
2598 if (token != TokenNameLBRACE) {
2599 throwSyntaxError("'{' expected after compound variable token '$'.");
2603 if (token != TokenNameRBRACE) {
2604 throwSyntaxError("'}' expected after compound variable token '$'.");
2609 // private void dim_offset() {
2615 private void object_property() {
2618 //| variable_without_objects
2619 if (Scanner.TRACE) {
2620 System.out.println("TRACE: object_property()");
2622 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2623 variable_without_objects();
2628 private void object_dim_list() {
2630 // object_dim_list '[' dim_offset ']'
2631 //| object_dim_list '{' expr '}'
2633 if (Scanner.TRACE) {
2634 System.out.println("TRACE: object_dim_list()");
2638 if (token == TokenNameLBRACE) {
2641 if (token != TokenNameRBRACE) {
2642 throwSyntaxError("'}' expected in object_dim_list.");
2645 } else if (token == TokenNameLBRACKET) {
2647 if (token == TokenNameRBRACKET) {
2652 if (token != TokenNameRBRACKET) {
2653 throwSyntaxError("']' expected in object_dim_list.");
2661 private void variable_name() {
2665 if (Scanner.TRACE) {
2666 System.out.println("TRACE: variable_name()");
2668 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
2669 if (token > TokenNameKEYWORD) {
2670 // TODO show a warning "Keyword used as variable" ?
2674 if (token != TokenNameLBRACE) {
2675 throwSyntaxError("'{' expected in variable name.");
2679 if (token != TokenNameRBRACE) {
2680 throwSyntaxError("'}' expected in variable name.");
2685 private void r_variable() {
2688 private void w_variable() {
2691 private void rw_variable() {
2694 private void variable() {
2696 // base_variable_with_function_calls T_OBJECT_OPERATOR
2697 // object_property method_or_not variable_properties
2698 // | base_variable_with_function_calls
2699 base_variable_with_function_calls();
2700 if (token == TokenNameMINUS_GREATER) {
2704 variable_properties();
2706 // if (token == TokenNameDOLLAR_LBRACE) {
2710 // if (token != TokenNameRBRACE) {
2711 // throwSyntaxError("'}' expected after indirect variable token '${'.");
2715 // if (token == TokenNameVariable) {
2717 // if (token == TokenNameLBRACKET) {
2720 // if (token != TokenNameRBRACKET) {
2721 // throwSyntaxError("']' expected in variable-list.");
2724 // } else if (token == TokenNameEQUAL) {
2729 // throwSyntaxError("$-variable expected in variable-list.");
2733 private void variable_properties() {
2734 // variable_properties:
2735 // variable_properties variable_property
2737 while (token == TokenNameMINUS_GREATER) {
2738 variable_property();
2741 private void variable_property() {
2742 // variable_property:
2743 // T_OBJECT_OPERATOR object_property method_or_not
2744 if (Scanner.TRACE) {
2745 System.out.println("TRACE: variable_property()");
2747 if (token == TokenNameMINUS_GREATER) {
2752 throwSyntaxError("'->' expected in variable_property.");
2755 private void method_or_not() {
2757 // '(' function_call_parameter_list ')'
2759 if (Scanner.TRACE) {
2760 System.out.println("TRACE: method_or_not()");
2762 if (token == TokenNameLPAREN) {
2764 if (token == TokenNameRPAREN) {
2768 non_empty_function_call_parameter_list();
2769 if (token != TokenNameRPAREN) {
2770 throwSyntaxError("')' expected in method_or_not.");
2775 private void exit_expr() {
2779 if (token != TokenNameLPAREN) {
2783 if (token == TokenNameRPAREN) {
2788 if (token != TokenNameRPAREN) {
2789 throwSyntaxError("')' expected after keyword 'exit'");
2793 private void encaps_list() {
2794 // encaps_list encaps_var
2795 // | encaps_list T_STRING
2796 // | encaps_list T_NUM_STRING
2797 // | encaps_list T_ENCAPSED_AND_WHITESPACE
2798 // | encaps_list T_CHARACTER
2799 // | encaps_list T_BAD_CHARACTER
2800 // | encaps_list '['
2801 // | encaps_list ']'
2802 // | encaps_list '{'
2803 // | encaps_list '}'
2804 // | encaps_list T_OBJECT_OPERATOR
2808 case TokenNameSTRING :
2811 case TokenNameLBRACE :
2812 // scanner.encapsedStringStack.pop();
2815 case TokenNameRBRACE :
2816 // scanner.encapsedStringStack.pop();
2819 case TokenNameLBRACKET :
2820 // scanner.encapsedStringStack.pop();
2823 case TokenNameRBRACKET :
2824 // scanner.encapsedStringStack.pop();
2827 case TokenNameMINUS_GREATER :
2828 // scanner.encapsedStringStack.pop();
2831 case TokenNameVariable :
2832 case TokenNameDOLLAR_LBRACE :
2833 case TokenNameCURLY_OPEN :
2836 // case TokenNameDOLLAR :
2838 // if (token == TokenNameLBRACE) {
2839 // token = TokenNameDOLLAR_LBRACE;
2844 char encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2846 if (encapsedChar == '$') {
2847 scanner.encapsedStringStack.pop();
2848 encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2850 switch (encapsedChar) {
2852 if (token == TokenNameEncapsedString0) {
2855 token = TokenNameSTRING;
2858 if (token == TokenNameEncapsedString1) {
2861 token = TokenNameSTRING;
2864 if (token == TokenNameEncapsedString2) {
2867 token = TokenNameSTRING;
2875 private void encaps_var() {
2877 // | T_VARIABLE '[' encaps_var_offset ']'
2878 // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
2879 // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
2880 // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
2881 // | T_CURLY_OPEN variable '}'
2883 case TokenNameVariable :
2885 if (token == TokenNameLBRACKET) {
2887 // if (token == TokenNameRBRACKET) {
2890 expr(); //encaps_var_offset();
2891 if (token != TokenNameRBRACKET) {
2892 throwSyntaxError("']' expected after variable.");
2894 // scanner.encapsedStringStack.pop();
2897 } else if (token == TokenNameMINUS_GREATER) {
2899 if (token != TokenNameIdentifier) {
2900 throwSyntaxError("Identifier expected after '->'.");
2902 // scanner.encapsedStringStack.pop();
2906 // // scanner.encapsedStringStack.pop();
2907 // int tempToken = TokenNameSTRING;
2908 // if (!scanner.encapsedStringStack.isEmpty()
2909 // && (token == TokenNameEncapsedString0
2910 // || token == TokenNameEncapsedString1
2911 // || token == TokenNameEncapsedString2 || token == TokenNameERROR)) {
2912 // char encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2915 // case TokenNameEncapsedString0 :
2916 // if (encapsedChar == '`') {
2917 // tempToken = TokenNameEncapsedString0;
2920 // case TokenNameEncapsedString1 :
2921 // if (encapsedChar == '\'') {
2922 // tempToken = TokenNameEncapsedString1;
2925 // case TokenNameEncapsedString2 :
2926 // if (encapsedChar == '"') {
2927 // tempToken = TokenNameEncapsedString2;
2930 // case TokenNameERROR :
2931 // if (scanner.source[scanner.currentPosition - 1] == '\\') {
2932 // scanner.currentPosition--;
2938 // token = tempToken;
2941 case TokenNameDOLLAR_LBRACE :
2943 if (token == TokenNameIdentifier) {
2945 if (token == TokenNameLBRACKET) {
2947 // if (token == TokenNameRBRACKET) {
2951 if (token != TokenNameRBRACKET) {
2952 throwSyntaxError("']' expected after '${'.");
2957 if (token != TokenNameRBRACE) {
2958 throwSyntaxError("'}' expected after '${'.");
2960 // scanner.encapsedStringStack.pop();
2964 if (token != TokenNameRBRACE) {
2965 throwSyntaxError("'}' expected.");
2967 // scanner.encapsedStringStack.pop();
2971 case TokenNameCURLY_OPEN :
2973 if (token == TokenNameIdentifier) {
2975 if (token == TokenNameLBRACKET) {
2977 // if (token == TokenNameRBRACKET) {
2981 if (token != TokenNameRBRACKET) {
2982 throwSyntaxError("']' expected after '{$'.");
2986 } else if (token == TokenNameMINUS_GREATER) {
2988 if (token != TokenNameIdentifier) {
2989 throwSyntaxError("String token expected.");
2993 // if (token != TokenNameRBRACE) {
2994 // throwSyntaxError("'}' expected after '{$'.");
2996 // // scanner.encapsedStringStack.pop();
3000 if (token != TokenNameRBRACE) {
3001 throwSyntaxError("'}' expected.");
3003 // scanner.encapsedStringStack.pop();
3009 private void encaps_var_offset() {
3014 case TokenNameSTRING :
3017 case TokenNameIntegerLiteral :
3020 case TokenNameVariable :
3023 case TokenNameIdentifier :
3027 throwSyntaxError("Variable or String token expected.");
3031 private void internal_functions_in_yacc() {
3033 case TokenNameisset :
3034 // T_ISSET '(' isset_variables ')'
3036 if (token != TokenNameLPAREN) {
3037 throwSyntaxError("'(' expected after keyword 'isset'");
3041 if (token != TokenNameRPAREN) {
3042 throwSyntaxError("')' expected after keyword 'isset'");
3046 case TokenNameempty :
3047 // T_EMPTY '(' variable ')'
3049 if (token != TokenNameLPAREN) {
3050 throwSyntaxError("'(' expected after keyword 'empty'");
3054 if (token != TokenNameRPAREN) {
3055 throwSyntaxError("')' expected after keyword 'empty'");
3059 case TokenNameinclude :
3064 case TokenNameinclude_once :
3065 // T_INCLUDE_ONCE expr
3069 case TokenNameeval :
3070 // T_EVAL '(' expr ')'
3072 if (token != TokenNameLPAREN) {
3073 throwSyntaxError("'(' expected after keyword 'eval'");
3077 if (token != TokenNameRPAREN) {
3078 throwSyntaxError("')' expected after keyword 'eval'");
3082 case TokenNamerequire :
3087 case TokenNamerequire_once :
3088 // T_REQUIRE_ONCE expr
3094 private void isset_variables() {
3096 // | isset_variables ','
3097 if (token == TokenNameRPAREN) {
3098 throwSyntaxError("Variable expected after keyword 'isset'");
3102 if (token == TokenNameCOMMA) {
3109 private boolean common_scalar() {
3113 // | T_CONSTANT_ENCAPSED_STRING
3120 case TokenNameIntegerLiteral :
3123 case TokenNameDoubleLiteral :
3126 case TokenNameStringLiteral :
3129 case TokenNameStringConstant :
3132 case TokenNameStringInterpolated :
3135 case TokenNameFILE :
3138 case TokenNameLINE :
3141 case TokenNameCLASS_C :
3144 case TokenNameMETHOD_C :
3147 case TokenNameFUNC_C :
3153 private void scalar() {
3156 //| T_STRING_VARNAME
3159 //| '"' encaps_list '"'
3160 //| '\'' encaps_list '\''
3161 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3162 throwSyntaxError("Not yet implemented (scalar).");
3164 private void static_scalar() {
3165 // static_scalar: /* compile-time evaluated scalars */
3168 // | '+' static_scalar
3169 // | '-' static_scalar
3170 // | T_ARRAY '(' static_array_pair_list ')'
3171 // | static_class_constant
3172 if (common_scalar()) {
3176 case TokenNameIdentifier :
3178 // static_class_constant:
3179 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3180 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3182 if (token == TokenNameIdentifier) {
3185 throwSyntaxError("Identifier expected after '::' operator.");
3189 case TokenNameEncapsedString0 :
3191 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3192 while (scanner.currentCharacter != '`') {
3193 if (scanner.currentCharacter == '\\') {
3194 scanner.currentPosition++;
3196 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3199 } catch (IndexOutOfBoundsException e) {
3200 throwSyntaxError("'`' expected at end of static string.");
3203 case TokenNameEncapsedString1 :
3205 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3206 while (scanner.currentCharacter != '\'') {
3207 if (scanner.currentCharacter == '\\') {
3208 scanner.currentPosition++;
3210 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3213 } catch (IndexOutOfBoundsException e) {
3214 throwSyntaxError("'\'' expected at end of static string.");
3217 case TokenNameEncapsedString2 :
3219 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3220 while (scanner.currentCharacter != '"') {
3221 if (scanner.currentCharacter == '\\') {
3222 scanner.currentPosition++;
3224 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3227 } catch (IndexOutOfBoundsException e) {
3228 throwSyntaxError("'\"' expected at end of static string.");
3231 case TokenNamePLUS :
3235 case TokenNameMINUS :
3239 case TokenNamearray :
3241 if (token != TokenNameLPAREN) {
3242 throwSyntaxError("'(' expected after keyword 'array'");
3245 if (token == TokenNameRPAREN) {
3249 non_empty_static_array_pair_list();
3250 if (token != TokenNameRPAREN) {
3251 throwSyntaxError("')' expected after keyword 'array'");
3255 // case TokenNamenull :
3258 // case TokenNamefalse :
3261 // case TokenNametrue :
3265 throwSyntaxError("Static scalar/constant expected.");
3268 private void non_empty_static_array_pair_list() {
3269 // non_empty_static_array_pair_list:
3270 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3272 //| non_empty_static_array_pair_list ',' static_scalar
3273 //| static_scalar T_DOUBLE_ARROW static_scalar
3277 if (token == TokenNameEQUAL_GREATER) {
3281 if (token != TokenNameCOMMA) {
3285 if (token == TokenNameRPAREN) {
3290 public void reportSyntaxError() { //int act, int currentKind, int
3292 /* remember current scanner position */
3293 int startPos = scanner.startPosition;
3294 int currentPos = scanner.currentPosition;
3295 // String[] expectings;
3296 // String tokenName = name[symbol_index[currentKind]];
3297 //fetch all "accurate" possible terminals that could recover the error
3298 // int start, end = start = asi(stack[stateStackTop]);
3299 // while (asr[end] != 0)
3301 // int length = end - start;
3302 // expectings = new String[length];
3303 // if (length != 0) {
3304 // char[] indexes = new char[length];
3305 // System.arraycopy(asr, start, indexes, 0, length);
3306 // for (int i = 0; i < length; i++) {
3307 // expectings[i] = name[symbol_index[indexes[i]]];
3310 //if the pb is an EOF, try to tell the user that they are some
3311 // if (tokenName.equals(UNEXPECTED_EOF)) {
3312 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3313 // char[] tokenSource;
3315 // tokenSource = this.scanner.getCurrentTokenSource();
3316 // } catch (Exception e) {
3317 // tokenSource = new char[] {};
3319 // problemReporter().parseError(
3320 // this.scanner.startPosition,
3321 // this.scanner.currentPosition - 1,
3326 // } else { //the next test is HEAVILY grammar DEPENDENT.
3327 // if ((length == 14)
3328 // && (expectings[0] == "=") //$NON-NLS-1$
3329 // && (expectings[1] == "*=") //$NON-NLS-1$
3330 // && (expressionPtr > -1)) {
3331 // switch(currentKind) {
3332 // case TokenNameSEMICOLON:
3333 // case TokenNamePLUS:
3334 // case TokenNameMINUS:
3335 // case TokenNameDIVIDE:
3336 // case TokenNameREMAINDER:
3337 // case TokenNameMULTIPLY:
3338 // case TokenNameLEFT_SHIFT:
3339 // case TokenNameRIGHT_SHIFT:
3340 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3341 // case TokenNameLESS:
3342 // case TokenNameGREATER:
3343 // case TokenNameLESS_EQUAL:
3344 // case TokenNameGREATER_EQUAL:
3345 // case TokenNameEQUAL_EQUAL:
3346 // case TokenNameNOT_EQUAL:
3347 // case TokenNameXOR:
3348 // case TokenNameAND:
3349 // case TokenNameOR:
3350 // case TokenNameOR_OR:
3351 // case TokenNameAND_AND:
3352 // // the ; is not the expected token ==> it ends a statement when an
3353 // expression is not ended
3354 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3356 // case TokenNameRBRACE :
3357 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3360 // char[] tokenSource;
3362 // tokenSource = this.scanner.getCurrentTokenSource();
3363 // } catch (Exception e) {
3364 // tokenSource = new char[] {};
3366 // problemReporter().parseError(
3367 // this.scanner.startPosition,
3368 // this.scanner.currentPosition - 1,
3372 // this.checkAndReportBracketAnomalies(problemReporter());
3377 tokenSource = this.scanner.getCurrentTokenSource();
3378 } catch (Exception e) {
3379 tokenSource = new char[]{};
3381 // problemReporter().parseError(
3382 // this.scanner.startPosition,
3383 // this.scanner.currentPosition - 1,
3387 this.checkAndReportBracketAnomalies(problemReporter());
3390 /* reset scanner where it was */
3391 scanner.startPosition = startPos;
3392 scanner.currentPosition = currentPos;
3394 public static final int RoundBracket = 0;
3395 public static final int SquareBracket = 1;
3396 public static final int CurlyBracket = 2;
3397 public static final int BracketKinds = 3;
3398 protected int[] nestedMethod; //the ptr is nestedType
3399 protected int nestedType, dimensions;
3401 final static int AstStackIncrement = 100;
3402 protected int astPtr;
3403 protected AstNode[] astStack = new AstNode[AstStackIncrement];
3404 protected int astLengthPtr;
3405 protected int[] astLengthStack;
3406 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3407 public CompilationUnitDeclaration compilationUnit; /*
3408 * the result from parse()
3410 protected ReferenceContext referenceContext;
3411 protected ProblemReporter problemReporter;
3412 // protected CompilationResult compilationResult;
3414 * Returns this parser's problem reporter initialized with its reference
3415 * context. Also it is assumed that a problem is going to be reported, so
3416 * initializes the compilation result's line positions.
3418 public ProblemReporter problemReporter() {
3419 if (scanner.recordLineSeparator) {
3420 compilationUnit.compilationResult.lineSeparatorPositions = scanner
3423 problemReporter.referenceContext = referenceContext;
3424 return problemReporter;
3427 * Reconsider the entire source looking for inconsistencies in {} () []
3429 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3430 scanner.wasAcr = false;
3431 boolean anomaliesDetected = false;
3433 char[] source = scanner.source;
3434 int[] leftCount = {0, 0, 0};
3435 int[] rightCount = {0, 0, 0};
3436 int[] depths = {0, 0, 0};
3437 int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3438 int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3439 int[][] rightPositions = new int[][]{new int[10], new int[10],
3441 int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3442 scanner.currentPosition = scanner.initialPosition; //starting
3444 // (first-zero-based
3446 while (scanner.currentPosition < scanner.eofPosition) { //loop for
3451 // ---------Consume white space and handles
3452 // startPosition---------
3453 boolean isWhiteSpace;
3455 scanner.startPosition = scanner.currentPosition;
3456 // if (((scanner.currentCharacter =
3457 // source[scanner.currentPosition++]) == '\\') &&
3458 // (source[scanner.currentPosition] == 'u')) {
3459 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3461 if (scanner.recordLineSeparator
3462 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3463 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3464 // only record line positions we have not
3466 scanner.pushLineSeparator();
3469 isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3471 } while (isWhiteSpace
3472 && (scanner.currentPosition < scanner.eofPosition));
3473 // -------consume token until } is found---------
3474 switch (scanner.currentCharacter) {
3477 int index = leftCount[CurlyBracket]++;
3478 if (index == leftPositions[CurlyBracket].length) {
3479 System.arraycopy(leftPositions[CurlyBracket], 0,
3480 (leftPositions[CurlyBracket] = new int[index * 2]), 0,
3483 .arraycopy(leftDepths[CurlyBracket], 0,
3484 (leftDepths[CurlyBracket] = new int[index * 2]), 0,
3487 leftPositions[CurlyBracket][index] = scanner.startPosition;
3488 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3493 int index = rightCount[CurlyBracket]++;
3494 if (index == rightPositions[CurlyBracket].length) {
3495 System.arraycopy(rightPositions[CurlyBracket], 0,
3496 (rightPositions[CurlyBracket] = new int[index * 2]), 0,
3498 System.arraycopy(rightDepths[CurlyBracket], 0,
3499 (rightDepths[CurlyBracket] = new int[index * 2]), 0,
3502 rightPositions[CurlyBracket][index] = scanner.startPosition;
3503 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3508 int index = leftCount[RoundBracket]++;
3509 if (index == leftPositions[RoundBracket].length) {
3510 System.arraycopy(leftPositions[RoundBracket], 0,
3511 (leftPositions[RoundBracket] = new int[index * 2]), 0,
3514 .arraycopy(leftDepths[RoundBracket], 0,
3515 (leftDepths[RoundBracket] = new int[index * 2]), 0,
3518 leftPositions[RoundBracket][index] = scanner.startPosition;
3519 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3524 int index = rightCount[RoundBracket]++;
3525 if (index == rightPositions[RoundBracket].length) {
3526 System.arraycopy(rightPositions[RoundBracket], 0,
3527 (rightPositions[RoundBracket] = new int[index * 2]), 0,
3529 System.arraycopy(rightDepths[RoundBracket], 0,
3530 (rightDepths[RoundBracket] = new int[index * 2]), 0,
3533 rightPositions[RoundBracket][index] = scanner.startPosition;
3534 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3539 int index = leftCount[SquareBracket]++;
3540 if (index == leftPositions[SquareBracket].length) {
3541 System.arraycopy(leftPositions[SquareBracket], 0,
3542 (leftPositions[SquareBracket] = new int[index * 2]), 0,
3544 System.arraycopy(leftDepths[SquareBracket], 0,
3545 (leftDepths[SquareBracket] = new int[index * 2]), 0,
3548 leftPositions[SquareBracket][index] = scanner.startPosition;
3549 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3554 int index = rightCount[SquareBracket]++;
3555 if (index == rightPositions[SquareBracket].length) {
3556 System.arraycopy(rightPositions[SquareBracket], 0,
3557 (rightPositions[SquareBracket] = new int[index * 2]), 0,
3559 System.arraycopy(rightDepths[SquareBracket], 0,
3560 (rightDepths[SquareBracket] = new int[index * 2]), 0,
3563 rightPositions[SquareBracket][index] = scanner.startPosition;
3564 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3569 if (scanner.getNextChar('\\')) {
3570 scanner.scanEscapeCharacter();
3571 } else { // consume next character
3572 scanner.unicodeAsBackSlash = false;
3573 // if (((scanner.currentCharacter =
3574 // source[scanner.currentPosition++]) ==
3576 // (source[scanner.currentPosition] ==
3578 // scanner.getNextUnicodeChar();
3580 if (scanner.withoutUnicodePtr != 0) {
3581 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3585 scanner.getNextChar('\'');
3589 // consume next character
3590 scanner.unicodeAsBackSlash = false;
3591 // if (((scanner.currentCharacter =
3592 // source[scanner.currentPosition++]) == '\\') &&
3593 // (source[scanner.currentPosition] == 'u')) {
3594 // scanner.getNextUnicodeChar();
3596 if (scanner.withoutUnicodePtr != 0) {
3597 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3600 while (scanner.currentCharacter != '"') {
3601 if (scanner.currentCharacter == '\r') {
3602 if (source[scanner.currentPosition] == '\n')
3603 scanner.currentPosition++;
3604 break; // the string cannot go further that
3607 if (scanner.currentCharacter == '\n') {
3608 break; // the string cannot go further that
3611 if (scanner.currentCharacter == '\\') {
3612 scanner.scanEscapeCharacter();
3614 // consume next character
3615 scanner.unicodeAsBackSlash = false;
3616 // if (((scanner.currentCharacter =
3617 // source[scanner.currentPosition++]) == '\\')
3618 // && (source[scanner.currentPosition] == 'u'))
3620 // scanner.getNextUnicodeChar();
3622 if (scanner.withoutUnicodePtr != 0) {
3623 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3631 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3634 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3635 && (source[scanner.currentPosition] == 'u')) {
3636 //-------------unicode traitement
3638 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3639 scanner.currentPosition++;
3640 while (source[scanner.currentPosition] == 'u') {
3641 scanner.currentPosition++;
3644 .getNumericValue(source[scanner.currentPosition++])) > 15
3647 .getNumericValue(source[scanner.currentPosition++])) > 15
3650 .getNumericValue(source[scanner.currentPosition++])) > 15
3653 .getNumericValue(source[scanner.currentPosition++])) > 15
3654 || c4 < 0) { //error don't
3657 scanner.currentCharacter = 'A';
3658 } //something different from \n and \r
3660 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3663 while (scanner.currentCharacter != '\r'
3664 && scanner.currentCharacter != '\n') {
3666 scanner.startPosition = scanner.currentPosition;
3667 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3668 && (source[scanner.currentPosition] == 'u')) {
3669 //-------------unicode traitement
3671 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3672 scanner.currentPosition++;
3673 while (source[scanner.currentPosition] == 'u') {
3674 scanner.currentPosition++;
3677 .getNumericValue(source[scanner.currentPosition++])) > 15
3680 .getNumericValue(source[scanner.currentPosition++])) > 15
3683 .getNumericValue(source[scanner.currentPosition++])) > 15
3686 .getNumericValue(source[scanner.currentPosition++])) > 15
3687 || c4 < 0) { //error don't
3690 scanner.currentCharacter = 'A';
3691 } //something different from \n
3694 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3698 if (scanner.recordLineSeparator
3699 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3700 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3701 // only record line positions we
3702 // have not recorded yet
3703 scanner.pushLineSeparator();
3704 if (this.scanner.taskTags != null) {
3705 this.scanner.checkTaskTag(this.scanner
3706 .getCurrentTokenStartPosition(), this.scanner
3707 .getCurrentTokenEndPosition());
3713 if (test > 0) { //traditional and annotation
3715 boolean star = false;
3716 // consume next character
3717 scanner.unicodeAsBackSlash = false;
3718 // if (((scanner.currentCharacter =
3719 // source[scanner.currentPosition++]) ==
3721 // (source[scanner.currentPosition] ==
3723 // scanner.getNextUnicodeChar();
3725 if (scanner.withoutUnicodePtr != 0) {
3726 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3729 if (scanner.currentCharacter == '*') {
3733 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3734 && (source[scanner.currentPosition] == 'u')) {
3735 //-------------unicode traitement
3737 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3738 scanner.currentPosition++;
3739 while (source[scanner.currentPosition] == 'u') {
3740 scanner.currentPosition++;
3743 .getNumericValue(source[scanner.currentPosition++])) > 15
3746 .getNumericValue(source[scanner.currentPosition++])) > 15
3749 .getNumericValue(source[scanner.currentPosition++])) > 15
3752 .getNumericValue(source[scanner.currentPosition++])) > 15
3753 || c4 < 0) { //error don't
3756 scanner.currentCharacter = 'A';
3757 } //something different from * and /
3759 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3762 //loop until end of comment */
3763 while ((scanner.currentCharacter != '/') || (!star)) {
3764 star = scanner.currentCharacter == '*';
3766 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3767 && (source[scanner.currentPosition] == 'u')) {
3768 //-------------unicode traitement
3770 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3771 scanner.currentPosition++;
3772 while (source[scanner.currentPosition] == 'u') {
3773 scanner.currentPosition++;
3776 .getNumericValue(source[scanner.currentPosition++])) > 15
3779 .getNumericValue(source[scanner.currentPosition++])) > 15
3782 .getNumericValue(source[scanner.currentPosition++])) > 15
3785 .getNumericValue(source[scanner.currentPosition++])) > 15
3786 || c4 < 0) { //error don't
3789 scanner.currentCharacter = 'A';
3790 } //something different from * and
3793 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3797 if (this.scanner.taskTags != null) {
3798 this.scanner.checkTaskTag(this.scanner
3799 .getCurrentTokenStartPosition(), this.scanner
3800 .getCurrentTokenEndPosition());
3807 if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3808 scanner.scanIdentifierOrKeyword(false);
3811 if (Character.isDigit(scanner.currentCharacter)) {
3812 scanner.scanNumber(false);
3816 //-----------------end switch while
3817 // try--------------------
3818 } catch (IndexOutOfBoundsException e) {
3819 break; // read until EOF
3820 } catch (InvalidInputException e) {
3821 return false; // no clue
3824 if (scanner.recordLineSeparator) {
3825 // compilationUnit.compilationResult.lineSeparatorPositions =
3826 // scanner.getLineEnds();
3828 // check placement anomalies against other kinds of brackets
3829 for (int kind = 0; kind < BracketKinds; kind++) {
3830 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3831 int start = leftPositions[kind][leftIndex]; // deepest
3833 // find matching closing bracket
3834 int depth = leftDepths[kind][leftIndex];
3836 for (int i = 0; i < rightCount[kind]; i++) {
3837 int pos = rightPositions[kind][i];
3838 // want matching bracket further in source with same
3840 if ((pos > start) && (depth == rightDepths[kind][i])) {
3845 if (end < 0) { // did not find a good closing match
3846 problemReporter.unmatchedBracket(start, referenceContext,
3847 compilationUnit.compilationResult);
3850 // check if even number of opening/closing other brackets
3851 // in between this pair of brackets
3853 for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3854 for (int i = 0; i < leftCount[otherKind]; i++) {
3855 int pos = leftPositions[otherKind][i];
3856 if ((pos > start) && (pos < end))
3859 for (int i = 0; i < rightCount[otherKind]; i++) {
3860 int pos = rightPositions[otherKind][i];
3861 if ((pos > start) && (pos < end))
3865 problemReporter.unmatchedBracket(start, referenceContext,
3866 compilationUnit.compilationResult); //bracket
3872 // too many opening brackets ?
3873 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3874 anomaliesDetected = true;
3875 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind]
3876 - i - 1], referenceContext, compilationUnit.compilationResult);
3878 // too many closing brackets ?
3879 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3880 anomaliesDetected = true;
3881 problemReporter.unmatchedBracket(rightPositions[kind][i],
3882 referenceContext, compilationUnit.compilationResult);
3884 if (anomaliesDetected)
3887 return anomaliesDetected;
3888 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
3889 return anomaliesDetected;
3890 } catch (NullPointerException e) { // jdk1.2.2 jit bug
3891 return anomaliesDetected;
3894 protected void pushOnAstLengthStack(int pos) {
3896 astLengthStack[++astLengthPtr] = pos;
3897 } catch (IndexOutOfBoundsException e) {
3898 int oldStackLength = astLengthStack.length;
3899 int[] oldPos = astLengthStack;
3900 astLengthStack = new int[oldStackLength + StackIncrement];
3901 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3902 astLengthStack[astLengthPtr] = pos;
3905 protected void pushOnAstStack(AstNode node) {
3907 * add a new obj on top of the ast stack
3910 astStack[++astPtr] = node;
3911 } catch (IndexOutOfBoundsException e) {
3912 int oldStackLength = astStack.length;
3913 AstNode[] oldStack = astStack;
3914 astStack = new AstNode[oldStackLength + AstStackIncrement];
3915 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
3916 astPtr = oldStackLength;
3917 astStack[astPtr] = node;
3920 astLengthStack[++astLengthPtr] = 1;
3921 } catch (IndexOutOfBoundsException e) {
3922 int oldStackLength = astLengthStack.length;
3923 int[] oldPos = astLengthStack;
3924 astLengthStack = new int[oldStackLength + AstStackIncrement];
3925 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3926 astLengthStack[astLengthPtr] = 1;