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.FieldDeclaration;
24 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
25 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
26 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
27 import org.eclipse.core.resources.IFile;
28 public class Parser //extends PHPParserSuperclass
29 implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
30 //internal data for the automat
31 protected final static int StackIncrement = 255;
32 protected int stateStackTop;
33 protected int[] stack = new int[StackIncrement];
34 public int firstToken; // handle for multiple parsing goals
35 public int lastAct; //handle for multiple parsing goals
36 protected RecoveredElement currentElement;
37 public static boolean VERBOSE_RECOVERY = false;
38 protected boolean diet = false; //tells the scanner to jump over some
39 // parts of the code/expressions like
42 public Scanner scanner;
43 private ArrayList phpList;
44 private int currentPHPString;
45 private boolean phpEnd;
46 // private static HashMap keywordMap = null;
52 // row counter for syntax errors:
54 // column counter for syntax errors:
58 // // current identifier
62 private String stringValue;
63 /** Contains the current expression. */
64 // private StringBuffer expression;
65 //private boolean phpMode;
66 protected int modifiers;
67 protected int modifiersSourceStart;
69 this.currentPHPString = 0;
70 // PHPParserSuperclass.fileToParse = fileToParse;
73 this.token = TokenNameEOF;
76 // this.columnCount = 0;
79 this.initializeScanner();
81 public void setFileToParse(IFile fileToParse) {
82 this.currentPHPString = 0;
83 // PHPParserSuperclass.fileToParse = fileToParse;
86 this.token = TokenNameEOF;
88 this.initializeScanner();
91 * ClassDeclaration Constructor.
95 * Description of Parameter
98 public Parser(IFile fileToParse) {
99 // if (keywordMap == null) {
100 // keywordMap = new HashMap();
101 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
102 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
105 this.currentPHPString = 0;
106 // PHPParserSuperclass.fileToParse = fileToParse;
109 this.token = TokenNameEOF;
111 // this.rowCount = 1;
112 // this.columnCount = 0;
115 this.initializeScanner();
117 public void initializeScanner() {
118 this.scanner = new Scanner(false, false, false, false);
121 * Create marker for the parse error
123 // private void setMarker(String message, int charStart, int charEnd, int
125 // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
128 * This method will throw the SyntaxError. It will add the good lines and
129 * columns to the Error
133 * @throws SyntaxError
136 private void throwSyntaxError(String error) {
137 int problemStartPosition = scanner.getCurrentTokenStartPosition();
138 int problemEndPosition = scanner.getCurrentTokenEndPosition();
139 throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
142 * This method will throw the SyntaxError. It will add the good lines and
143 * columns to the Error
147 * @throws SyntaxError
150 // private void throwSyntaxError(String error, int startRow) {
151 // throw new SyntaxError(startRow, 0, " ", error);
153 private void throwSyntaxError(String error, int problemStartPosition,
154 int problemEndPosition) {
156 .phpParsingError(new String[]{error}, problemStartPosition,
157 problemEndPosition, referenceContext,
158 compilationUnit.compilationResult);
159 throw new SyntaxError(1, 0, " ", error);
161 private void reportSyntaxError(String error, int problemStartPosition,
162 int problemEndPosition) {
164 .phpParsingError(new String[]{error}, problemStartPosition,
165 problemEndPosition, referenceContext,
166 compilationUnit.compilationResult);
168 private void reportSyntaxWarning(String error, int problemStartPosition,
169 int problemEndPosition) {
170 problemReporter.phpParsingWarning(new String[]{error},
171 problemStartPosition, problemEndPosition, referenceContext,
172 compilationUnit.compilationResult);
175 * Method Declaration.
179 // private void getChar() {
180 // if (str.length() > chIndx) {
181 // ch = str.charAt(chIndx++);
186 // chIndx = str.length() + 1;
188 // // token = TokenNameEOF;
192 * gets the next token from input
194 private void getNextToken() {
196 token = scanner.getNextToken();
198 int currentEndPosition = scanner.getCurrentTokenEndPosition();
199 int currentStartPosition = scanner.getCurrentTokenStartPosition();
201 .print(currentStartPosition + "," + currentEndPosition + ": ");
202 System.out.println(scanner.toStringAction(token));
204 } catch (InvalidInputException e) {
205 token = TokenNameERROR;
209 public void init(String s) {
211 this.token = TokenNameEOF;
213 // this.rowCount = 1;
214 // this.columnCount = 0;
216 // this.phpMode = false;
217 /* scanner initialization */
218 scanner.setSource(s.toCharArray());
219 scanner.setPHPMode(false);
221 protected void initialize(boolean phpMode) {
222 compilationUnit = null;
223 referenceContext = null;
225 this.token = TokenNameEOF;
227 // this.rowCount = 1;
228 // this.columnCount = 0;
230 // this.phpMode = phpMode;
231 scanner.setPHPMode(phpMode);
234 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
237 public void parse(String s) {
242 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
245 protected void parse() {
249 if (token != TokenNameEOF && token != TokenNameERROR) {
252 if (token != TokenNameEOF) {
253 if (token == TokenNameERROR) {
254 throwSyntaxError("Scanner error (Found unknown token: "
255 + scanner.toStringAction(token) + ")");
257 if (token == TokenNameRPAREN) {
258 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
260 if (token == TokenNameRBRACE) {
261 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
263 if (token == TokenNameRBRACKET) {
264 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
266 if (token == TokenNameLPAREN) {
267 throwSyntaxError("Read character '('; end-of-file not reached.");
269 if (token == TokenNameLBRACE) {
270 throwSyntaxError("Read character '{'; end-of-file not reached.");
272 if (token == TokenNameLBRACKET) {
273 throwSyntaxError("Read character '['; end-of-file not reached.");
275 throwSyntaxError("End-of-file not reached.");
278 } catch (SyntaxError sytaxErr1) {
279 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
281 // setMarker(sytaxErr1.getMessage(),
282 // scanner.getCurrentTokenStartPosition(),
283 // scanner.getCurrentTokenEndPosition(), ERROR);
285 // if an error occured,
286 // try to find keywords 'class' or 'function'
287 // to parse the rest of the string
288 while (token != TokenNameEOF && token != TokenNameERROR) {
289 if (token == TokenNameabstract || token == TokenNamefinal
290 || token == TokenNameclass || token == TokenNamefunction) {
295 if (token == TokenNameEOF || token == TokenNameERROR) {
298 } catch (SyntaxError sytaxErr2) {
299 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
301 // setMarker(sytaxErr2.getMessage(),
302 // scanner.getCurrentTokenStartPosition(),
303 // scanner.getCurrentTokenEndPosition(), ERROR);
309 // public PHPOutlineInfo parseInfo(Object parent, String s) {
310 // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
311 // // Stack stack = new Stack();
312 // // stack.push(outlineInfo.getDeclarations());
314 // this.token = TokenNameEOF;
315 // // this.chIndx = 0;
316 // // this.rowCount = 1;
317 // // this.columnCount = 0;
318 // this.phpEnd = false;
319 // this.phpMode = false;
320 // scanner.setSource(s.toCharArray());
321 // scanner.setPHPMode(false);
324 // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
326 // return outlineInfo;
328 private boolean isVariable() {
329 return token == TokenNameVariable; // || token == TokenNamethis;
331 // private void parseDeclarations(PHPOutlineInfo outlineInfo,
332 // OutlineableWithChildren current, boolean goBack) {
334 // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
335 // PHPSegmentWithChildren temp;
337 // IPreferenceStore store =
338 // PHPeclipsePlugin.getDefault().getPreferenceStore();
340 // while (token != TokenNameEOF && token != TokenNameERROR) {
341 // if (token == TokenNameVariable) {
342 // ident = scanner.getCurrentIdentifierSource();
343 // outlineInfo.addVariable(new String(ident));
345 // } else if (token == TokenNamevar) {
347 // if (token == TokenNameVariable
348 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
349 // ident = scanner.getCurrentIdentifierSource();
350 // //substring(1) added because PHPVarDeclaration doesn't
351 // // need the $ anymore
352 // String variableName = new String(ident).substring(1);
353 // outlineInfo.addVariable(variableName);
355 // if (token != TokenNameSEMICOLON) {
357 // ident = scanner.getCurrentTokenSource();
358 // if (token > TokenNameKEYWORD) {
359 // current.add(new PHPVarDeclaration(current, variableName,
360 // // chIndx - ident.length,
361 // scanner.getCurrentTokenStartPosition(), new String(ident)));
364 // case TokenNameVariable :
365 // case TokenNamethis :
366 // current.add(new PHPVarDeclaration(current, variableName,
369 // scanner.getCurrentTokenStartPosition(), new String(
372 // case TokenNameIdentifier :
373 // current.add(new PHPVarDeclaration(current, variableName,
376 // scanner.getCurrentTokenStartPosition(), new String(
379 // case TokenNameDoubleLiteral :
380 // current.add(new PHPVarDeclaration(current, variableName
384 // scanner.getCurrentTokenStartPosition(), new String(
387 // case TokenNameIntegerLiteral :
388 // current.add(new PHPVarDeclaration(current, variableName,
391 // scanner.getCurrentTokenStartPosition(), new String(
394 // case TokenNameStringInterpolated :
395 // case TokenNameStringLiteral :
396 // current.add(new PHPVarDeclaration(current, variableName,
399 // scanner.getCurrentTokenStartPosition(), new String(
402 // case TokenNameStringConstant :
403 // current.add(new PHPVarDeclaration(current, variableName,
406 // scanner.getCurrentTokenStartPosition(), new String(
410 // current.add(new PHPVarDeclaration(current, variableName,
413 // scanner.getCurrentTokenStartPosition()));
418 // ident = scanner.getCurrentIdentifierSource();
419 // current.add(new PHPVarDeclaration(current, variableName,
420 // // chIndx - ident.length
421 // scanner.getCurrentTokenStartPosition()));
424 // } else if (token == TokenNamefunction) {
426 // if (token == TokenNameAND) {
429 // if (token == TokenNameIdentifier
430 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
431 // ident = scanner.getCurrentIdentifierSource();
432 // outlineInfo.addVariable(new String(ident));
433 // temp = new PHPFunctionDeclaration(current, new String(ident),
434 // // chIndx - ident.length
435 // scanner.getCurrentTokenStartPosition());
436 // current.add(temp);
438 // parseDeclarations(outlineInfo, temp, true);
440 // } else if (token == TokenNameclass) {
442 // if (token == TokenNameIdentifier
443 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
444 // ident = scanner.getCurrentIdentifierSource();
445 // outlineInfo.addVariable(new String(ident));
446 // temp = new PHPClassDeclaration(current, new String(ident),
447 // // chIndx - ident.len
448 // scanner.getCurrentTokenStartPosition());
449 // current.add(temp);
450 // // stack.push(temp);
452 // //skip tokens for classname, extends and others until
453 // // we have the opening '{'
454 // while (token != TokenNameLBRACE && token != TokenNameEOF
455 // && token != TokenNameERROR) {
458 // parseDeclarations(outlineInfo, temp, true);
461 // } else if ((token == TokenNameLBRACE)
462 // || (token == TokenNameDOLLAR_LBRACE)) {
465 // } else if (token == TokenNameRBRACE) {
468 // if (counter == 0 && goBack) {
471 // } else if (token == TokenNamerequire || token == TokenNamerequire_once
472 // || token == TokenNameinclude || token == TokenNameinclude_once) {
473 // ident = scanner.getCurrentTokenSource();
475 // int startPosition = scanner.getCurrentTokenStartPosition();
477 // char[] expr = scanner.getCurrentTokenSource(startPosition);
478 // outlineInfo.addVariable(new String(ident));
479 // current.add(new PHPReqIncDeclaration(current, new String(ident),
480 // // chIndx - ident.length,
481 // startPosition, new String(expr)));
487 // } catch (SyntaxError sytaxErr) {
489 // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
490 // // setMarker(sytaxErr.getMessage(),
491 // // scanner.getCurrentTokenStartPosition(),
492 // // scanner.getCurrentTokenEndPosition(), ERROR);
493 // // } catch (CoreException e) {
497 private void statementList() {
499 statement(TokenNameEOF);
500 if ((token == TokenNameRBRACE) || (token == TokenNamecase)
501 || (token == TokenNamedefault) || (token == TokenNameelse)
502 || (token == TokenNameelseif) || (token == TokenNameendif)
503 || (token == TokenNameendfor) || (token == TokenNameendforeach)
504 || (token == TokenNameendwhile) || (token == TokenNameendswitch)
505 || (token == TokenNameEOF) || (token == TokenNameERROR)) {
510 private void functionBody(MethodDeclaration methodDecl) {
511 // '{' [statement-list] '}'
512 if (token == TokenNameLBRACE) {
515 throwSyntaxError("'{' expected in compound-statement.");
517 if (token != TokenNameRBRACE) {
520 if (token == TokenNameRBRACE) {
521 methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
524 throwSyntaxError("'}' expected in compound-statement.");
527 private void statement(int previousToken) {
528 // if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
530 // char[] ident = scanner.getCurrentIdentifierSource();
531 // String keyword = new String(ident);
532 // if (token == TokenNameAT) {
534 // if (token != TokenNamerequire && token != TokenNamerequire_once
535 // && token != TokenNameinclude && token != TokenNameinclude_once
536 // && token != TokenNameIdentifier && token != TokenNameVariable
537 // && token != TokenNameStringInterpolated) {
538 // throwSyntaxError("identifier expected after '@'.");
541 // if (token == TokenNameinclude || token == TokenNameinclude_once) {
543 // if (token == TokenNameLPAREN) {
545 // if (token == TokenNameSEMICOLON) {
548 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
549 // throwSyntaxError("';' expected after 'include' or 'include_once'.");
551 // // getNextToken();
554 // concatenationExpression();
557 // } else if (token == TokenNamerequire || token == TokenNamerequire_once)
561 // if (token == TokenNameLPAREN) {
563 // if (token == TokenNameSEMICOLON) {
566 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
567 // throwSyntaxError("';' expected after 'require' or 'require_once'.");
569 // // getNextToken();
572 // concatenationExpression();
576 if (token == TokenNameif) {
578 if (token == TokenNameLPAREN) {
581 throwSyntaxError("'(' expected after 'if' keyword.");
584 if (token == TokenNameRPAREN) {
587 throwSyntaxError("')' expected after 'if' condition.");
591 } else if (token == TokenNameswitch) {
593 if (token == TokenNameLPAREN) {
596 throwSyntaxError("'(' expected after 'switch' keyword.");
599 if (token == TokenNameRPAREN) {
602 throwSyntaxError("')' expected after 'switch' condition.");
606 } else if (token == TokenNamefor) {
608 if (token == TokenNameLPAREN) {
611 throwSyntaxError("'(' expected after 'for' keyword.");
613 if (token == TokenNameSEMICOLON) {
617 if (token == TokenNameSEMICOLON) {
620 throwSyntaxError("';' expected after 'for'.");
623 if (token == TokenNameSEMICOLON) {
627 if (token == TokenNameSEMICOLON) {
630 throwSyntaxError("';' expected after 'for'.");
633 if (token == TokenNameRPAREN) {
637 if (token == TokenNameRPAREN) {
640 throwSyntaxError("')' expected after 'for'.");
645 } else if (token == TokenNamewhile) {
647 if (token == TokenNameLPAREN) {
650 throwSyntaxError("'(' expected after 'while' keyword.");
653 if (token == TokenNameRPAREN) {
656 throwSyntaxError("')' expected after 'while' condition.");
660 } else if (token == TokenNamedo) {
662 if (token == TokenNameLBRACE) {
664 if (token != TokenNameRBRACE) {
667 if (token == TokenNameRBRACE) {
670 throwSyntaxError("'}' expected after 'do' keyword.");
673 statement(TokenNameEOF);
675 if (token == TokenNamewhile) {
677 if (token == TokenNameLPAREN) {
680 throwSyntaxError("'(' expected after 'while' keyword.");
683 if (token == TokenNameRPAREN) {
686 throwSyntaxError("')' expected after 'while' condition.");
689 throwSyntaxError("'while' expected after 'do' keyword.");
691 if (token == TokenNameSEMICOLON) {
694 if (token != TokenNameINLINE_HTML) {
695 throwSyntaxError("';' expected after do-while statement.");
700 } else if (token == TokenNameforeach) {
702 if (token == TokenNameLPAREN) {
705 throwSyntaxError("'(' expected after 'foreach' keyword.");
708 if (token == TokenNameas) {
711 throwSyntaxError("'as' expected after 'foreach' exxpression.");
715 foreach_optional_arg();
716 if (token == TokenNameEQUAL_GREATER) {
720 if (token == TokenNameRPAREN) {
723 throwSyntaxError("')' expected after 'foreach' expression.");
727 } else if (token == TokenNamecontinue || token == TokenNamebreak
728 || token == TokenNamereturn) {
730 if (token != TokenNameSEMICOLON) {
733 if (token == TokenNameSEMICOLON) {
736 if (token != TokenNameINLINE_HTML) {
737 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
742 } else if (token == TokenNameecho) {
745 if (token == TokenNameSEMICOLON) {
748 if (token != TokenNameINLINE_HTML) {
749 throwSyntaxError("';' expected after 'echo' statement.");
754 } else if (token == TokenNameINLINE_HTML) {
757 // } else if (token == TokenNameprint) {
760 // if (token == TokenNameSEMICOLON) {
763 // if (token != TokenNameStopPHP) {
764 // throwSyntaxError("';' expected after 'print' statement.");
769 } else if (token == TokenNameglobal) {
772 if (token == TokenNameSEMICOLON) {
775 if (token != TokenNameINLINE_HTML) {
776 throwSyntaxError("';' expected after 'global' statement.");
781 } else if (token == TokenNamestatic) {
784 if (token == TokenNameSEMICOLON) {
787 if (token != TokenNameINLINE_HTML) {
788 throwSyntaxError("';' expected after 'static' statement.");
793 } else if (token == TokenNameunset) {
795 if (token == TokenNameLPAREN) {
798 throwSyntaxError("'(' expected after 'unset' statement.");
801 if (token == TokenNameRPAREN) {
804 throwSyntaxError("')' expected after 'unset' statement.");
806 if (token == TokenNameSEMICOLON) {
809 if (token != TokenNameINLINE_HTML) {
810 throwSyntaxError("';' expected after 'unset' statement.");
815 } else if (token == TokenNamefunction) {
816 MethodDeclaration methodDecl = new MethodDeclaration(
817 this.compilationUnit.compilationResult);
818 methodDecl.declarationSourceStart = scanner
819 .getCurrentTokenStartPosition();
821 functionDefinition(methodDecl);
823 } else if (token == TokenNametry) {
825 if (token != TokenNameLBRACE) {
826 throwSyntaxError("'{' expected in 'try' statement.");
830 if (token != TokenNameRBRACE) {
831 throwSyntaxError("'}' expected in 'try' statement.");
835 } else if (token == TokenNamecatch) {
837 if (token != TokenNameLPAREN) {
838 throwSyntaxError("'(' expected in 'catch' statement.");
841 fully_qualified_class_name();
842 if (token != TokenNameVariable) {
843 throwSyntaxError("Variable expected in 'catch' statement.");
846 if (token != TokenNameRPAREN) {
847 throwSyntaxError("')' expected in 'catch' statement.");
850 if (token != TokenNameLBRACE) {
851 throwSyntaxError("'{' expected in 'catch' statement.");
854 if (token != TokenNameRBRACE) {
856 if (token != TokenNameRBRACE) {
857 throwSyntaxError("'}' expected in 'catch' statement.");
861 additional_catches();
863 } else if (token == TokenNamethrow) {
866 if (token == TokenNameSEMICOLON) {
869 throwSyntaxError("';' expected after 'throw' exxpression.");
872 } else if (token == TokenNamefinal || token == TokenNameabstract
873 || token == TokenNameclass || token == TokenNameinterface) {
874 TypeDeclaration typeDecl = new TypeDeclaration(
875 this.compilationUnit.compilationResult);
876 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
877 // default super class
878 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
879 compilationUnit.types.add(typeDecl);
881 pushOnAstStack(typeDecl);
882 unticked_class_declaration_statement(typeDecl);
883 // classBody(typeDecl);
890 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
891 } else if (token == TokenNameLBRACE) {
893 if (token != TokenNameRBRACE) {
896 if (token == TokenNameRBRACE) {
900 throwSyntaxError("'}' expected.");
903 if (token != TokenNameSEMICOLON) {
906 if (token == TokenNameSEMICOLON) {
910 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
911 throwSyntaxError("';' expected after expression (Found token: "
912 + scanner.toStringAction(token) + ")");
918 private void additional_catches() {
919 while (token == TokenNamecatch) {
921 if (token != TokenNameLPAREN) {
922 throwSyntaxError("'(' expected in 'catch' statement.");
925 fully_qualified_class_name();
926 if (token != TokenNameVariable) {
927 throwSyntaxError("Variable expected in 'catch' statement.");
930 if (token != TokenNameRPAREN) {
931 throwSyntaxError("')' expected in 'catch' statement.");
934 if (token != TokenNameLBRACE) {
935 throwSyntaxError("'{' expected in 'catch' statement.");
939 if (token != TokenNameRBRACE) {
940 throwSyntaxError("'}' expected in 'catch' statement.");
945 private void foreach_variable() {
948 if (token == TokenNameAND) {
953 private void foreach_optional_arg() {
955 //| T_DOUBLE_ARROW foreach_variable
956 if (token == TokenNameEQUAL_GREATER) {
961 private void global_var_list() {
963 // global_var_list ',' global_var
967 if (token != TokenNameCOMMA) {
973 private void global_var() {
978 if (token == TokenNameVariable) {
980 } else if (token == TokenNameDOLLAR) {
982 if (token == TokenNameLPAREN) {
985 if (token != TokenNameLPAREN) {
986 throwSyntaxError("')' expected in global variable.");
994 private void static_var_list() {
996 // static_var_list ',' T_VARIABLE
997 //| static_var_list ',' T_VARIABLE '=' static_scalar
999 //| T_VARIABLE '=' static_scalar
1001 if (token == TokenNameVariable) {
1003 if (token == TokenNameEQUAL) {
1007 if (token != TokenNameCOMMA) {
1016 private void unset_variables() {
1019 // | unset_variables ',' unset_variable
1024 if (token != TokenNameCOMMA) {
1030 private final void initializeModifiers() {
1032 this.modifiersSourceStart = -1;
1034 private final void checkAndSetModifiers(int flag) {
1035 this.modifiers |= flag;
1036 if (this.modifiersSourceStart < 0)
1037 this.modifiersSourceStart = this.scanner.startPosition;
1039 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1040 initializeModifiers();
1041 if (token == TokenNameinterface) {
1042 // interface_entry T_STRING
1043 // interface_extends_list
1044 // '{' class_statement_list '}'
1045 checkAndSetModifiers(AccInterface);
1047 typeDecl.modifiers = this.modifiers;
1048 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1049 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1050 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1051 typeDecl.name = scanner.getCurrentIdentifierSource();
1052 if (token > TokenNameKEYWORD) {
1053 throwSyntaxError("Don't use a keyword for interface declaration ["
1054 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1055 typeDecl.sourceEnd);
1058 interface_extends_list();
1060 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1061 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1062 typeDecl.name = new char[]{' '};
1063 throwSyntaxError("Interface name expected after keyword 'interface'.",
1064 typeDecl.sourceStart, typeDecl.sourceEnd);
1068 // class_entry_type T_STRING extends_from
1070 // '{' class_statement_list'}'
1072 typeDecl.modifiers = this.modifiers;
1074 //identifier 'extends' identifier
1075 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1076 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1077 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1078 typeDecl.name = scanner.getCurrentIdentifierSource();
1079 if (token > TokenNameKEYWORD) {
1080 throwSyntaxError("Don't use a keyword for class declaration ["
1081 + scanner.toStringAction(token) + "].", typeDecl.sourceStart,
1082 typeDecl.sourceEnd);
1087 // | T_EXTENDS fully_qualified_class_name
1088 if (token == TokenNameextends) {
1089 interface_extends_list();
1091 // if (token != TokenNameIdentifier) {
1092 // throwSyntaxError("Class name expected after keyword 'extends'.",
1093 // scanner.getCurrentTokenStartPosition(), scanner
1094 // .getCurrentTokenEndPosition());
1099 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1100 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1101 typeDecl.name = new char[]{' '};
1102 throwSyntaxError("Class name expected after keyword 'class'.",
1103 typeDecl.sourceStart, typeDecl.sourceEnd);
1107 // '{' class_statement_list '}'
1108 if (token == TokenNameLBRACE) {
1110 if (token != TokenNameRBRACE) {
1111 class_statement_list();
1113 if (token == TokenNameRBRACE) {
1114 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1117 throwSyntaxError("'}' expected at end of class body.");
1120 throwSyntaxError("'{' expected at start of class body.");
1123 private void class_entry_type() {
1125 // | T_ABSTRACT T_CLASS
1126 // | T_FINAL T_CLASS
1127 if (token == TokenNameclass) {
1129 } else if (token == TokenNameabstract) {
1130 checkAndSetModifiers(AccAbstract);
1132 if (token != TokenNameclass) {
1133 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1136 } else if (token == TokenNamefinal) {
1137 checkAndSetModifiers(AccFinal);
1139 if (token != TokenNameclass) {
1140 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1144 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1147 private void interface_extends_list() {
1149 // | T_EXTENDS interface_list
1150 if (token == TokenNameextends) {
1155 private void implements_list() {
1157 // | T_IMPLEMENTS interface_list
1158 if (token == TokenNameimplements) {
1163 private void interface_list() {
1165 // fully_qualified_class_name
1166 //| interface_list ',' fully_qualified_class_name
1168 if (token == TokenNameIdentifier) {
1171 throwSyntaxError("Interface name expected after keyword 'implements'.");
1173 if (token != TokenNameCOMMA) {
1179 // private void classBody(TypeDeclaration typeDecl) {
1180 // //'{' [class-element-list] '}'
1181 // if (token == TokenNameLBRACE) {
1183 // if (token != TokenNameRBRACE) {
1184 // class_statement_list();
1186 // if (token == TokenNameRBRACE) {
1187 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1190 // throwSyntaxError("'}' expected at end of class body.");
1193 // throwSyntaxError("'{' expected at start of class body.");
1196 private void class_statement_list() {
1199 } while (token == TokenNamepublic || token == TokenNameprotected
1200 || token == TokenNameprivate || token == TokenNamestatic
1201 || token == TokenNameabstract || token == TokenNamefinal
1202 || token == TokenNamefunction || token == TokenNamevar
1203 || token == TokenNameconst);
1205 private void class_statement() {
1207 // variable_modifiers class_variable_declaration ';'
1208 // | class_constant_declaration ';'
1209 // | method_modifiers T_FUNCTION is_reference T_STRING
1210 // '(' parameter_list ')' method_body
1211 initializeModifiers();
1212 if (token == TokenNamevar) {
1213 checkAndSetModifiers(AccPublic);
1214 problemReporter.phpVarDeprecatedWarning(scanner
1215 .getCurrentTokenStartPosition(),
1216 scanner.getCurrentTokenEndPosition(), referenceContext,
1217 compilationUnit.compilationResult);
1219 class_variable_declaration();
1220 } else if (token == TokenNameconst) {
1221 class_constant_declaration();
1222 if (token != TokenNameSEMICOLON) {
1223 throwSyntaxError("';' expected after class const declaration.");
1227 boolean hasModifiers = member_modifiers();
1228 if (token == TokenNamefunction) {
1229 if (!hasModifiers) {
1230 checkAndSetModifiers(AccPublic);
1232 MethodDeclaration methodDecl = new MethodDeclaration(
1233 this.compilationUnit.compilationResult);
1234 methodDecl.declarationSourceStart = scanner
1235 .getCurrentTokenStartPosition();
1236 methodDecl.modifiers = this.modifiers;
1238 functionDefinition(methodDecl);
1240 if (!hasModifiers) {
1241 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1243 class_variable_declaration();
1246 // if (token == TokenNamefunction) {
1247 // MethodDeclaration methodDecl = new MethodDeclaration(
1248 // this.compilationUnit.compilationResult);
1249 // methodDecl.declarationSourceStart = scanner
1250 // .getCurrentTokenStartPosition();
1252 // functionDefinition(methodDecl);
1253 // } else if (token == TokenNamevar) {
1257 // throwSyntaxError("'function' or 'var' expected.");
1260 private void class_constant_declaration() {
1261 // class_constant_declaration ',' T_STRING '=' static_scalar
1262 // | T_CONST T_STRING '=' static_scalar
1263 if (token != TokenNameconst) {
1264 throwSyntaxError("'const' keyword expected in class declaration.");
1269 if (token != TokenNameIdentifier) {
1270 throwSyntaxError("Identifier expected in class const declaration.");
1273 if (token != TokenNameEQUAL) {
1274 throwSyntaxError("'=' expected in class const declaration.");
1278 if (token != TokenNameCOMMA) {
1279 break; // while(true)-loop
1284 // private void variable_modifiers() {
1285 // // variable_modifiers:
1286 // // non_empty_member_modifiers
1288 // initializeModifiers();
1289 // if (token == TokenNamevar) {
1290 // checkAndSetModifiers(AccPublic);
1291 // reportSyntaxError(
1292 // "Keyword 'var' is deprecated. Please use 'public' 'private' or 'protected'
1293 // modifier for field declarations.",
1294 // scanner.getCurrentTokenStartPosition(), scanner
1295 // .getCurrentTokenEndPosition());
1298 // if (!member_modifiers()) {
1299 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1300 // field declarations.");
1304 // private void method_modifiers() {
1305 // //method_modifiers:
1307 // //| non_empty_member_modifiers
1308 // initializeModifiers();
1309 // if (!member_modifiers()) {
1310 // checkAndSetModifiers(AccPublic);
1313 private boolean member_modifiers() {
1320 boolean foundToken = false;
1322 if (token == TokenNamepublic) {
1323 checkAndSetModifiers(AccPublic);
1326 } else if (token == TokenNameprotected) {
1327 checkAndSetModifiers(AccProtected);
1330 } else if (token == TokenNameprivate) {
1331 checkAndSetModifiers(AccPrivate);
1334 } else if (token == TokenNamestatic) {
1335 checkAndSetModifiers(AccStatic);
1338 } else if (token == TokenNameabstract) {
1339 checkAndSetModifiers(AccAbstract);
1342 } else if (token == TokenNamefinal) {
1343 checkAndSetModifiers(AccFinal);
1352 private void class_variable_declaration() {
1353 // class_variable_declaration:
1354 // class_variable_declaration ',' T_VARIABLE
1355 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1357 // | T_VARIABLE '=' static_scalar
1359 if (token == TokenNameVariable) {
1360 FieldDeclaration fieldDeclaration = new FieldDeclaration(null, scanner
1361 .getCurrentIdentifierSource(), scanner
1362 .getCurrentTokenStartPosition(), scanner
1363 .getCurrentTokenEndPosition());
1365 if (token == TokenNameEQUAL) {
1370 // if (token == TokenNamethis) {
1371 // throwSyntaxError("'$this' not allowed after keyword 'public'
1372 // 'protected' 'private' 'var'.");
1374 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1376 if (token != TokenNameCOMMA) {
1381 if (token != TokenNameSEMICOLON) {
1382 throwSyntaxError("';' expected after field declaration.");
1386 private void functionDefinition(MethodDeclaration methodDecl) {
1387 boolean isAbstract = false;
1389 compilationUnit.types.add(methodDecl);
1391 AstNode node = astStack[astPtr];
1392 if (node instanceof TypeDeclaration) {
1393 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1394 if (typeDecl.methods == null) {
1395 typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1397 AbstractMethodDeclaration[] newMethods;
1402 newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1403 1, typeDecl.methods.length);
1404 newMethods[0] = methodDecl;
1405 typeDecl.methods = newMethods;
1407 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1409 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1414 functionDeclarator(methodDecl);
1415 if (token == TokenNameSEMICOLON) {
1417 throwSyntaxError("Body declaration expected for method: "
1418 + new String(methodDecl.selector));
1423 functionBody(methodDecl);
1425 private void functionDeclarator(MethodDeclaration methodDecl) {
1426 //identifier '(' [parameter-list] ')'
1427 if (token == TokenNameAND) {
1430 if (token == TokenNameIdentifier) {
1431 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1432 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1433 methodDecl.selector = scanner.getCurrentIdentifierSource();
1435 if (token == TokenNameLPAREN) {
1438 throwSyntaxError("'(' expected in function declaration.");
1440 if (token != TokenNameRPAREN) {
1443 if (token != TokenNameRPAREN) {
1444 throwSyntaxError("')' expected in function declaration.");
1446 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1450 if (token > TokenNameKEYWORD) {
1451 throwSyntaxError("Don't use keyword for function declaration [" + token
1454 throwSyntaxError("Function name expected after keyword 'function'.");
1458 private void parameter_list() {
1459 // non_empty_parameter_list
1461 non_empty_parameter_list(true);
1463 private void non_empty_parameter_list(boolean empty_allowed) {
1464 // optional_class_type T_VARIABLE
1465 // | optional_class_type '&' T_VARIABLE
1466 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1467 // | optional_class_type T_VARIABLE '=' static_scalar
1468 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1469 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1470 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1472 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1474 if (token == TokenNameIdentifier || token == TokenNameVariable
1475 || token == TokenNameAND) {
1477 if (token == TokenNameIdentifier) {
1480 if (token == TokenNameAND) {
1483 if (token == TokenNameVariable) {
1485 if (token == TokenNameEQUAL) {
1490 throwSyntaxError("Variable expected in parameter list.");
1492 if (token != TokenNameCOMMA) {
1499 if (!empty_allowed) {
1500 throwSyntaxError("Identifier expected in parameter list.");
1503 private void optional_class_type() {
1507 private void parameterDeclaration() {
1509 //variable-reference
1510 if (token == TokenNameAND) {
1515 throwSyntaxError("Variable expected after reference operator '&'.");
1518 //variable '=' constant
1519 if (token == TokenNameVariable) {
1521 if (token == TokenNameEQUAL) {
1527 // if (token == TokenNamethis) {
1528 // throwSyntaxError("Reserved word '$this' not allowed in parameter
1532 private void labeledStatementList() {
1533 if (token != TokenNamecase && token != TokenNamedefault) {
1534 throwSyntaxError("'case' or 'default' expected.");
1537 if (token == TokenNamecase) {
1539 expr(); //constant();
1540 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1542 if (token == TokenNamecase || token == TokenNamedefault) {
1543 // empty case statement ?
1548 // else if (token == TokenNameSEMICOLON) {
1550 // "':' expected after 'case' keyword (Found token: " +
1551 // scanner.toStringAction(token) + ")",
1552 // scanner.getCurrentTokenStartPosition(),
1553 // scanner.getCurrentTokenEndPosition(),
1556 // if (token == TokenNamecase) { // empty case statement ?
1562 throwSyntaxError("':' character after 'case' constant expected (Found token: "
1563 + scanner.toStringAction(token) + ")");
1565 } else { // TokenNamedefault
1567 if (token == TokenNameCOLON) {
1569 if (token==TokenNameRBRACE) {
1570 // empty default case
1575 throwSyntaxError("':' character after 'default' expected.");
1578 } while (token == TokenNamecase || token == TokenNamedefault);
1580 // public void labeledStatement() {
1581 // if (token == TokenNamecase) {
1584 // if (token == TokenNameDDOT) {
1588 // throwSyntaxError("':' character after 'case' constant expected.");
1591 // } else if (token == TokenNamedefault) {
1593 // if (token == TokenNameDDOT) {
1597 // throwSyntaxError("':' character after 'default' expected.");
1602 // public void expressionStatement() {
1604 // private void inclusionStatement() {
1606 // public void compoundStatement() {
1608 // public void selectionStatement() {
1611 // public void iterationStatement() {
1614 // public void jumpStatement() {
1617 // public void outputStatement() {
1620 // public void scopeStatement() {
1623 // public void flowStatement() {
1626 // public void definitionStatement() {
1628 private void ifStatement() {
1629 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1630 if (token == TokenNameCOLON) {
1632 if (token != TokenNameendif) {
1635 case TokenNameelse :
1637 if (token == TokenNameCOLON) {
1639 if (token != TokenNameendif) {
1643 if (token == TokenNameif) { //'else if'
1645 elseifStatementList();
1647 throwSyntaxError("':' expected after 'else'.");
1651 case TokenNameelseif :
1653 elseifStatementList();
1657 if (token != TokenNameendif) {
1658 throwSyntaxError("'endif' expected.");
1661 if (token != TokenNameSEMICOLON) {
1662 throwSyntaxError("';' expected after if-statement.");
1666 // statement [else-statement]
1667 statement(TokenNameEOF);
1668 if (token == TokenNameelseif) {
1670 if (token == TokenNameLPAREN) {
1673 throwSyntaxError("'(' expected after 'elseif' keyword.");
1676 if (token == TokenNameRPAREN) {
1679 throwSyntaxError("')' expected after 'elseif' condition.");
1682 } else if (token == TokenNameelse) {
1684 statement(TokenNameEOF);
1688 private void elseifStatementList() {
1692 case TokenNameelse :
1694 if (token == TokenNameCOLON) {
1696 if (token != TokenNameendif) {
1701 if (token == TokenNameif) { //'else if'
1704 throwSyntaxError("':' expected after 'else'.");
1708 case TokenNameelseif :
1716 private void elseifStatement() {
1717 if (token == TokenNameLPAREN) {
1720 if (token != TokenNameRPAREN) {
1721 throwSyntaxError("')' expected in else-if-statement.");
1724 if (token != TokenNameCOLON) {
1725 throwSyntaxError("':' expected in else-if-statement.");
1728 if (token != TokenNameendif) {
1733 private void switchStatement() {
1734 if (token == TokenNameCOLON) {
1735 // ':' [labeled-statement-list] 'endswitch' ';'
1737 labeledStatementList();
1738 if (token != TokenNameendswitch) {
1739 throwSyntaxError("'endswitch' expected.");
1742 if (token != TokenNameSEMICOLON) {
1743 throwSyntaxError("';' expected after switch-statement.");
1747 // '{' [labeled-statement-list] '}'
1748 if (token != TokenNameLBRACE) {
1749 throwSyntaxError("'{' expected in switch statement.");
1752 if (token != TokenNameRBRACE) {
1753 labeledStatementList();
1755 if (token != TokenNameRBRACE) {
1756 throwSyntaxError("'}' expected in switch statement.");
1761 private void forStatement() {
1762 if (token == TokenNameCOLON) {
1765 if (token != TokenNameendfor) {
1766 throwSyntaxError("'endfor' expected.");
1769 if (token != TokenNameSEMICOLON) {
1770 throwSyntaxError("';' expected after for-statement.");
1774 statement(TokenNameEOF);
1777 private void whileStatement() {
1778 // ':' statement-list 'endwhile' ';'
1779 if (token == TokenNameCOLON) {
1782 if (token != TokenNameendwhile) {
1783 throwSyntaxError("'endwhile' expected.");
1786 if (token != TokenNameSEMICOLON) {
1787 throwSyntaxError("';' expected after while-statement.");
1791 statement(TokenNameEOF);
1794 private void foreachStatement() {
1795 if (token == TokenNameCOLON) {
1798 if (token != TokenNameendforeach) {
1799 throwSyntaxError("'endforeach' expected.");
1802 if (token != TokenNameSEMICOLON) {
1803 throwSyntaxError("';' expected after foreach-statement.");
1807 statement(TokenNameEOF);
1810 // private void exitStatus() {
1811 // if (token == TokenNameLPAREN) {
1814 // throwSyntaxError("'(' expected in 'exit-status'.");
1816 // if (token != TokenNameRPAREN) {
1819 // if (token == TokenNameRPAREN) {
1822 // throwSyntaxError("')' expected after 'exit-status'.");
1825 private void expressionList() {
1828 if (token == TokenNameCOMMA) {
1835 private void expr() {
1837 // | expr_without_variable
1838 // if (token!=TokenNameEOF) {
1839 if (Scanner.TRACE) {
1840 System.out.println("TRACE: expr()");
1842 expr_without_variable(true);
1845 private void expr_without_variable(boolean only_variable) {
1846 // internal_functions_in_yacc
1855 // | T_INC rw_variable
1856 // | T_DEC rw_variable
1857 // | T_INT_CAST expr
1858 // | T_DOUBLE_CAST expr
1859 // | T_STRING_CAST expr
1860 // | T_ARRAY_CAST expr
1861 // | T_OBJECT_CAST expr
1862 // | T_BOOL_CAST expr
1863 // | T_UNSET_CAST expr
1864 // | T_EXIT exit_expr
1866 // | T_ARRAY '(' array_pair_list ')'
1867 // | '`' encaps_list '`'
1868 // | T_LIST '(' assignment_list ')' '=' expr
1869 // | T_NEW class_name_reference ctor_arguments
1870 // | variable '=' expr
1871 // | variable '=' '&' variable
1872 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
1873 // | variable T_PLUS_EQUAL expr
1874 // | variable T_MINUS_EQUAL expr
1875 // | variable T_MUL_EQUAL expr
1876 // | variable T_DIV_EQUAL expr
1877 // | variable T_CONCAT_EQUAL expr
1878 // | variable T_MOD_EQUAL expr
1879 // | variable T_AND_EQUAL expr
1880 // | variable T_OR_EQUAL expr
1881 // | variable T_XOR_EQUAL expr
1882 // | variable T_SL_EQUAL expr
1883 // | variable T_SR_EQUAL expr
1884 // | rw_variable T_INC
1885 // | rw_variable T_DEC
1886 // | expr T_BOOLEAN_OR expr
1887 // | expr T_BOOLEAN_AND expr
1888 // | expr T_LOGICAL_OR expr
1889 // | expr T_LOGICAL_AND expr
1890 // | expr T_LOGICAL_XOR expr
1902 // | expr T_IS_IDENTICAL expr
1903 // | expr T_IS_NOT_IDENTICAL expr
1904 // | expr T_IS_EQUAL expr
1905 // | expr T_IS_NOT_EQUAL expr
1907 // | expr T_IS_SMALLER_OR_EQUAL expr
1909 // | expr T_IS_GREATER_OR_EQUAL expr
1910 // | expr T_INSTANCEOF class_name_reference
1911 // | expr '?' expr ':' expr
1912 if (Scanner.TRACE) {
1913 System.out.println("TRACE: expr_without_variable() PART 1");
1916 case TokenNameisset :
1917 case TokenNameempty :
1918 case TokenNameeval :
1919 case TokenNameinclude :
1920 case TokenNameinclude_once :
1921 case TokenNamerequire :
1922 case TokenNamerequire_once :
1923 internal_functions_in_yacc();
1926 case TokenNameLPAREN :
1929 if (token == TokenNameRPAREN) {
1932 throwSyntaxError("')' expected in expression.");
1942 // | T_INT_CAST expr
1943 // | T_DOUBLE_CAST expr
1944 // | T_STRING_CAST expr
1945 // | T_ARRAY_CAST expr
1946 // | T_OBJECT_CAST expr
1947 // | T_BOOL_CAST expr
1948 // | T_UNSET_CAST expr
1949 case TokenNameclone :
1950 case TokenNameprint :
1952 case TokenNamePLUS :
1953 case TokenNameMINUS :
1955 case TokenNameTWIDDLE :
1956 case TokenNameintCAST :
1957 case TokenNamedoubleCAST :
1958 case TokenNamestringCAST :
1959 case TokenNamearrayCAST :
1960 case TokenNameobjectCAST :
1961 case TokenNameboolCAST :
1962 case TokenNameunsetCAST :
1966 case TokenNameexit :
1972 //| T_STRING_VARNAME
1974 //| T_START_HEREDOC encaps_list T_END_HEREDOC
1975 // | '`' encaps_list '`'
1977 // | '`' encaps_list '`'
1978 case TokenNameEncapsedString0 :
1979 scanner.encapsedStringStack.push(new Character('`'));
1982 if (token == TokenNameEncapsedString0) {
1985 if (token != TokenNameEncapsedString0) {
1986 throwSyntaxError("\'`\' expected at end of string"
1987 + "(Found token: " + scanner.toStringAction(token) + " )");
1991 scanner.encapsedStringStack.pop();
1995 // | '\'' encaps_list '\''
1996 case TokenNameEncapsedString1 :
1997 scanner.encapsedStringStack.push(new Character('\''));
2000 if (token == TokenNameEncapsedString1) {
2003 if (token != TokenNameEncapsedString1) {
2004 throwSyntaxError("\'\'\' expected at end of string"
2005 + "(Found token: " + scanner.toStringAction(token) + " )");
2009 scanner.encapsedStringStack.pop();
2013 //| '"' encaps_list '"'
2014 case TokenNameEncapsedString2 :
2015 scanner.encapsedStringStack.push(new Character('"'));
2018 if (token == TokenNameEncapsedString2) {
2021 if (token != TokenNameEncapsedString2) {
2022 throwSyntaxError("'\"' expected at end of string"
2023 + "(Found token: " + scanner.toStringAction(token) + " )");
2027 scanner.encapsedStringStack.pop();
2031 case TokenNameIntegerLiteral :
2032 case TokenNameDoubleLiteral :
2033 case TokenNameStringLiteral :
2034 case TokenNameStringConstant :
2035 case TokenNameStringInterpolated :
2036 case TokenNameFILE :
2037 case TokenNameLINE :
2038 case TokenNameCLASS_C :
2039 case TokenNameMETHOD_C :
2040 case TokenNameFUNC_C :
2043 case TokenNameHEREDOC :
2046 case TokenNamearray :
2047 // T_ARRAY '(' array_pair_list ')'
2049 if (token == TokenNameLPAREN) {
2051 if (token == TokenNameRPAREN) {
2056 if (token != TokenNameRPAREN) {
2057 throwSyntaxError("')' expected after keyword 'array'"
2058 + "(Found token: " + scanner.toStringAction(token) + ")");
2062 throwSyntaxError("'(' expected after keyword 'array'"
2063 + "(Found token: " + scanner.toStringAction(token) + ")");
2066 case TokenNamelist :
2067 // | T_LIST '(' assignment_list ')' '=' expr
2069 if (token == TokenNameLPAREN) {
2072 if (token != TokenNameRPAREN) {
2073 throwSyntaxError("')' expected after 'list' keyword.");
2076 if (token != TokenNameEQUAL) {
2077 throwSyntaxError("'=' expected after 'list' keyword.");
2082 throwSyntaxError("'(' expected after 'list' keyword.");
2086 // | T_NEW class_name_reference ctor_arguments
2088 class_name_reference();
2091 // | T_INC rw_variable
2092 // | T_DEC rw_variable
2093 case TokenNamePLUS_PLUS :
2094 case TokenNameMINUS_MINUS :
2098 // | variable '=' expr
2099 // | variable '=' '&' variable
2100 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2101 // | variable T_PLUS_EQUAL expr
2102 // | variable T_MINUS_EQUAL expr
2103 // | variable T_MUL_EQUAL expr
2104 // | variable T_DIV_EQUAL expr
2105 // | variable T_CONCAT_EQUAL expr
2106 // | variable T_MOD_EQUAL expr
2107 // | variable T_AND_EQUAL expr
2108 // | variable T_OR_EQUAL expr
2109 // | variable T_XOR_EQUAL expr
2110 // | variable T_SL_EQUAL expr
2111 // | variable T_SR_EQUAL expr
2112 // | rw_variable T_INC
2113 // | rw_variable T_DEC
2114 case TokenNameIdentifier :
2115 case TokenNameVariable :
2116 case TokenNameDOLLAR :
2119 case TokenNameEQUAL :
2121 if (token == TokenNameAND) {
2123 if (token == TokenNamenew) {
2124 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2126 class_name_reference();
2135 case TokenNamePLUS_EQUAL :
2136 case TokenNameMINUS_EQUAL :
2137 case TokenNameMULTIPLY_EQUAL :
2138 case TokenNameDIVIDE_EQUAL :
2139 case TokenNameDOT_EQUAL :
2140 case TokenNameREMAINDER_EQUAL :
2141 case TokenNameAND_EQUAL :
2142 case TokenNameOR_EQUAL :
2143 case TokenNameXOR_EQUAL :
2144 case TokenNameRIGHT_SHIFT_EQUAL :
2145 case TokenNameLEFT_SHIFT_EQUAL :
2149 case TokenNamePLUS_PLUS :
2150 case TokenNameMINUS_MINUS :
2154 if (!only_variable) {
2155 throwSyntaxError("Variable expression not allowed (found token '"
2156 + scanner.toStringAction(token) + "').");
2161 if (token != TokenNameINLINE_HTML) {
2162 throwSyntaxError("Error in expression (found token '"
2163 + scanner.toStringAction(token) + "').");
2167 if (Scanner.TRACE) {
2168 System.out.println("TRACE: expr_without_variable() PART 2");
2170 // | expr T_BOOLEAN_OR expr
2171 // | expr T_BOOLEAN_AND expr
2172 // | expr T_LOGICAL_OR expr
2173 // | expr T_LOGICAL_AND expr
2174 // | expr T_LOGICAL_XOR expr
2186 // | expr T_IS_IDENTICAL expr
2187 // | expr T_IS_NOT_IDENTICAL expr
2188 // | expr T_IS_EQUAL expr
2189 // | expr T_IS_NOT_EQUAL expr
2191 // | expr T_IS_SMALLER_OR_EQUAL expr
2193 // | expr T_IS_GREATER_OR_EQUAL expr
2196 case TokenNameOR_OR :
2197 case TokenNameAND_AND :
2205 case TokenNamePLUS :
2206 case TokenNameMINUS :
2207 case TokenNameMULTIPLY :
2208 case TokenNameDIVIDE :
2209 case TokenNameREMAINDER :
2210 case TokenNameLEFT_SHIFT :
2211 case TokenNameRIGHT_SHIFT :
2212 case TokenNameEQUAL_EQUAL_EQUAL :
2213 case TokenNameNOT_EQUAL_EQUAL :
2214 case TokenNameEQUAL_EQUAL :
2215 case TokenNameNOT_EQUAL :
2216 case TokenNameLESS :
2217 case TokenNameLESS_EQUAL :
2218 case TokenNameGREATER :
2219 case TokenNameGREATER_EQUAL :
2223 // | expr T_INSTANCEOF class_name_reference
2224 // | expr '?' expr ':' expr
2225 case TokenNameinstanceof :
2227 class_name_reference();
2229 case TokenNameQUESTION :
2232 if (token == TokenNameCOLON) {
2242 private void class_name_reference() {
2243 // class_name_reference:
2245 //| dynamic_class_name_reference
2246 if (Scanner.TRACE) {
2247 System.out.println("TRACE: class_name_reference()");
2249 if (token == TokenNameIdentifier) {
2252 dynamic_class_name_reference();
2255 private void dynamic_class_name_reference() {
2256 //dynamic_class_name_reference:
2257 // base_variable T_OBJECT_OPERATOR object_property
2258 // dynamic_class_name_variable_properties
2260 if (Scanner.TRACE) {
2261 System.out.println("TRACE: dynamic_class_name_reference()");
2264 if (token == TokenNameMINUS_GREATER) {
2267 dynamic_class_name_variable_properties();
2270 private void dynamic_class_name_variable_properties() {
2271 // dynamic_class_name_variable_properties:
2272 // dynamic_class_name_variable_properties
2273 // dynamic_class_name_variable_property
2275 if (Scanner.TRACE) {
2276 System.out.println("TRACE: dynamic_class_name_variable_properties()");
2278 while (token == TokenNameMINUS_GREATER) {
2279 dynamic_class_name_variable_property();
2282 private void dynamic_class_name_variable_property() {
2283 // dynamic_class_name_variable_property:
2284 // T_OBJECT_OPERATOR object_property
2285 if (Scanner.TRACE) {
2286 System.out.println("TRACE: dynamic_class_name_variable_property()");
2288 if (token == TokenNameMINUS_GREATER) {
2293 private void ctor_arguments() {
2296 //| '(' function_call_parameter_list ')'
2297 if (token == TokenNameLPAREN) {
2299 if (token == TokenNameRPAREN) {
2303 non_empty_function_call_parameter_list();
2304 if (token != TokenNameRPAREN) {
2305 throwSyntaxError("')' expected in ctor_arguments.");
2310 private void assignment_list() {
2312 // assignment_list ',' assignment_list_element
2313 //| assignment_list_element
2315 assignment_list_element();
2316 if (token != TokenNameCOMMA) {
2322 private void assignment_list_element() {
2323 //assignment_list_element:
2325 //| T_LIST '(' assignment_list ')'
2327 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2330 if (token == TokenNamelist) {
2332 if (token == TokenNameLPAREN) {
2335 if (token != TokenNameRPAREN) {
2336 throwSyntaxError("')' expected after 'list' keyword.");
2340 throwSyntaxError("'(' expected after 'list' keyword.");
2345 private void array_pair_list() {
2348 //| non_empty_array_pair_list possible_comma
2349 non_empty_array_pair_list();
2350 if (token == TokenNameCOMMA) {
2354 private void non_empty_array_pair_list() {
2355 //non_empty_array_pair_list:
2356 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2357 //| non_empty_array_pair_list ',' expr
2358 //| expr T_DOUBLE_ARROW expr
2360 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2361 //| non_empty_array_pair_list ',' '&' w_variable
2362 //| expr T_DOUBLE_ARROW '&' w_variable
2365 if (token == TokenNameAND) {
2370 if (token == TokenNameAND) {
2373 } else if (token == TokenNameEQUAL_GREATER) {
2375 if (token == TokenNameAND) {
2383 if (token != TokenNameCOMMA) {
2387 if (token == TokenNameRPAREN) {
2392 // private void variableList() {
2395 // if (token == TokenNameCOMMA) {
2402 private void variable_without_objects() {
2403 // variable_without_objects:
2404 // reference_variable
2405 // | simple_indirect_reference reference_variable
2406 if (Scanner.TRACE) {
2407 System.out.println("TRACE: variable_without_objects()");
2409 while (token == TokenNameDOLLAR) {
2412 reference_variable();
2414 private void function_call() {
2416 // T_STRING '(' function_call_parameter_list ')'
2417 //| class_constant '(' function_call_parameter_list ')'
2418 //| static_member '(' function_call_parameter_list ')'
2419 //| variable_without_objects '(' function_call_parameter_list ')'
2420 if (Scanner.TRACE) {
2421 System.out.println("TRACE: function_call()");
2423 if (token == TokenNameIdentifier) {
2426 case TokenNamePAAMAYIM_NEKUDOTAYIM :
2429 if (token == TokenNameIdentifier) {
2434 variable_without_objects();
2439 variable_without_objects();
2441 if (token != TokenNameLPAREN) {
2442 // TODO is this ok ?
2444 // throwSyntaxError("'(' expected in function call.");
2447 if (token == TokenNameRPAREN) {
2451 non_empty_function_call_parameter_list();
2452 if (token != TokenNameRPAREN) {
2453 throwSyntaxError("')' expected in function call.");
2457 // private void function_call_parameter_list() {
2458 // function_call_parameter_list:
2459 // non_empty_function_call_parameter_list { $$ = $1; }
2462 private void non_empty_function_call_parameter_list() {
2463 //non_empty_function_call_parameter_list:
2464 // expr_without_variable
2467 // | non_empty_function_call_parameter_list ',' expr_without_variable
2468 // | non_empty_function_call_parameter_list ',' variable
2469 // | non_empty_function_call_parameter_list ',' '&' w_variable
2470 if (Scanner.TRACE) {
2471 System.out.println("TRACE: non_empty_function_call_parameter_list()");
2474 if (token == TokenNameAND) {
2478 // if (token == TokenNameIdentifier || token == TokenNameVariable
2479 // || token == TokenNameDOLLAR) {
2482 expr_without_variable(true);
2485 if (token != TokenNameCOMMA) {
2491 private void fully_qualified_class_name() {
2492 if (token == TokenNameIdentifier) {
2495 throwSyntaxError("Class name expected.");
2498 private void static_member() {
2500 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2501 // variable_without_objects
2502 if (Scanner.TRACE) {
2503 System.out.println("TRACE: static_member()");
2505 fully_qualified_class_name();
2506 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2507 throwSyntaxError("'::' expected after class name (static_member).");
2510 variable_without_objects();
2512 private void base_variable_with_function_calls() {
2513 // base_variable_with_function_calls:
2516 boolean functionCall = false;
2517 if (Scanner.TRACE) {
2518 System.out.println("TRACE: base_variable_with_function_calls()");
2520 // if (token == TokenNameIdentifier) {
2521 // functionCall = true;
2522 // } else if (token == TokenNameVariable) {
2523 // int tempToken = token;
2524 // int tempPosition = scanner.currentPosition;
2526 // if (token == TokenNameLPAREN) {
2527 // functionCall = true;
2529 // token = tempToken;
2530 // scanner.currentPosition = tempPosition;
2531 // scanner.phpMode = true;
2533 // if (functionCall) {
2539 private void base_variable() {
2541 // reference_variable
2542 // | simple_indirect_reference reference_variable
2544 if (Scanner.TRACE) {
2545 System.out.println("TRACE: base_variable()");
2547 if (token == TokenNameIdentifier) {
2550 while (token == TokenNameDOLLAR) {
2553 reference_variable();
2556 // private void simple_indirect_reference() {
2557 // // simple_indirect_reference:
2559 // //| simple_indirect_reference '$'
2561 private void reference_variable() {
2562 // reference_variable:
2563 // reference_variable '[' dim_offset ']'
2564 // | reference_variable '{' expr '}'
2565 // | compound_variable
2566 if (Scanner.TRACE) {
2567 System.out.println("TRACE: reference_variable()");
2569 compound_variable();
2571 if (token == TokenNameLBRACE) {
2574 if (token != TokenNameRBRACE) {
2575 throwSyntaxError("'}' expected in reference variable.");
2578 } else if (token == TokenNameLBRACKET) {
2580 if (token != TokenNameRBRACKET) {
2583 if (token != TokenNameRBRACKET) {
2584 throwSyntaxError("']' expected in reference variable.");
2593 private void compound_variable() {
2594 // compound_variable:
2596 // | '$' '{' expr '}'
2597 if (Scanner.TRACE) {
2598 System.out.println("TRACE: compound_variable()");
2600 if (token == TokenNameVariable) {
2603 // because of simple_indirect_reference
2604 while (token == TokenNameDOLLAR) {
2607 if (token != TokenNameLBRACE) {
2608 throwSyntaxError("'{' expected after compound variable token '$'.");
2612 if (token != TokenNameRBRACE) {
2613 throwSyntaxError("'}' expected after compound variable token '$'.");
2618 // private void dim_offset() {
2624 private void object_property() {
2627 //| variable_without_objects
2628 if (Scanner.TRACE) {
2629 System.out.println("TRACE: object_property()");
2631 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2632 variable_without_objects();
2637 private void object_dim_list() {
2639 // object_dim_list '[' dim_offset ']'
2640 //| object_dim_list '{' expr '}'
2642 if (Scanner.TRACE) {
2643 System.out.println("TRACE: object_dim_list()");
2647 if (token == TokenNameLBRACE) {
2650 if (token != TokenNameRBRACE) {
2651 throwSyntaxError("'}' expected in object_dim_list.");
2654 } else if (token == TokenNameLBRACKET) {
2656 if (token == TokenNameRBRACKET) {
2661 if (token != TokenNameRBRACKET) {
2662 throwSyntaxError("']' expected in object_dim_list.");
2670 private void variable_name() {
2674 if (Scanner.TRACE) {
2675 System.out.println("TRACE: variable_name()");
2677 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
2678 if (token > TokenNameKEYWORD) {
2679 // TODO show a warning "Keyword used as variable" ?
2683 if (token != TokenNameLBRACE) {
2684 throwSyntaxError("'{' expected in variable name.");
2688 if (token != TokenNameRBRACE) {
2689 throwSyntaxError("'}' expected in variable name.");
2694 private void r_variable() {
2697 private void w_variable() {
2700 private void rw_variable() {
2703 private void variable() {
2705 // base_variable_with_function_calls T_OBJECT_OPERATOR
2706 // object_property method_or_not variable_properties
2707 // | base_variable_with_function_calls
2708 base_variable_with_function_calls();
2709 if (token == TokenNameMINUS_GREATER) {
2713 variable_properties();
2715 // if (token == TokenNameDOLLAR_LBRACE) {
2719 // if (token != TokenNameRBRACE) {
2720 // throwSyntaxError("'}' expected after indirect variable token '${'.");
2724 // if (token == TokenNameVariable) {
2726 // if (token == TokenNameLBRACKET) {
2729 // if (token != TokenNameRBRACKET) {
2730 // throwSyntaxError("']' expected in variable-list.");
2733 // } else if (token == TokenNameEQUAL) {
2738 // throwSyntaxError("$-variable expected in variable-list.");
2742 private void variable_properties() {
2743 // variable_properties:
2744 // variable_properties variable_property
2746 while (token == TokenNameMINUS_GREATER) {
2747 variable_property();
2750 private void variable_property() {
2751 // variable_property:
2752 // T_OBJECT_OPERATOR object_property method_or_not
2753 if (Scanner.TRACE) {
2754 System.out.println("TRACE: variable_property()");
2756 if (token == TokenNameMINUS_GREATER) {
2761 throwSyntaxError("'->' expected in variable_property.");
2764 private void method_or_not() {
2766 // '(' function_call_parameter_list ')'
2768 if (Scanner.TRACE) {
2769 System.out.println("TRACE: method_or_not()");
2771 if (token == TokenNameLPAREN) {
2773 if (token == TokenNameRPAREN) {
2777 non_empty_function_call_parameter_list();
2778 if (token != TokenNameRPAREN) {
2779 throwSyntaxError("')' expected in method_or_not.");
2784 private void exit_expr() {
2788 if (token != TokenNameLPAREN) {
2792 if (token == TokenNameRPAREN) {
2797 if (token != TokenNameRPAREN) {
2798 throwSyntaxError("')' expected after keyword 'exit'");
2802 private void encaps_list() {
2803 // encaps_list encaps_var
2804 // | encaps_list T_STRING
2805 // | encaps_list T_NUM_STRING
2806 // | encaps_list T_ENCAPSED_AND_WHITESPACE
2807 // | encaps_list T_CHARACTER
2808 // | encaps_list T_BAD_CHARACTER
2809 // | encaps_list '['
2810 // | encaps_list ']'
2811 // | encaps_list '{'
2812 // | encaps_list '}'
2813 // | encaps_list T_OBJECT_OPERATOR
2817 case TokenNameSTRING :
2820 case TokenNameLBRACE :
2821 // scanner.encapsedStringStack.pop();
2824 case TokenNameRBRACE :
2825 // scanner.encapsedStringStack.pop();
2828 case TokenNameLBRACKET :
2829 // scanner.encapsedStringStack.pop();
2832 case TokenNameRBRACKET :
2833 // scanner.encapsedStringStack.pop();
2836 case TokenNameMINUS_GREATER :
2837 // scanner.encapsedStringStack.pop();
2840 case TokenNameVariable :
2841 case TokenNameDOLLAR_LBRACE :
2842 case TokenNameCURLY_OPEN :
2845 // case TokenNameDOLLAR :
2847 // if (token == TokenNameLBRACE) {
2848 // token = TokenNameDOLLAR_LBRACE;
2853 char encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2855 if (encapsedChar == '$') {
2856 scanner.encapsedStringStack.pop();
2857 encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2859 switch (encapsedChar) {
2861 if (token == TokenNameEncapsedString0) {
2864 token = TokenNameSTRING;
2867 if (token == TokenNameEncapsedString1) {
2870 token = TokenNameSTRING;
2873 if (token == TokenNameEncapsedString2) {
2876 token = TokenNameSTRING;
2884 private void encaps_var() {
2886 // | T_VARIABLE '[' encaps_var_offset ']'
2887 // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
2888 // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
2889 // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
2890 // | T_CURLY_OPEN variable '}'
2892 case TokenNameVariable :
2894 if (token == TokenNameLBRACKET) {
2896 // if (token == TokenNameRBRACKET) {
2899 expr(); //encaps_var_offset();
2900 if (token != TokenNameRBRACKET) {
2901 throwSyntaxError("']' expected after variable.");
2903 // scanner.encapsedStringStack.pop();
2906 } else if (token == TokenNameMINUS_GREATER) {
2908 if (token != TokenNameIdentifier) {
2909 throwSyntaxError("Identifier expected after '->'.");
2911 // scanner.encapsedStringStack.pop();
2915 // // scanner.encapsedStringStack.pop();
2916 // int tempToken = TokenNameSTRING;
2917 // if (!scanner.encapsedStringStack.isEmpty()
2918 // && (token == TokenNameEncapsedString0
2919 // || token == TokenNameEncapsedString1
2920 // || token == TokenNameEncapsedString2 || token == TokenNameERROR)) {
2921 // char encapsedChar = ((Character) scanner.encapsedStringStack.peek())
2924 // case TokenNameEncapsedString0 :
2925 // if (encapsedChar == '`') {
2926 // tempToken = TokenNameEncapsedString0;
2929 // case TokenNameEncapsedString1 :
2930 // if (encapsedChar == '\'') {
2931 // tempToken = TokenNameEncapsedString1;
2934 // case TokenNameEncapsedString2 :
2935 // if (encapsedChar == '"') {
2936 // tempToken = TokenNameEncapsedString2;
2939 // case TokenNameERROR :
2940 // if (scanner.source[scanner.currentPosition - 1] == '\\') {
2941 // scanner.currentPosition--;
2947 // token = tempToken;
2950 case TokenNameDOLLAR_LBRACE :
2952 if (token == TokenNameIdentifier) {
2954 if (token == TokenNameLBRACKET) {
2956 // if (token == TokenNameRBRACKET) {
2960 if (token != TokenNameRBRACKET) {
2961 throwSyntaxError("']' expected after '${'.");
2966 if (token != TokenNameRBRACE) {
2967 throwSyntaxError("'}' expected after '${'.");
2969 // scanner.encapsedStringStack.pop();
2973 if (token != TokenNameRBRACE) {
2974 throwSyntaxError("'}' expected.");
2976 // scanner.encapsedStringStack.pop();
2980 case TokenNameCURLY_OPEN :
2982 if (token == TokenNameIdentifier) {
2984 if (token == TokenNameLBRACKET) {
2986 // if (token == TokenNameRBRACKET) {
2990 if (token != TokenNameRBRACKET) {
2991 throwSyntaxError("']' expected after '{$'.");
2995 } else if (token == TokenNameMINUS_GREATER) {
2997 if (token != TokenNameIdentifier) {
2998 throwSyntaxError("String token expected.");
3002 // if (token != TokenNameRBRACE) {
3003 // throwSyntaxError("'}' expected after '{$'.");
3005 // // scanner.encapsedStringStack.pop();
3009 if (token != TokenNameRBRACE) {
3010 throwSyntaxError("'}' expected.");
3012 // scanner.encapsedStringStack.pop();
3018 private void encaps_var_offset() {
3023 case TokenNameSTRING :
3026 case TokenNameIntegerLiteral :
3029 case TokenNameVariable :
3032 case TokenNameIdentifier :
3036 throwSyntaxError("Variable or String token expected.");
3040 private void internal_functions_in_yacc() {
3042 case TokenNameisset :
3043 // T_ISSET '(' isset_variables ')'
3045 if (token != TokenNameLPAREN) {
3046 throwSyntaxError("'(' expected after keyword 'isset'");
3050 if (token != TokenNameRPAREN) {
3051 throwSyntaxError("')' expected after keyword 'isset'");
3055 case TokenNameempty :
3056 // T_EMPTY '(' variable ')'
3058 if (token != TokenNameLPAREN) {
3059 throwSyntaxError("'(' expected after keyword 'empty'");
3063 if (token != TokenNameRPAREN) {
3064 throwSyntaxError("')' expected after keyword 'empty'");
3068 case TokenNameinclude :
3073 case TokenNameinclude_once :
3074 // T_INCLUDE_ONCE expr
3078 case TokenNameeval :
3079 // T_EVAL '(' expr ')'
3081 if (token != TokenNameLPAREN) {
3082 throwSyntaxError("'(' expected after keyword 'eval'");
3086 if (token != TokenNameRPAREN) {
3087 throwSyntaxError("')' expected after keyword 'eval'");
3091 case TokenNamerequire :
3096 case TokenNamerequire_once :
3097 // T_REQUIRE_ONCE expr
3103 private void isset_variables() {
3105 // | isset_variables ','
3106 if (token == TokenNameRPAREN) {
3107 throwSyntaxError("Variable expected after keyword 'isset'");
3111 if (token == TokenNameCOMMA) {
3118 private boolean common_scalar() {
3122 // | T_CONSTANT_ENCAPSED_STRING
3129 case TokenNameIntegerLiteral :
3132 case TokenNameDoubleLiteral :
3135 case TokenNameStringLiteral :
3138 case TokenNameStringConstant :
3141 case TokenNameStringInterpolated :
3144 case TokenNameFILE :
3147 case TokenNameLINE :
3150 case TokenNameCLASS_C :
3153 case TokenNameMETHOD_C :
3156 case TokenNameFUNC_C :
3162 private void scalar() {
3165 //| T_STRING_VARNAME
3168 //| '"' encaps_list '"'
3169 //| '\'' encaps_list '\''
3170 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3171 throwSyntaxError("Not yet implemented (scalar).");
3173 private void static_scalar() {
3174 // static_scalar: /* compile-time evaluated scalars */
3177 // | '+' static_scalar
3178 // | '-' static_scalar
3179 // | T_ARRAY '(' static_array_pair_list ')'
3180 // | static_class_constant
3181 if (common_scalar()) {
3185 case TokenNameIdentifier :
3187 // static_class_constant:
3188 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3189 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3191 if (token == TokenNameIdentifier) {
3194 throwSyntaxError("Identifier expected after '::' operator.");
3198 case TokenNameEncapsedString0 :
3200 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3201 while (scanner.currentCharacter != '`') {
3202 if (scanner.currentCharacter == '\\') {
3203 scanner.currentPosition++;
3205 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3208 } catch (IndexOutOfBoundsException e) {
3209 throwSyntaxError("'`' expected at end of static string.");
3212 case TokenNameEncapsedString1 :
3214 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3215 while (scanner.currentCharacter != '\'') {
3216 if (scanner.currentCharacter == '\\') {
3217 scanner.currentPosition++;
3219 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3222 } catch (IndexOutOfBoundsException e) {
3223 throwSyntaxError("'\'' expected at end of static string.");
3226 case TokenNameEncapsedString2 :
3228 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3229 while (scanner.currentCharacter != '"') {
3230 if (scanner.currentCharacter == '\\') {
3231 scanner.currentPosition++;
3233 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3236 } catch (IndexOutOfBoundsException e) {
3237 throwSyntaxError("'\"' expected at end of static string.");
3240 case TokenNamePLUS :
3244 case TokenNameMINUS :
3248 case TokenNamearray :
3250 if (token != TokenNameLPAREN) {
3251 throwSyntaxError("'(' expected after keyword 'array'");
3254 if (token == TokenNameRPAREN) {
3258 non_empty_static_array_pair_list();
3259 if (token != TokenNameRPAREN) {
3260 throwSyntaxError("')' expected after keyword 'array'");
3264 // case TokenNamenull :
3267 // case TokenNamefalse :
3270 // case TokenNametrue :
3274 throwSyntaxError("Static scalar/constant expected.");
3277 private void non_empty_static_array_pair_list() {
3278 // non_empty_static_array_pair_list:
3279 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3281 //| non_empty_static_array_pair_list ',' static_scalar
3282 //| static_scalar T_DOUBLE_ARROW static_scalar
3286 if (token == TokenNameEQUAL_GREATER) {
3290 if (token != TokenNameCOMMA) {
3294 if (token == TokenNameRPAREN) {
3299 public void reportSyntaxError() { //int act, int currentKind, int
3301 /* remember current scanner position */
3302 int startPos = scanner.startPosition;
3303 int currentPos = scanner.currentPosition;
3304 // String[] expectings;
3305 // String tokenName = name[symbol_index[currentKind]];
3306 //fetch all "accurate" possible terminals that could recover the error
3307 // int start, end = start = asi(stack[stateStackTop]);
3308 // while (asr[end] != 0)
3310 // int length = end - start;
3311 // expectings = new String[length];
3312 // if (length != 0) {
3313 // char[] indexes = new char[length];
3314 // System.arraycopy(asr, start, indexes, 0, length);
3315 // for (int i = 0; i < length; i++) {
3316 // expectings[i] = name[symbol_index[indexes[i]]];
3319 //if the pb is an EOF, try to tell the user that they are some
3320 // if (tokenName.equals(UNEXPECTED_EOF)) {
3321 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3322 // char[] tokenSource;
3324 // tokenSource = this.scanner.getCurrentTokenSource();
3325 // } catch (Exception e) {
3326 // tokenSource = new char[] {};
3328 // problemReporter().parseError(
3329 // this.scanner.startPosition,
3330 // this.scanner.currentPosition - 1,
3335 // } else { //the next test is HEAVILY grammar DEPENDENT.
3336 // if ((length == 14)
3337 // && (expectings[0] == "=") //$NON-NLS-1$
3338 // && (expectings[1] == "*=") //$NON-NLS-1$
3339 // && (expressionPtr > -1)) {
3340 // switch(currentKind) {
3341 // case TokenNameSEMICOLON:
3342 // case TokenNamePLUS:
3343 // case TokenNameMINUS:
3344 // case TokenNameDIVIDE:
3345 // case TokenNameREMAINDER:
3346 // case TokenNameMULTIPLY:
3347 // case TokenNameLEFT_SHIFT:
3348 // case TokenNameRIGHT_SHIFT:
3349 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3350 // case TokenNameLESS:
3351 // case TokenNameGREATER:
3352 // case TokenNameLESS_EQUAL:
3353 // case TokenNameGREATER_EQUAL:
3354 // case TokenNameEQUAL_EQUAL:
3355 // case TokenNameNOT_EQUAL:
3356 // case TokenNameXOR:
3357 // case TokenNameAND:
3358 // case TokenNameOR:
3359 // case TokenNameOR_OR:
3360 // case TokenNameAND_AND:
3361 // // the ; is not the expected token ==> it ends a statement when an
3362 // expression is not ended
3363 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3365 // case TokenNameRBRACE :
3366 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3369 // char[] tokenSource;
3371 // tokenSource = this.scanner.getCurrentTokenSource();
3372 // } catch (Exception e) {
3373 // tokenSource = new char[] {};
3375 // problemReporter().parseError(
3376 // this.scanner.startPosition,
3377 // this.scanner.currentPosition - 1,
3381 // this.checkAndReportBracketAnomalies(problemReporter());
3386 tokenSource = this.scanner.getCurrentTokenSource();
3387 } catch (Exception e) {
3388 tokenSource = new char[]{};
3390 // problemReporter().parseError(
3391 // this.scanner.startPosition,
3392 // this.scanner.currentPosition - 1,
3396 this.checkAndReportBracketAnomalies(problemReporter());
3399 /* reset scanner where it was */
3400 scanner.startPosition = startPos;
3401 scanner.currentPosition = currentPos;
3403 public static final int RoundBracket = 0;
3404 public static final int SquareBracket = 1;
3405 public static final int CurlyBracket = 2;
3406 public static final int BracketKinds = 3;
3407 protected int[] nestedMethod; //the ptr is nestedType
3408 protected int nestedType, dimensions;
3410 final static int AstStackIncrement = 100;
3411 protected int astPtr;
3412 protected AstNode[] astStack = new AstNode[AstStackIncrement];
3413 protected int astLengthPtr;
3414 protected int[] astLengthStack;
3415 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3416 public CompilationUnitDeclaration compilationUnit; /*
3417 * the result from parse()
3419 protected ReferenceContext referenceContext;
3420 protected ProblemReporter problemReporter;
3421 // protected CompilationResult compilationResult;
3423 * Returns this parser's problem reporter initialized with its reference
3424 * context. Also it is assumed that a problem is going to be reported, so
3425 * initializes the compilation result's line positions.
3427 public ProblemReporter problemReporter() {
3428 if (scanner.recordLineSeparator) {
3429 compilationUnit.compilationResult.lineSeparatorPositions = scanner
3432 problemReporter.referenceContext = referenceContext;
3433 return problemReporter;
3436 * Reconsider the entire source looking for inconsistencies in {} () []
3438 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3439 scanner.wasAcr = false;
3440 boolean anomaliesDetected = false;
3442 char[] source = scanner.source;
3443 int[] leftCount = {0, 0, 0};
3444 int[] rightCount = {0, 0, 0};
3445 int[] depths = {0, 0, 0};
3446 int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3447 int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3448 int[][] rightPositions = new int[][]{new int[10], new int[10],
3450 int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3451 scanner.currentPosition = scanner.initialPosition; //starting
3453 // (first-zero-based
3455 while (scanner.currentPosition < scanner.eofPosition) { //loop for
3460 // ---------Consume white space and handles
3461 // startPosition---------
3462 boolean isWhiteSpace;
3464 scanner.startPosition = scanner.currentPosition;
3465 // if (((scanner.currentCharacter =
3466 // source[scanner.currentPosition++]) == '\\') &&
3467 // (source[scanner.currentPosition] == 'u')) {
3468 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3470 if (scanner.recordLineSeparator
3471 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3472 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3473 // only record line positions we have not
3475 scanner.pushLineSeparator();
3478 isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3480 } while (isWhiteSpace
3481 && (scanner.currentPosition < scanner.eofPosition));
3482 // -------consume token until } is found---------
3483 switch (scanner.currentCharacter) {
3486 int index = leftCount[CurlyBracket]++;
3487 if (index == leftPositions[CurlyBracket].length) {
3488 System.arraycopy(leftPositions[CurlyBracket], 0,
3489 (leftPositions[CurlyBracket] = new int[index * 2]), 0,
3492 .arraycopy(leftDepths[CurlyBracket], 0,
3493 (leftDepths[CurlyBracket] = new int[index * 2]), 0,
3496 leftPositions[CurlyBracket][index] = scanner.startPosition;
3497 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3502 int index = rightCount[CurlyBracket]++;
3503 if (index == rightPositions[CurlyBracket].length) {
3504 System.arraycopy(rightPositions[CurlyBracket], 0,
3505 (rightPositions[CurlyBracket] = new int[index * 2]), 0,
3507 System.arraycopy(rightDepths[CurlyBracket], 0,
3508 (rightDepths[CurlyBracket] = new int[index * 2]), 0,
3511 rightPositions[CurlyBracket][index] = scanner.startPosition;
3512 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3517 int index = leftCount[RoundBracket]++;
3518 if (index == leftPositions[RoundBracket].length) {
3519 System.arraycopy(leftPositions[RoundBracket], 0,
3520 (leftPositions[RoundBracket] = new int[index * 2]), 0,
3523 .arraycopy(leftDepths[RoundBracket], 0,
3524 (leftDepths[RoundBracket] = new int[index * 2]), 0,
3527 leftPositions[RoundBracket][index] = scanner.startPosition;
3528 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3533 int index = rightCount[RoundBracket]++;
3534 if (index == rightPositions[RoundBracket].length) {
3535 System.arraycopy(rightPositions[RoundBracket], 0,
3536 (rightPositions[RoundBracket] = new int[index * 2]), 0,
3538 System.arraycopy(rightDepths[RoundBracket], 0,
3539 (rightDepths[RoundBracket] = new int[index * 2]), 0,
3542 rightPositions[RoundBracket][index] = scanner.startPosition;
3543 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3548 int index = leftCount[SquareBracket]++;
3549 if (index == leftPositions[SquareBracket].length) {
3550 System.arraycopy(leftPositions[SquareBracket], 0,
3551 (leftPositions[SquareBracket] = new int[index * 2]), 0,
3553 System.arraycopy(leftDepths[SquareBracket], 0,
3554 (leftDepths[SquareBracket] = new int[index * 2]), 0,
3557 leftPositions[SquareBracket][index] = scanner.startPosition;
3558 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3563 int index = rightCount[SquareBracket]++;
3564 if (index == rightPositions[SquareBracket].length) {
3565 System.arraycopy(rightPositions[SquareBracket], 0,
3566 (rightPositions[SquareBracket] = new int[index * 2]), 0,
3568 System.arraycopy(rightDepths[SquareBracket], 0,
3569 (rightDepths[SquareBracket] = new int[index * 2]), 0,
3572 rightPositions[SquareBracket][index] = scanner.startPosition;
3573 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3578 if (scanner.getNextChar('\\')) {
3579 scanner.scanEscapeCharacter();
3580 } else { // consume next character
3581 scanner.unicodeAsBackSlash = false;
3582 // if (((scanner.currentCharacter =
3583 // source[scanner.currentPosition++]) ==
3585 // (source[scanner.currentPosition] ==
3587 // scanner.getNextUnicodeChar();
3589 if (scanner.withoutUnicodePtr != 0) {
3590 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3594 scanner.getNextChar('\'');
3598 // consume next character
3599 scanner.unicodeAsBackSlash = false;
3600 // if (((scanner.currentCharacter =
3601 // source[scanner.currentPosition++]) == '\\') &&
3602 // (source[scanner.currentPosition] == 'u')) {
3603 // scanner.getNextUnicodeChar();
3605 if (scanner.withoutUnicodePtr != 0) {
3606 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3609 while (scanner.currentCharacter != '"') {
3610 if (scanner.currentCharacter == '\r') {
3611 if (source[scanner.currentPosition] == '\n')
3612 scanner.currentPosition++;
3613 break; // the string cannot go further that
3616 if (scanner.currentCharacter == '\n') {
3617 break; // the string cannot go further that
3620 if (scanner.currentCharacter == '\\') {
3621 scanner.scanEscapeCharacter();
3623 // consume next character
3624 scanner.unicodeAsBackSlash = false;
3625 // if (((scanner.currentCharacter =
3626 // source[scanner.currentPosition++]) == '\\')
3627 // && (source[scanner.currentPosition] == 'u'))
3629 // scanner.getNextUnicodeChar();
3631 if (scanner.withoutUnicodePtr != 0) {
3632 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3640 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3643 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3644 && (source[scanner.currentPosition] == 'u')) {
3645 //-------------unicode traitement
3647 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3648 scanner.currentPosition++;
3649 while (source[scanner.currentPosition] == 'u') {
3650 scanner.currentPosition++;
3653 .getNumericValue(source[scanner.currentPosition++])) > 15
3656 .getNumericValue(source[scanner.currentPosition++])) > 15
3659 .getNumericValue(source[scanner.currentPosition++])) > 15
3662 .getNumericValue(source[scanner.currentPosition++])) > 15
3663 || c4 < 0) { //error don't
3666 scanner.currentCharacter = 'A';
3667 } //something different from \n and \r
3669 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3672 while (scanner.currentCharacter != '\r'
3673 && scanner.currentCharacter != '\n') {
3675 scanner.startPosition = scanner.currentPosition;
3676 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3677 && (source[scanner.currentPosition] == 'u')) {
3678 //-------------unicode traitement
3680 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3681 scanner.currentPosition++;
3682 while (source[scanner.currentPosition] == 'u') {
3683 scanner.currentPosition++;
3686 .getNumericValue(source[scanner.currentPosition++])) > 15
3689 .getNumericValue(source[scanner.currentPosition++])) > 15
3692 .getNumericValue(source[scanner.currentPosition++])) > 15
3695 .getNumericValue(source[scanner.currentPosition++])) > 15
3696 || c4 < 0) { //error don't
3699 scanner.currentCharacter = 'A';
3700 } //something different from \n
3703 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3707 if (scanner.recordLineSeparator
3708 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3709 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3710 // only record line positions we
3711 // have not recorded yet
3712 scanner.pushLineSeparator();
3713 if (this.scanner.taskTags != null) {
3714 this.scanner.checkTaskTag(this.scanner
3715 .getCurrentTokenStartPosition(), this.scanner
3716 .getCurrentTokenEndPosition());
3722 if (test > 0) { //traditional and annotation
3724 boolean star = false;
3725 // consume next character
3726 scanner.unicodeAsBackSlash = false;
3727 // if (((scanner.currentCharacter =
3728 // source[scanner.currentPosition++]) ==
3730 // (source[scanner.currentPosition] ==
3732 // scanner.getNextUnicodeChar();
3734 if (scanner.withoutUnicodePtr != 0) {
3735 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3738 if (scanner.currentCharacter == '*') {
3742 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3743 && (source[scanner.currentPosition] == 'u')) {
3744 //-------------unicode traitement
3746 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3747 scanner.currentPosition++;
3748 while (source[scanner.currentPosition] == 'u') {
3749 scanner.currentPosition++;
3752 .getNumericValue(source[scanner.currentPosition++])) > 15
3755 .getNumericValue(source[scanner.currentPosition++])) > 15
3758 .getNumericValue(source[scanner.currentPosition++])) > 15
3761 .getNumericValue(source[scanner.currentPosition++])) > 15
3762 || c4 < 0) { //error don't
3765 scanner.currentCharacter = 'A';
3766 } //something different from * and /
3768 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3771 //loop until end of comment */
3772 while ((scanner.currentCharacter != '/') || (!star)) {
3773 star = scanner.currentCharacter == '*';
3775 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3776 && (source[scanner.currentPosition] == 'u')) {
3777 //-------------unicode traitement
3779 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3780 scanner.currentPosition++;
3781 while (source[scanner.currentPosition] == 'u') {
3782 scanner.currentPosition++;
3785 .getNumericValue(source[scanner.currentPosition++])) > 15
3788 .getNumericValue(source[scanner.currentPosition++])) > 15
3791 .getNumericValue(source[scanner.currentPosition++])) > 15
3794 .getNumericValue(source[scanner.currentPosition++])) > 15
3795 || c4 < 0) { //error don't
3798 scanner.currentCharacter = 'A';
3799 } //something different from * and
3802 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3806 if (this.scanner.taskTags != null) {
3807 this.scanner.checkTaskTag(this.scanner
3808 .getCurrentTokenStartPosition(), this.scanner
3809 .getCurrentTokenEndPosition());
3816 if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3817 scanner.scanIdentifierOrKeyword(false);
3820 if (Character.isDigit(scanner.currentCharacter)) {
3821 scanner.scanNumber(false);
3825 //-----------------end switch while
3826 // try--------------------
3827 } catch (IndexOutOfBoundsException e) {
3828 break; // read until EOF
3829 } catch (InvalidInputException e) {
3830 return false; // no clue
3833 if (scanner.recordLineSeparator) {
3834 // compilationUnit.compilationResult.lineSeparatorPositions =
3835 // scanner.getLineEnds();
3837 // check placement anomalies against other kinds of brackets
3838 for (int kind = 0; kind < BracketKinds; kind++) {
3839 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3840 int start = leftPositions[kind][leftIndex]; // deepest
3842 // find matching closing bracket
3843 int depth = leftDepths[kind][leftIndex];
3845 for (int i = 0; i < rightCount[kind]; i++) {
3846 int pos = rightPositions[kind][i];
3847 // want matching bracket further in source with same
3849 if ((pos > start) && (depth == rightDepths[kind][i])) {
3854 if (end < 0) { // did not find a good closing match
3855 problemReporter.unmatchedBracket(start, referenceContext,
3856 compilationUnit.compilationResult);
3859 // check if even number of opening/closing other brackets
3860 // in between this pair of brackets
3862 for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3863 for (int i = 0; i < leftCount[otherKind]; i++) {
3864 int pos = leftPositions[otherKind][i];
3865 if ((pos > start) && (pos < end))
3868 for (int i = 0; i < rightCount[otherKind]; i++) {
3869 int pos = rightPositions[otherKind][i];
3870 if ((pos > start) && (pos < end))
3874 problemReporter.unmatchedBracket(start, referenceContext,
3875 compilationUnit.compilationResult); //bracket
3881 // too many opening brackets ?
3882 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3883 anomaliesDetected = true;
3884 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind]
3885 - i - 1], referenceContext, compilationUnit.compilationResult);
3887 // too many closing brackets ?
3888 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3889 anomaliesDetected = true;
3890 problemReporter.unmatchedBracket(rightPositions[kind][i],
3891 referenceContext, compilationUnit.compilationResult);
3893 if (anomaliesDetected)
3896 return anomaliesDetected;
3897 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
3898 return anomaliesDetected;
3899 } catch (NullPointerException e) { // jdk1.2.2 jit bug
3900 return anomaliesDetected;
3903 protected void pushOnAstLengthStack(int pos) {
3905 astLengthStack[++astLengthPtr] = pos;
3906 } catch (IndexOutOfBoundsException e) {
3907 int oldStackLength = astLengthStack.length;
3908 int[] oldPos = astLengthStack;
3909 astLengthStack = new int[oldStackLength + StackIncrement];
3910 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3911 astLengthStack[astLengthPtr] = pos;
3914 protected void pushOnAstStack(AstNode node) {
3916 * add a new obj on top of the ast stack
3919 astStack[++astPtr] = node;
3920 } catch (IndexOutOfBoundsException e) {
3921 int oldStackLength = astStack.length;
3922 AstNode[] oldStack = astStack;
3923 astStack = new AstNode[oldStackLength + AstStackIncrement];
3924 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
3925 astPtr = oldStackLength;
3926 astStack[astPtr] = node;
3929 astLengthStack[++astLengthPtr] = 1;
3930 } catch (IndexOutOfBoundsException e) {
3931 int oldStackLength = astLengthStack.length;
3932 int[] oldPos = astLengthStack;
3933 astLengthStack = new int[oldStackLength + AstStackIncrement];
3934 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
3935 astLengthStack[astLengthPtr] = 1;