1 /*******************************************************************************
2 * Copyright (c) 2002 Klaus Hartlage - www.eclipseproject.de All rights
3 * reserved. This program and the accompanying material are made available under
4 * the terms of the Common Public License v1.0 which accompanies this
5 * distribution, and is available at http://www.eclipse.org/legal/cpl-v10.html
7 * Contributors: Klaus Hartlage - www.eclipseproject.de
8 ******************************************************************************/
9 package net.sourceforge.phpdt.internal.compiler.parser;
10 import java.util.ArrayList;
12 import net.sourceforge.phpdt.core.compiler.CharOperation;
13 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
14 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
15 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
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.phpdt.internal.compiler.problem.ProblemSeverities;
21 import net.sourceforge.phpdt.internal.compiler.util.Util;
22 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
23 import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
24 import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
25 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
26 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
27 import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
28 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
29 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
30 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
32 import org.eclipse.core.resources.IFile;
33 public class Parser //extends PHPParserSuperclass
34 implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
35 //internal data for the automat
36 protected final static int StackIncrement = 255;
37 protected int stateStackTop;
38 protected int[] stack = new int[StackIncrement];
39 public int firstToken; // handle for multiple parsing goals
40 public int lastAct; //handle for multiple parsing goals
41 protected RecoveredElement currentElement;
42 public static boolean VERBOSE_RECOVERY = false;
43 protected boolean diet = false; //tells the scanner to jump over some
44 // parts of the code/expressions like
47 public Scanner scanner;
48 private ArrayList phpList;
49 private int currentPHPString;
50 private boolean phpEnd;
51 // private static HashMap keywordMap = null;
57 // row counter for syntax errors:
59 // column counter for syntax errors:
63 // // current identifier
67 private String stringValue;
68 /** Contains the current expression. */
69 // private StringBuffer expression;
70 //private boolean phpMode;
71 protected int modifiers;
72 protected int modifiersSourceStart;
73 protected IdentifierIndexManager indexManager;
75 protected Parser(ProblemReporter problemReporter) {
76 this.problemReporter = problemReporter;
77 this.options = problemReporter.options;
78 this.currentPHPString = 0;
79 // PHPParserSuperclass.fileToParse = fileToParse;
81 this.indexManager = null;
83 this.token = TokenNameEOF;
86 // this.columnCount = 0;
89 this.initializeScanner();
91 public void setFileToParse(IFile fileToParse) {
92 this.currentPHPString = 0;
93 // PHPParserSuperclass.fileToParse = fileToParse;
95 this.indexManager = null;
97 this.token = TokenNameEOF;
99 this.initializeScanner();
102 * ClassDeclaration Constructor.
106 * Description of Parameter
109 public Parser(IFile fileToParse) {
110 // if (keywordMap == null) {
111 // keywordMap = new HashMap();
112 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
113 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
116 this.currentPHPString = 0;
117 // PHPParserSuperclass.fileToParse = fileToParse;
119 this.includesList = null;
121 this.token = TokenNameEOF;
123 // this.rowCount = 1;
124 // this.columnCount = 0;
127 this.initializeScanner();
129 public void initializeScanner() {
130 this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options
131 .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false,
132 this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */);
135 * Create marker for the parse error
137 // private void setMarker(String message, int charStart, int charEnd, int
139 // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
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) {
151 int problemStartPosition = scanner.getCurrentTokenStartPosition();
152 int problemEndPosition = scanner.getCurrentTokenEndPosition();
153 throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
156 * This method will throw the SyntaxError. It will add the good lines and
157 * columns to the Error
161 * @throws SyntaxError
164 // private void throwSyntaxError(String error, int startRow) {
165 // throw new SyntaxError(startRow, 0, " ", error);
167 private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
168 problemReporter.phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
169 compilationUnit.compilationResult);
170 throw new SyntaxError(1, 0, " ", error);
172 private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
173 problemReporter.phpParsingError(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
174 compilationUnit.compilationResult);
176 private void reportSyntaxWarning(String error, int problemStartPosition, int problemEndPosition) {
177 problemReporter.phpParsingWarning(new String[]{error}, problemStartPosition, problemEndPosition, referenceContext,
178 compilationUnit.compilationResult);
181 * Method Declaration.
185 // private void getChar() {
186 // if (str.length() > chIndx) {
187 // ch = str.charAt(chIndx++);
192 // chIndx = str.length() + 1;
194 // // token = TokenNameEOF;
198 * gets the next token from input
200 private void getNextToken() {
202 token = scanner.getNextToken();
204 int currentEndPosition = scanner.getCurrentTokenEndPosition();
205 int currentStartPosition = scanner.getCurrentTokenStartPosition();
206 System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
207 System.out.println(scanner.toStringAction(token));
209 } catch (InvalidInputException e) {
210 token = TokenNameERROR;
214 public void init(String s) {
216 this.token = TokenNameEOF;
218 // this.rowCount = 1;
219 // this.columnCount = 0;
221 // this.phpMode = false;
222 /* scanner initialization */
223 scanner.setSource(s.toCharArray());
224 scanner.setPHPMode(false);
226 protected void initialize(boolean phpMode) {
227 initialize(phpMode, null);
229 protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) {
230 compilationUnit = null;
231 referenceContext = null;
232 includesList = new ArrayList();
233 this.indexManager = indexManager;
235 this.token = TokenNameEOF;
237 // this.rowCount = 1;
238 // this.columnCount = 0;
240 // this.phpMode = phpMode;
241 scanner.setPHPMode(phpMode);
244 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
247 public void parse(String s) {
252 * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
255 protected void parse() {
259 if (token != TokenNameEOF && token != TokenNameERROR) {
262 if (token != TokenNameEOF) {
263 if (token == TokenNameERROR) {
264 throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
266 if (token == TokenNameRPAREN) {
267 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
269 if (token == TokenNameRBRACE) {
270 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
272 if (token == TokenNameRBRACKET) {
273 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
275 if (token == TokenNameLPAREN) {
276 throwSyntaxError("Read character '('; end-of-file not reached.");
278 if (token == TokenNameLBRACE) {
279 throwSyntaxError("Read character '{'; end-of-file not reached.");
281 if (token == TokenNameLBRACKET) {
282 throwSyntaxError("Read character '['; end-of-file not reached.");
284 throwSyntaxError("End-of-file not reached.");
287 } catch (SyntaxError sytaxErr1) {
288 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
290 // setMarker(sytaxErr1.getMessage(),
291 // scanner.getCurrentTokenStartPosition(),
292 // scanner.getCurrentTokenEndPosition(), ERROR);
294 // if an error occured,
295 // try to find keywords 'class' or 'function'
296 // to parse the rest of the string
297 while (token != TokenNameEOF && token != TokenNameERROR) {
298 if (token == TokenNameabstract || token == TokenNamefinal || token == TokenNameclass || token == TokenNamefunction) {
303 if (token == TokenNameEOF || token == TokenNameERROR) {
306 } catch (SyntaxError sytaxErr2) {
307 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
309 // setMarker(sytaxErr2.getMessage(),
310 // scanner.getCurrentTokenStartPosition(),
311 // scanner.getCurrentTokenEndPosition(), ERROR);
320 protected CompilationUnitDeclaration endParse(int act) {
324 if (currentElement != null) {
325 currentElement.topElement().updateParseTree();
326 if (VERBOSE_RECOVERY) {
327 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
328 System.out.println("--------------------------"); //$NON-NLS-1$
329 System.out.println(compilationUnit);
330 System.out.println("----------------------------------"); //$NON-NLS-1$
333 if (diet & VERBOSE_RECOVERY) {
334 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
335 System.out.println("--------------------------"); //$NON-NLS-1$
336 System.out.println(compilationUnit);
337 System.out.println("----------------------------------"); //$NON-NLS-1$
340 if (scanner.recordLineSeparator) {
341 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
343 if (scanner.taskTags != null) {
344 for (int i = 0; i < scanner.foundTaskCount; i++) {
345 problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]),
346 scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
347 scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]);
350 compilationUnit.imports = new ImportReference[includesList.size()];
351 for (int i = 0; i < includesList.size(); i++) {
352 compilationUnit.imports[i] = (ImportReference) includesList.get(i);
354 return compilationUnit;
356 // public PHPOutlineInfo parseInfo(Object parent, String s) {
357 // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
358 // // Stack stack = new Stack();
359 // // stack.push(outlineInfo.getDeclarations());
361 // this.token = TokenNameEOF;
362 // // this.chIndx = 0;
363 // // this.rowCount = 1;
364 // // this.columnCount = 0;
365 // this.phpEnd = false;
366 // this.phpMode = false;
367 // scanner.setSource(s.toCharArray());
368 // scanner.setPHPMode(false);
371 // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
373 // return outlineInfo;
375 private boolean isVariable() {
376 return token == TokenNameVariable; // || token == TokenNamethis;
378 // private void parseDeclarations(PHPOutlineInfo outlineInfo,
379 // OutlineableWithChildren current, boolean goBack) {
381 // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
382 // PHPSegmentWithChildren temp;
384 // IPreferenceStore store =
385 // PHPeclipsePlugin.getDefault().getPreferenceStore();
387 // while (token != TokenNameEOF && token != TokenNameERROR) {
388 // if (token == TokenNameVariable) {
389 // ident = scanner.getCurrentIdentifierSource();
390 // outlineInfo.addVariable(new String(ident));
392 // } else if (token == TokenNamevar) {
394 // if (token == TokenNameVariable
395 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
396 // ident = scanner.getCurrentIdentifierSource();
397 // //substring(1) added because PHPVarDeclaration doesn't
398 // // need the $ anymore
399 // String variableName = new String(ident).substring(1);
400 // outlineInfo.addVariable(variableName);
402 // if (token != TokenNameSEMICOLON) {
404 // ident = scanner.getCurrentTokenSource();
405 // if (token > TokenNameKEYWORD) {
406 // current.add(new PHPVarDeclaration(current, variableName,
407 // // chIndx - ident.length,
408 // scanner.getCurrentTokenStartPosition(), new String(ident)));
411 // case TokenNameVariable :
412 // case TokenNamethis :
413 // current.add(new PHPVarDeclaration(current, variableName,
416 // scanner.getCurrentTokenStartPosition(), new String(
419 // case TokenNameIdentifier :
420 // current.add(new PHPVarDeclaration(current, variableName,
423 // scanner.getCurrentTokenStartPosition(), new String(
426 // case TokenNameDoubleLiteral :
427 // current.add(new PHPVarDeclaration(current, variableName
431 // scanner.getCurrentTokenStartPosition(), new String(
434 // case TokenNameIntegerLiteral :
435 // current.add(new PHPVarDeclaration(current, variableName,
438 // scanner.getCurrentTokenStartPosition(), new String(
441 // case TokenNameStringInterpolated :
442 // case TokenNameStringLiteral :
443 // current.add(new PHPVarDeclaration(current, variableName,
446 // scanner.getCurrentTokenStartPosition(), new String(
449 // case TokenNameStringConstant :
450 // current.add(new PHPVarDeclaration(current, variableName,
453 // scanner.getCurrentTokenStartPosition(), new String(
457 // current.add(new PHPVarDeclaration(current, variableName,
460 // scanner.getCurrentTokenStartPosition()));
465 // ident = scanner.getCurrentIdentifierSource();
466 // current.add(new PHPVarDeclaration(current, variableName,
467 // // chIndx - ident.length
468 // scanner.getCurrentTokenStartPosition()));
471 // } else if (token == TokenNamefunction) {
473 // if (token == TokenNameAND) {
476 // if (token == TokenNameIdentifier
477 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
478 // ident = scanner.getCurrentIdentifierSource();
479 // outlineInfo.addVariable(new String(ident));
480 // temp = new PHPFunctionDeclaration(current, new String(ident),
481 // // chIndx - ident.length
482 // scanner.getCurrentTokenStartPosition());
483 // current.add(temp);
485 // parseDeclarations(outlineInfo, temp, true);
487 // } else if (token == TokenNameclass) {
489 // if (token == TokenNameIdentifier
490 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
491 // ident = scanner.getCurrentIdentifierSource();
492 // outlineInfo.addVariable(new String(ident));
493 // temp = new PHPClassDeclaration(current, new String(ident),
494 // // chIndx - ident.len
495 // scanner.getCurrentTokenStartPosition());
496 // current.add(temp);
497 // // stack.push(temp);
499 // //skip tokens for classname, extends and others until
500 // // we have the opening '{'
501 // while (token != TokenNameLBRACE && token != TokenNameEOF
502 // && token != TokenNameERROR) {
505 // parseDeclarations(outlineInfo, temp, true);
508 // } else if ((token == TokenNameLBRACE)
509 // || (token == TokenNameDOLLAR_LBRACE)) {
512 // } else if (token == TokenNameRBRACE) {
515 // if (counter == 0 && goBack) {
518 // } else if (token == TokenNamerequire || token == TokenNamerequire_once
519 // || token == TokenNameinclude || token == TokenNameinclude_once) {
520 // ident = scanner.getCurrentTokenSource();
522 // int startPosition = scanner.getCurrentTokenStartPosition();
524 // char[] expr = scanner.getCurrentTokenSource(startPosition);
525 // outlineInfo.addVariable(new String(ident));
526 // current.add(new PHPReqIncDeclaration(current, new String(ident),
527 // // chIndx - ident.length,
528 // startPosition, new String(expr)));
534 // } catch (SyntaxError sytaxErr) {
536 // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
537 // // setMarker(sytaxErr.getMessage(),
538 // // scanner.getCurrentTokenStartPosition(),
539 // // scanner.getCurrentTokenEndPosition(), ERROR);
540 // // } catch (CoreException e) {
544 private void statementList() {
546 statement(TokenNameEOF);
547 if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
548 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
549 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
550 || (token == TokenNameEOF) || (token == TokenNameERROR)) {
555 private void functionBody(MethodDeclaration methodDecl) {
556 // '{' [statement-list] '}'
557 if (token == TokenNameLBRACE) {
560 throwSyntaxError("'{' expected in compound-statement.");
562 if (token != TokenNameRBRACE) {
565 if (token == TokenNameRBRACE) {
566 methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
569 throwSyntaxError("'}' expected in compound-statement.");
572 private void statement(int previousToken) {
573 // if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
575 // char[] ident = scanner.getCurrentIdentifierSource();
576 // String keyword = new String(ident);
577 // if (token == TokenNameAT) {
579 // if (token != TokenNamerequire && token != TokenNamerequire_once
580 // && token != TokenNameinclude && token != TokenNameinclude_once
581 // && token != TokenNameIdentifier && token != TokenNameVariable
582 // && token != TokenNameStringInterpolated) {
583 // throwSyntaxError("identifier expected after '@'.");
586 // if (token == TokenNameinclude || token == TokenNameinclude_once) {
588 // if (token == TokenNameLPAREN) {
590 // if (token == TokenNameSEMICOLON) {
593 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
594 // throwSyntaxError("';' expected after 'include' or 'include_once'.");
596 // // getNextToken();
599 // concatenationExpression();
602 // } else if (token == TokenNamerequire || token ==
603 // TokenNamerequire_once)
607 // if (token == TokenNameLPAREN) {
609 // if (token == TokenNameSEMICOLON) {
612 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
613 // throwSyntaxError("';' expected after 'require' or 'require_once'.");
615 // // getNextToken();
618 // concatenationExpression();
622 if (token == TokenNameif) {
624 if (token == TokenNameLPAREN) {
627 throwSyntaxError("'(' expected after 'if' keyword.");
630 if (token == TokenNameRPAREN) {
633 throwSyntaxError("')' expected after 'if' condition.");
637 } else if (token == TokenNameswitch) {
639 if (token == TokenNameLPAREN) {
642 throwSyntaxError("'(' expected after 'switch' keyword.");
645 if (token == TokenNameRPAREN) {
648 throwSyntaxError("')' expected after 'switch' condition.");
652 } else if (token == TokenNamefor) {
654 if (token == TokenNameLPAREN) {
657 throwSyntaxError("'(' expected after 'for' keyword.");
659 if (token == TokenNameSEMICOLON) {
663 if (token == TokenNameSEMICOLON) {
666 throwSyntaxError("';' expected after 'for'.");
669 if (token == TokenNameSEMICOLON) {
673 if (token == TokenNameSEMICOLON) {
676 throwSyntaxError("';' expected after 'for'.");
679 if (token == TokenNameRPAREN) {
683 if (token == TokenNameRPAREN) {
686 throwSyntaxError("')' expected after 'for'.");
691 } else if (token == TokenNamewhile) {
693 if (token == TokenNameLPAREN) {
696 throwSyntaxError("'(' expected after 'while' keyword.");
699 if (token == TokenNameRPAREN) {
702 throwSyntaxError("')' expected after 'while' condition.");
706 } else if (token == TokenNamedo) {
708 if (token == TokenNameLBRACE) {
710 if (token != TokenNameRBRACE) {
713 if (token == TokenNameRBRACE) {
716 throwSyntaxError("'}' expected after 'do' keyword.");
719 statement(TokenNameEOF);
721 if (token == TokenNamewhile) {
723 if (token == TokenNameLPAREN) {
726 throwSyntaxError("'(' expected after 'while' keyword.");
729 if (token == TokenNameRPAREN) {
732 throwSyntaxError("')' expected after 'while' condition.");
735 throwSyntaxError("'while' expected after 'do' keyword.");
737 if (token == TokenNameSEMICOLON) {
740 if (token != TokenNameINLINE_HTML) {
741 throwSyntaxError("';' expected after do-while statement.");
746 } else if (token == TokenNameforeach) {
748 if (token == TokenNameLPAREN) {
751 throwSyntaxError("'(' expected after 'foreach' keyword.");
754 if (token == TokenNameas) {
757 throwSyntaxError("'as' expected after 'foreach' exxpression.");
761 foreach_optional_arg();
762 if (token == TokenNameEQUAL_GREATER) {
766 if (token == TokenNameRPAREN) {
769 throwSyntaxError("')' expected after 'foreach' expression.");
773 } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
775 if (token != TokenNameSEMICOLON) {
778 if (token == TokenNameSEMICOLON) {
781 if (token != TokenNameINLINE_HTML) {
782 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
787 } else if (token == TokenNameecho) {
790 if (token == TokenNameSEMICOLON) {
793 if (token != TokenNameINLINE_HTML) {
794 throwSyntaxError("';' expected after 'echo' statement.");
799 } else if (token == TokenNameINLINE_HTML) {
802 // } else if (token == TokenNameprint) {
805 // if (token == TokenNameSEMICOLON) {
808 // if (token != TokenNameStopPHP) {
809 // throwSyntaxError("';' expected after 'print' statement.");
814 } else if (token == TokenNameglobal) {
817 if (token == TokenNameSEMICOLON) {
820 if (token != TokenNameINLINE_HTML) {
821 throwSyntaxError("';' expected after 'global' statement.");
826 } else if (token == TokenNamestatic) {
829 if (token == TokenNameSEMICOLON) {
832 if (token != TokenNameINLINE_HTML) {
833 throwSyntaxError("';' expected after 'static' statement.");
838 } else if (token == TokenNameunset) {
840 if (token == TokenNameLPAREN) {
843 throwSyntaxError("'(' expected after 'unset' statement.");
846 if (token == TokenNameRPAREN) {
849 throwSyntaxError("')' expected after 'unset' statement.");
851 if (token == TokenNameSEMICOLON) {
854 if (token != TokenNameINLINE_HTML) {
855 throwSyntaxError("';' expected after 'unset' statement.");
860 } else if (token == TokenNamefunction) {
861 MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
862 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
863 methodDecl.modifiers = AccDefault;
865 functionDefinition(methodDecl);
867 } else if (token == TokenNametry) {
869 if (token != TokenNameLBRACE) {
870 throwSyntaxError("'{' expected in 'try' statement.");
874 if (token != TokenNameRBRACE) {
875 throwSyntaxError("'}' expected in 'try' statement.");
879 } else if (token == TokenNamecatch) {
881 if (token != TokenNameLPAREN) {
882 throwSyntaxError("'(' expected in 'catch' statement.");
885 fully_qualified_class_name();
886 if (token != TokenNameVariable) {
887 throwSyntaxError("Variable expected in 'catch' statement.");
890 if (token != TokenNameRPAREN) {
891 throwSyntaxError("')' expected in 'catch' statement.");
894 if (token != TokenNameLBRACE) {
895 throwSyntaxError("'{' expected in 'catch' statement.");
898 if (token != TokenNameRBRACE) {
900 if (token != TokenNameRBRACE) {
901 throwSyntaxError("'}' expected in 'catch' statement.");
905 additional_catches();
907 } else if (token == TokenNamethrow) {
910 if (token == TokenNameSEMICOLON) {
913 throwSyntaxError("';' expected after 'throw' exxpression.");
916 } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
917 TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
918 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
919 // default super class
920 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
921 compilationUnit.types.add(typeDecl);
923 pushOnAstStack(typeDecl);
924 unticked_class_declaration_statement(typeDecl);
925 // classBody(typeDecl);
932 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
933 } else if (token == TokenNameLBRACE) {
935 if (token != TokenNameRBRACE) {
938 if (token == TokenNameRBRACE) {
942 throwSyntaxError("'}' expected.");
945 if (token != TokenNameSEMICOLON) {
948 if (token == TokenNameSEMICOLON) {
952 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
953 throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
959 private void additional_catches() {
960 while (token == TokenNamecatch) {
962 if (token != TokenNameLPAREN) {
963 throwSyntaxError("'(' expected in 'catch' statement.");
966 fully_qualified_class_name();
967 if (token != TokenNameVariable) {
968 throwSyntaxError("Variable expected in 'catch' statement.");
971 if (token != TokenNameRPAREN) {
972 throwSyntaxError("')' expected in 'catch' statement.");
975 if (token != TokenNameLBRACE) {
976 throwSyntaxError("'{' expected in 'catch' statement.");
980 if (token != TokenNameRBRACE) {
981 throwSyntaxError("'}' expected in 'catch' statement.");
986 private void foreach_variable() {
989 if (token == TokenNameAND) {
994 private void foreach_optional_arg() {
996 //| T_DOUBLE_ARROW foreach_variable
997 if (token == TokenNameEQUAL_GREATER) {
1002 private void global_var_list() {
1004 // global_var_list ',' global_var
1008 if (token != TokenNameCOMMA) {
1014 private void global_var() {
1018 //| '$' '{' expr '}'
1019 if (token == TokenNameVariable) {
1021 } else if (token == TokenNameDOLLAR) {
1023 if (token == TokenNameLPAREN) {
1026 if (token != TokenNameLPAREN) {
1027 throwSyntaxError("')' expected in global variable.");
1035 private void static_var_list() {
1037 // static_var_list ',' T_VARIABLE
1038 //| static_var_list ',' T_VARIABLE '=' static_scalar
1040 //| T_VARIABLE '=' static_scalar
1042 if (token == TokenNameVariable) {
1044 if (token == TokenNameEQUAL) {
1048 if (token != TokenNameCOMMA) {
1057 private void unset_variables() {
1060 // | unset_variables ',' unset_variable
1065 if (token != TokenNameCOMMA) {
1071 private final void initializeModifiers() {
1073 this.modifiersSourceStart = -1;
1075 private final void checkAndSetModifiers(int flag) {
1076 this.modifiers |= flag;
1077 if (this.modifiersSourceStart < 0)
1078 this.modifiersSourceStart = this.scanner.startPosition;
1080 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1081 initializeModifiers();
1082 if (token == TokenNameinterface) {
1083 // interface_entry T_STRING
1084 // interface_extends_list
1085 // '{' class_statement_list '}'
1086 checkAndSetModifiers(AccInterface);
1088 typeDecl.modifiers = this.modifiers;
1089 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1090 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1091 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1092 typeDecl.name = scanner.getCurrentIdentifierSource();
1093 if (token > TokenNameKEYWORD) {
1094 throwSyntaxError("Don't use a keyword for interface declaration [" + scanner.toStringAction(token) + "].",
1095 typeDecl.sourceStart, typeDecl.sourceEnd);
1098 interface_extends_list();
1100 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1101 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1102 typeDecl.name = new char[]{' '};
1103 throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1107 // class_entry_type T_STRING extends_from
1109 // '{' class_statement_list'}'
1111 typeDecl.modifiers = this.modifiers;
1113 //identifier 'extends' identifier
1114 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1115 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1116 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1117 typeDecl.name = scanner.getCurrentIdentifierSource();
1118 if (token > TokenNameKEYWORD) {
1119 throwSyntaxError("Don't use a keyword for class declaration [" + scanner.toStringAction(token) + "].",
1120 typeDecl.sourceStart, typeDecl.sourceEnd);
1125 // | T_EXTENDS fully_qualified_class_name
1126 if (token == TokenNameextends) {
1127 interface_extends_list();
1129 // if (token != TokenNameIdentifier) {
1130 // throwSyntaxError("Class name expected after keyword
1132 // scanner.getCurrentTokenStartPosition(), scanner
1133 // .getCurrentTokenEndPosition());
1138 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1139 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1140 typeDecl.name = new char[]{' '};
1141 throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
1145 // '{' class_statement_list '}'
1146 if (token == TokenNameLBRACE) {
1148 if (token != TokenNameRBRACE) {
1149 ArrayList list = new ArrayList();
1150 class_statement_list(list);
1151 typeDecl.fields = new FieldDeclaration[list.size()];
1152 for (int i = 0; i < list.size(); i++) {
1153 typeDecl.fields[i] = (FieldDeclaration) list.get(i);
1156 if (token == TokenNameRBRACE) {
1157 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1160 throwSyntaxError("'}' expected at end of class body.");
1163 throwSyntaxError("'{' expected at start of class body.");
1166 private void class_entry_type() {
1168 // | T_ABSTRACT T_CLASS
1169 // | T_FINAL T_CLASS
1170 if (token == TokenNameclass) {
1172 } else if (token == TokenNameabstract) {
1173 checkAndSetModifiers(AccAbstract);
1175 if (token != TokenNameclass) {
1176 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1179 } else if (token == TokenNamefinal) {
1180 checkAndSetModifiers(AccFinal);
1182 if (token != TokenNameclass) {
1183 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1187 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1190 private void interface_extends_list() {
1192 // | T_EXTENDS interface_list
1193 if (token == TokenNameextends) {
1198 private void implements_list() {
1200 // | T_IMPLEMENTS interface_list
1201 if (token == TokenNameimplements) {
1206 private void interface_list() {
1208 // fully_qualified_class_name
1209 //| interface_list ',' fully_qualified_class_name
1211 if (token == TokenNameIdentifier) {
1214 throwSyntaxError("Interface name expected after keyword 'implements'.");
1216 if (token != TokenNameCOMMA) {
1222 // private void classBody(TypeDeclaration typeDecl) {
1223 // //'{' [class-element-list] '}'
1224 // if (token == TokenNameLBRACE) {
1226 // if (token != TokenNameRBRACE) {
1227 // class_statement_list();
1229 // if (token == TokenNameRBRACE) {
1230 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1233 // throwSyntaxError("'}' expected at end of class body.");
1236 // throwSyntaxError("'{' expected at start of class body.");
1239 private void class_statement_list(ArrayList list) {
1241 class_statement(list);
1242 } while (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
1243 || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
1244 || token == TokenNameconst);
1246 private void class_statement(ArrayList list) {
1248 // variable_modifiers class_variable_declaration ';'
1249 // | class_constant_declaration ';'
1250 // | method_modifiers T_FUNCTION is_reference T_STRING
1251 // '(' parameter_list ')' method_body
1252 initializeModifiers();
1253 int declarationSourceStart = scanner.getCurrentTokenStartPosition();
1255 if (token == TokenNamevar) {
1256 checkAndSetModifiers(AccPublic);
1257 problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
1258 referenceContext, compilationUnit.compilationResult);
1260 class_variable_declaration(declarationSourceStart, list);
1261 } else if (token == TokenNameconst) {
1262 checkAndSetModifiers(AccFinal|AccPublic);
1263 class_constant_declaration(declarationSourceStart, list);
1264 if (token != TokenNameSEMICOLON) {
1265 throwSyntaxError("';' expected after class const declaration.");
1269 boolean hasModifiers = member_modifiers();
1270 if (token == TokenNamefunction) {
1271 if (!hasModifiers) {
1272 checkAndSetModifiers(AccPublic);
1274 MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
1275 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
1276 methodDecl.modifiers = this.modifiers;
1278 functionDefinition(methodDecl);
1280 if (!hasModifiers) {
1281 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1283 class_variable_declaration(declarationSourceStart, list);
1287 private void class_constant_declaration(int declarationSourceStart, ArrayList list) {
1288 // class_constant_declaration ',' T_STRING '=' static_scalar
1289 // | T_CONST T_STRING '=' static_scalar
1290 if (token != TokenNameconst) {
1291 throwSyntaxError("'const' keyword expected in class declaration.");
1296 if (token != TokenNameIdentifier) {
1297 throwSyntaxError("Identifier expected in class const declaration.");
1299 FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
1300 .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1301 fieldDeclaration.modifiers = this.modifiers;
1302 fieldDeclaration.declarationSourceStart = declarationSourceStart;
1303 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1304 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1305 // fieldDeclaration.type
1306 list.add(fieldDeclaration);
1308 if (token != TokenNameEQUAL) {
1309 throwSyntaxError("'=' expected in class const declaration.");
1313 if (token != TokenNameCOMMA) {
1314 break; // while(true)-loop
1319 // private void variable_modifiers() {
1320 // // variable_modifiers:
1321 // // non_empty_member_modifiers
1323 // initializeModifiers();
1324 // if (token == TokenNamevar) {
1325 // checkAndSetModifiers(AccPublic);
1326 // reportSyntaxError(
1327 // "Keyword 'var' is deprecated. Please use 'public' 'private' or
1329 // modifier for field declarations.",
1330 // scanner.getCurrentTokenStartPosition(), scanner
1331 // .getCurrentTokenEndPosition());
1334 // if (!member_modifiers()) {
1335 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1336 // field declarations.");
1340 // private void method_modifiers() {
1341 // //method_modifiers:
1343 // //| non_empty_member_modifiers
1344 // initializeModifiers();
1345 // if (!member_modifiers()) {
1346 // checkAndSetModifiers(AccPublic);
1349 private boolean member_modifiers() {
1356 boolean foundToken = false;
1358 if (token == TokenNamepublic) {
1359 checkAndSetModifiers(AccPublic);
1362 } else if (token == TokenNameprotected) {
1363 checkAndSetModifiers(AccProtected);
1366 } else if (token == TokenNameprivate) {
1367 checkAndSetModifiers(AccPrivate);
1370 } else if (token == TokenNamestatic) {
1371 checkAndSetModifiers(AccStatic);
1374 } else if (token == TokenNameabstract) {
1375 checkAndSetModifiers(AccAbstract);
1378 } else if (token == TokenNamefinal) {
1379 checkAndSetModifiers(AccFinal);
1388 private void class_variable_declaration(int declarationSourceStart, ArrayList list) {
1389 // class_variable_declaration:
1390 // class_variable_declaration ',' T_VARIABLE
1391 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1393 // | T_VARIABLE '=' static_scalar
1395 if (token == TokenNameVariable) {
1396 FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
1397 .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
1398 fieldDeclaration.modifiers = this.modifiers;
1399 fieldDeclaration.declarationSourceStart = declarationSourceStart;
1400 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1401 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1402 // fieldDeclaration.type
1403 list.add(fieldDeclaration);
1405 if (token == TokenNameEQUAL) {
1410 // if (token == TokenNamethis) {
1411 // throwSyntaxError("'$this' not allowed after keyword 'public'
1412 // 'protected' 'private' 'var'.");
1414 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1416 if (token != TokenNameCOMMA) {
1421 if (token != TokenNameSEMICOLON) {
1422 throwSyntaxError("';' expected after field declaration.");
1426 private void functionDefinition(MethodDeclaration methodDecl) {
1427 boolean isAbstract = false;
1429 compilationUnit.types.add(methodDecl);
1431 AstNode node = astStack[astPtr];
1432 if (node instanceof TypeDeclaration) {
1433 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1434 if (typeDecl.methods == null) {
1435 typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1437 AbstractMethodDeclaration[] newMethods;
1438 System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1,
1439 typeDecl.methods.length);
1440 newMethods[0] = methodDecl;
1441 typeDecl.methods = newMethods;
1443 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1445 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1450 functionDeclarator(methodDecl);
1451 if (token == TokenNameSEMICOLON) {
1453 throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
1458 functionBody(methodDecl);
1460 private void functionDeclarator(MethodDeclaration methodDecl) {
1461 //identifier '(' [parameter-list] ')'
1462 if (token == TokenNameAND) {
1465 if (token == TokenNameIdentifier) {
1466 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1467 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1468 methodDecl.selector = scanner.getCurrentIdentifierSource();
1470 if (token == TokenNameLPAREN) {
1473 throwSyntaxError("'(' expected in function declaration.");
1475 if (token != TokenNameRPAREN) {
1478 if (token != TokenNameRPAREN) {
1479 throwSyntaxError("')' expected in function declaration.");
1481 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1485 if (token > TokenNameKEYWORD) {
1486 throwSyntaxError("Don't use keyword for function declaration [" + token + "].");
1488 throwSyntaxError("Function name expected after keyword 'function'.");
1492 private void parameter_list() {
1493 // non_empty_parameter_list
1495 non_empty_parameter_list(true);
1497 private void non_empty_parameter_list(boolean empty_allowed) {
1498 // optional_class_type T_VARIABLE
1499 // | optional_class_type '&' T_VARIABLE
1500 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1501 // | optional_class_type T_VARIABLE '=' static_scalar
1502 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1503 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1504 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1506 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1508 if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
1510 if (token == TokenNameIdentifier) {
1513 if (token == TokenNameAND) {
1516 if (token == TokenNameVariable) {
1518 if (token == TokenNameEQUAL) {
1523 throwSyntaxError("Variable expected in parameter list.");
1525 if (token != TokenNameCOMMA) {
1532 if (!empty_allowed) {
1533 throwSyntaxError("Identifier expected in parameter list.");
1536 private void optional_class_type() {
1540 private void parameterDeclaration() {
1542 //variable-reference
1543 if (token == TokenNameAND) {
1548 throwSyntaxError("Variable expected after reference operator '&'.");
1551 //variable '=' constant
1552 if (token == TokenNameVariable) {
1554 if (token == TokenNameEQUAL) {
1560 // if (token == TokenNamethis) {
1561 // throwSyntaxError("Reserved word '$this' not allowed in parameter
1565 private void labeledStatementList() {
1566 if (token != TokenNamecase && token != TokenNamedefault) {
1567 throwSyntaxError("'case' or 'default' expected.");
1570 if (token == TokenNamecase) {
1572 expr(); //constant();
1573 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1575 if (token == TokenNamecase || token == TokenNamedefault) {
1576 // empty case statement ?
1581 // else if (token == TokenNameSEMICOLON) {
1583 // "':' expected after 'case' keyword (Found token: " +
1584 // scanner.toStringAction(token) + ")",
1585 // scanner.getCurrentTokenStartPosition(),
1586 // scanner.getCurrentTokenEndPosition(),
1589 // if (token == TokenNamecase) { // empty case statement ?
1595 throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")");
1597 } else { // TokenNamedefault
1599 if (token == TokenNameCOLON) {
1601 if (token == TokenNameRBRACE) {
1602 // empty default case
1607 throwSyntaxError("':' character after 'default' expected.");
1610 } while (token == TokenNamecase || token == TokenNamedefault);
1612 // public void labeledStatement() {
1613 // if (token == TokenNamecase) {
1616 // if (token == TokenNameDDOT) {
1620 // throwSyntaxError("':' character after 'case' constant expected.");
1623 // } else if (token == TokenNamedefault) {
1625 // if (token == TokenNameDDOT) {
1629 // throwSyntaxError("':' character after 'default' expected.");
1634 // public void expressionStatement() {
1636 // private void inclusionStatement() {
1638 // public void compoundStatement() {
1640 // public void selectionStatement() {
1643 // public void iterationStatement() {
1646 // public void jumpStatement() {
1649 // public void outputStatement() {
1652 // public void scopeStatement() {
1655 // public void flowStatement() {
1658 // public void definitionStatement() {
1660 private void ifStatement() {
1661 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1662 if (token == TokenNameCOLON) {
1664 if (token != TokenNameendif) {
1667 case TokenNameelse :
1669 if (token == TokenNameCOLON) {
1671 if (token != TokenNameendif) {
1675 if (token == TokenNameif) { //'else if'
1677 elseifStatementList();
1679 throwSyntaxError("':' expected after 'else'.");
1683 case TokenNameelseif :
1685 elseifStatementList();
1689 if (token != TokenNameendif) {
1690 throwSyntaxError("'endif' expected.");
1693 if (token != TokenNameSEMICOLON) {
1694 throwSyntaxError("';' expected after if-statement.");
1698 // statement [else-statement]
1699 statement(TokenNameEOF);
1700 if (token == TokenNameelseif) {
1702 if (token == TokenNameLPAREN) {
1705 throwSyntaxError("'(' expected after 'elseif' keyword.");
1708 if (token == TokenNameRPAREN) {
1711 throwSyntaxError("')' expected after 'elseif' condition.");
1714 } else if (token == TokenNameelse) {
1716 statement(TokenNameEOF);
1720 private void elseifStatementList() {
1724 case TokenNameelse :
1726 if (token == TokenNameCOLON) {
1728 if (token != TokenNameendif) {
1733 if (token == TokenNameif) { //'else if'
1736 throwSyntaxError("':' expected after 'else'.");
1740 case TokenNameelseif :
1748 private void elseifStatement() {
1749 if (token == TokenNameLPAREN) {
1752 if (token != TokenNameRPAREN) {
1753 throwSyntaxError("')' expected in else-if-statement.");
1756 if (token != TokenNameCOLON) {
1757 throwSyntaxError("':' expected in else-if-statement.");
1760 if (token != TokenNameendif) {
1765 private void switchStatement() {
1766 if (token == TokenNameCOLON) {
1767 // ':' [labeled-statement-list] 'endswitch' ';'
1769 labeledStatementList();
1770 if (token != TokenNameendswitch) {
1771 throwSyntaxError("'endswitch' expected.");
1774 if (token != TokenNameSEMICOLON) {
1775 throwSyntaxError("';' expected after switch-statement.");
1779 // '{' [labeled-statement-list] '}'
1780 if (token != TokenNameLBRACE) {
1781 throwSyntaxError("'{' expected in switch statement.");
1784 if (token != TokenNameRBRACE) {
1785 labeledStatementList();
1787 if (token != TokenNameRBRACE) {
1788 throwSyntaxError("'}' expected in switch statement.");
1793 private void forStatement() {
1794 if (token == TokenNameCOLON) {
1797 if (token != TokenNameendfor) {
1798 throwSyntaxError("'endfor' expected.");
1801 if (token != TokenNameSEMICOLON) {
1802 throwSyntaxError("';' expected after for-statement.");
1806 statement(TokenNameEOF);
1809 private void whileStatement() {
1810 // ':' statement-list 'endwhile' ';'
1811 if (token == TokenNameCOLON) {
1814 if (token != TokenNameendwhile) {
1815 throwSyntaxError("'endwhile' expected.");
1818 if (token != TokenNameSEMICOLON) {
1819 throwSyntaxError("';' expected after while-statement.");
1823 statement(TokenNameEOF);
1826 private void foreachStatement() {
1827 if (token == TokenNameCOLON) {
1830 if (token != TokenNameendforeach) {
1831 throwSyntaxError("'endforeach' expected.");
1834 if (token != TokenNameSEMICOLON) {
1835 throwSyntaxError("';' expected after foreach-statement.");
1839 statement(TokenNameEOF);
1842 // private void exitStatus() {
1843 // if (token == TokenNameLPAREN) {
1846 // throwSyntaxError("'(' expected in 'exit-status'.");
1848 // if (token != TokenNameRPAREN) {
1851 // if (token == TokenNameRPAREN) {
1854 // throwSyntaxError("')' expected after 'exit-status'.");
1857 private void expressionList() {
1860 if (token == TokenNameCOMMA) {
1867 private void expr() {
1869 // | expr_without_variable
1870 // if (token!=TokenNameEOF) {
1871 if (Scanner.TRACE) {
1872 System.out.println("TRACE: expr()");
1874 expr_without_variable(true);
1877 private void expr_without_variable(boolean only_variable) {
1878 // internal_functions_in_yacc
1887 // | T_INC rw_variable
1888 // | T_DEC rw_variable
1889 // | T_INT_CAST expr
1890 // | T_DOUBLE_CAST expr
1891 // | T_STRING_CAST expr
1892 // | T_ARRAY_CAST expr
1893 // | T_OBJECT_CAST expr
1894 // | T_BOOL_CAST expr
1895 // | T_UNSET_CAST expr
1896 // | T_EXIT exit_expr
1898 // | T_ARRAY '(' array_pair_list ')'
1899 // | '`' encaps_list '`'
1900 // | T_LIST '(' assignment_list ')' '=' expr
1901 // | T_NEW class_name_reference ctor_arguments
1902 // | variable '=' expr
1903 // | variable '=' '&' variable
1904 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
1905 // | variable T_PLUS_EQUAL expr
1906 // | variable T_MINUS_EQUAL expr
1907 // | variable T_MUL_EQUAL expr
1908 // | variable T_DIV_EQUAL expr
1909 // | variable T_CONCAT_EQUAL expr
1910 // | variable T_MOD_EQUAL expr
1911 // | variable T_AND_EQUAL expr
1912 // | variable T_OR_EQUAL expr
1913 // | variable T_XOR_EQUAL expr
1914 // | variable T_SL_EQUAL expr
1915 // | variable T_SR_EQUAL expr
1916 // | rw_variable T_INC
1917 // | rw_variable T_DEC
1918 // | expr T_BOOLEAN_OR expr
1919 // | expr T_BOOLEAN_AND expr
1920 // | expr T_LOGICAL_OR expr
1921 // | expr T_LOGICAL_AND expr
1922 // | expr T_LOGICAL_XOR expr
1934 // | expr T_IS_IDENTICAL expr
1935 // | expr T_IS_NOT_IDENTICAL expr
1936 // | expr T_IS_EQUAL expr
1937 // | expr T_IS_NOT_EQUAL expr
1939 // | expr T_IS_SMALLER_OR_EQUAL expr
1941 // | expr T_IS_GREATER_OR_EQUAL expr
1942 // | expr T_INSTANCEOF class_name_reference
1943 // | expr '?' expr ':' expr
1944 if (Scanner.TRACE) {
1945 System.out.println("TRACE: expr_without_variable() PART 1");
1948 case TokenNameisset :
1949 case TokenNameempty :
1950 case TokenNameeval :
1951 case TokenNameinclude :
1952 case TokenNameinclude_once :
1953 case TokenNamerequire :
1954 case TokenNamerequire_once :
1955 internal_functions_in_yacc();
1958 case TokenNameLPAREN :
1961 if (token == TokenNameRPAREN) {
1964 throwSyntaxError("')' expected in expression.");
1974 // | T_INT_CAST expr
1975 // | T_DOUBLE_CAST expr
1976 // | T_STRING_CAST expr
1977 // | T_ARRAY_CAST expr
1978 // | T_OBJECT_CAST expr
1979 // | T_BOOL_CAST expr
1980 // | T_UNSET_CAST expr
1981 case TokenNameclone :
1982 case TokenNameprint :
1984 case TokenNamePLUS :
1985 case TokenNameMINUS :
1987 case TokenNameTWIDDLE :
1988 case TokenNameintCAST :
1989 case TokenNamedoubleCAST :
1990 case TokenNamestringCAST :
1991 case TokenNamearrayCAST :
1992 case TokenNameobjectCAST :
1993 case TokenNameboolCAST :
1994 case TokenNameunsetCAST :
1998 case TokenNameexit :
2004 //| T_STRING_VARNAME
2006 //| T_START_HEREDOC encaps_list T_END_HEREDOC
2007 // | '`' encaps_list '`'
2009 // | '`' encaps_list '`'
2010 case TokenNameEncapsedString0 :
2011 scanner.encapsedStringStack.push(new Character('`'));
2014 if (token == TokenNameEncapsedString0) {
2017 if (token != TokenNameEncapsedString0) {
2018 throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2022 scanner.encapsedStringStack.pop();
2026 // | '\'' encaps_list '\''
2027 case TokenNameEncapsedString1 :
2028 scanner.encapsedStringStack.push(new Character('\''));
2031 if (token == TokenNameEncapsedString1) {
2034 if (token != TokenNameEncapsedString1) {
2035 throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2039 scanner.encapsedStringStack.pop();
2043 //| '"' encaps_list '"'
2044 case TokenNameEncapsedString2 :
2045 scanner.encapsedStringStack.push(new Character('"'));
2048 if (token == TokenNameEncapsedString2) {
2051 if (token != TokenNameEncapsedString2) {
2052 throwSyntaxError("'\"' expected at end of string" + "(Found token: " + scanner.toStringAction(token) + " )");
2056 scanner.encapsedStringStack.pop();
2060 case TokenNameIntegerLiteral :
2061 case TokenNameDoubleLiteral :
2062 case TokenNameStringDoubleQuote :
2063 case TokenNameStringSingleQuote :
2064 case TokenNameStringInterpolated :
2065 case TokenNameFILE :
2066 case TokenNameLINE :
2067 case TokenNameCLASS_C :
2068 case TokenNameMETHOD_C :
2069 case TokenNameFUNC_C :
2072 case TokenNameHEREDOC :
2075 case TokenNamearray :
2076 // T_ARRAY '(' array_pair_list ')'
2078 if (token == TokenNameLPAREN) {
2080 if (token == TokenNameRPAREN) {
2085 if (token != TokenNameRPAREN) {
2086 throwSyntaxError("')' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2090 throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
2093 case TokenNamelist :
2094 // | T_LIST '(' assignment_list ')' '=' expr
2096 if (token == TokenNameLPAREN) {
2099 if (token != TokenNameRPAREN) {
2100 throwSyntaxError("')' expected after 'list' keyword.");
2103 if (token != TokenNameEQUAL) {
2104 throwSyntaxError("'=' expected after 'list' keyword.");
2109 throwSyntaxError("'(' expected after 'list' keyword.");
2113 // | T_NEW class_name_reference ctor_arguments
2115 class_name_reference();
2118 // | T_INC rw_variable
2119 // | T_DEC rw_variable
2120 case TokenNamePLUS_PLUS :
2121 case TokenNameMINUS_MINUS :
2125 // | variable '=' expr
2126 // | variable '=' '&' variable
2127 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2128 // | variable T_PLUS_EQUAL expr
2129 // | variable T_MINUS_EQUAL expr
2130 // | variable T_MUL_EQUAL expr
2131 // | variable T_DIV_EQUAL expr
2132 // | variable T_CONCAT_EQUAL expr
2133 // | variable T_MOD_EQUAL expr
2134 // | variable T_AND_EQUAL expr
2135 // | variable T_OR_EQUAL expr
2136 // | variable T_XOR_EQUAL expr
2137 // | variable T_SL_EQUAL expr
2138 // | variable T_SR_EQUAL expr
2139 // | rw_variable T_INC
2140 // | rw_variable T_DEC
2141 case TokenNameIdentifier :
2142 case TokenNameVariable :
2143 case TokenNameDOLLAR :
2146 case TokenNameEQUAL :
2148 if (token == TokenNameAND) {
2150 if (token == TokenNamenew) {
2151 // | variable '=' '&' T_NEW class_name_reference
2154 class_name_reference();
2163 case TokenNamePLUS_EQUAL :
2164 case TokenNameMINUS_EQUAL :
2165 case TokenNameMULTIPLY_EQUAL :
2166 case TokenNameDIVIDE_EQUAL :
2167 case TokenNameDOT_EQUAL :
2168 case TokenNameREMAINDER_EQUAL :
2169 case TokenNameAND_EQUAL :
2170 case TokenNameOR_EQUAL :
2171 case TokenNameXOR_EQUAL :
2172 case TokenNameRIGHT_SHIFT_EQUAL :
2173 case TokenNameLEFT_SHIFT_EQUAL :
2177 case TokenNamePLUS_PLUS :
2178 case TokenNameMINUS_MINUS :
2182 if (!only_variable) {
2183 throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "').");
2188 if (token != TokenNameINLINE_HTML) {
2189 if (token > TokenNameKEYWORD) {
2193 throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
2198 if (Scanner.TRACE) {
2199 System.out.println("TRACE: expr_without_variable() PART 2");
2201 // | expr T_BOOLEAN_OR expr
2202 // | expr T_BOOLEAN_AND expr
2203 // | expr T_LOGICAL_OR expr
2204 // | expr T_LOGICAL_AND expr
2205 // | expr T_LOGICAL_XOR expr
2217 // | expr T_IS_IDENTICAL expr
2218 // | expr T_IS_NOT_IDENTICAL expr
2219 // | expr T_IS_EQUAL expr
2220 // | expr T_IS_NOT_EQUAL expr
2222 // | expr T_IS_SMALLER_OR_EQUAL expr
2224 // | expr T_IS_GREATER_OR_EQUAL expr
2227 case TokenNameOR_OR :
2228 case TokenNameAND_AND :
2236 case TokenNamePLUS :
2237 case TokenNameMINUS :
2238 case TokenNameMULTIPLY :
2239 case TokenNameDIVIDE :
2240 case TokenNameREMAINDER :
2241 case TokenNameLEFT_SHIFT :
2242 case TokenNameRIGHT_SHIFT :
2243 case TokenNameEQUAL_EQUAL_EQUAL :
2244 case TokenNameNOT_EQUAL_EQUAL :
2245 case TokenNameEQUAL_EQUAL :
2246 case TokenNameNOT_EQUAL :
2247 case TokenNameLESS :
2248 case TokenNameLESS_EQUAL :
2249 case TokenNameGREATER :
2250 case TokenNameGREATER_EQUAL :
2254 // | expr T_INSTANCEOF class_name_reference
2255 // | expr '?' expr ':' expr
2256 case TokenNameinstanceof :
2258 class_name_reference();
2260 case TokenNameQUESTION :
2263 if (token == TokenNameCOLON) {
2273 private void class_name_reference() {
2274 // class_name_reference:
2276 //| dynamic_class_name_reference
2277 if (Scanner.TRACE) {
2278 System.out.println("TRACE: class_name_reference()");
2280 if (token == TokenNameIdentifier) {
2283 dynamic_class_name_reference();
2286 private void dynamic_class_name_reference() {
2287 //dynamic_class_name_reference:
2288 // base_variable T_OBJECT_OPERATOR object_property
2289 // dynamic_class_name_variable_properties
2291 if (Scanner.TRACE) {
2292 System.out.println("TRACE: dynamic_class_name_reference()");
2295 if (token == TokenNameMINUS_GREATER) {
2298 dynamic_class_name_variable_properties();
2301 private void dynamic_class_name_variable_properties() {
2302 // dynamic_class_name_variable_properties:
2303 // dynamic_class_name_variable_properties
2304 // dynamic_class_name_variable_property
2306 if (Scanner.TRACE) {
2307 System.out.println("TRACE: dynamic_class_name_variable_properties()");
2309 while (token == TokenNameMINUS_GREATER) {
2310 dynamic_class_name_variable_property();
2313 private void dynamic_class_name_variable_property() {
2314 // dynamic_class_name_variable_property:
2315 // T_OBJECT_OPERATOR object_property
2316 if (Scanner.TRACE) {
2317 System.out.println("TRACE: dynamic_class_name_variable_property()");
2319 if (token == TokenNameMINUS_GREATER) {
2324 private void ctor_arguments() {
2327 //| '(' function_call_parameter_list ')'
2328 if (token == TokenNameLPAREN) {
2330 if (token == TokenNameRPAREN) {
2334 non_empty_function_call_parameter_list();
2335 if (token != TokenNameRPAREN) {
2336 throwSyntaxError("')' expected in ctor_arguments.");
2341 private void assignment_list() {
2343 // assignment_list ',' assignment_list_element
2344 //| assignment_list_element
2346 assignment_list_element();
2347 if (token != TokenNameCOMMA) {
2353 private void assignment_list_element() {
2354 //assignment_list_element:
2356 //| T_LIST '(' assignment_list ')'
2358 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2361 if (token == TokenNamelist) {
2363 if (token == TokenNameLPAREN) {
2366 if (token != TokenNameRPAREN) {
2367 throwSyntaxError("')' expected after 'list' keyword.");
2371 throwSyntaxError("'(' expected after 'list' keyword.");
2376 private void array_pair_list() {
2379 //| non_empty_array_pair_list possible_comma
2380 non_empty_array_pair_list();
2381 if (token == TokenNameCOMMA) {
2385 private void non_empty_array_pair_list() {
2386 //non_empty_array_pair_list:
2387 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2388 //| non_empty_array_pair_list ',' expr
2389 //| expr T_DOUBLE_ARROW expr
2391 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2392 //| non_empty_array_pair_list ',' '&' w_variable
2393 //| expr T_DOUBLE_ARROW '&' w_variable
2396 if (token == TokenNameAND) {
2401 if (token == TokenNameAND) {
2404 } else if (token == TokenNameEQUAL_GREATER) {
2406 if (token == TokenNameAND) {
2414 if (token != TokenNameCOMMA) {
2418 if (token == TokenNameRPAREN) {
2423 // private void variableList() {
2426 // if (token == TokenNameCOMMA) {
2433 private void variable_without_objects() {
2434 // variable_without_objects:
2435 // reference_variable
2436 // | simple_indirect_reference reference_variable
2437 if (Scanner.TRACE) {
2438 System.out.println("TRACE: variable_without_objects()");
2440 while (token == TokenNameDOLLAR) {
2443 reference_variable();
2445 private void function_call() {
2447 // T_STRING '(' function_call_parameter_list ')'
2448 //| class_constant '(' function_call_parameter_list ')'
2449 //| static_member '(' function_call_parameter_list ')'
2450 //| variable_without_objects '(' function_call_parameter_list ')'
2451 if (Scanner.TRACE) {
2452 System.out.println("TRACE: function_call()");
2454 if (token == TokenNameIdentifier) {
2457 case TokenNamePAAMAYIM_NEKUDOTAYIM :
2460 if (token == TokenNameIdentifier) {
2465 variable_without_objects();
2470 variable_without_objects();
2472 if (token != TokenNameLPAREN) {
2473 // TODO is this ok ?
2475 // throwSyntaxError("'(' expected in function call.");
2478 if (token == TokenNameRPAREN) {
2482 non_empty_function_call_parameter_list();
2483 if (token != TokenNameRPAREN) {
2484 throwSyntaxError("')' expected in function call.");
2488 // private void function_call_parameter_list() {
2489 // function_call_parameter_list:
2490 // non_empty_function_call_parameter_list { $$ = $1; }
2493 private void non_empty_function_call_parameter_list() {
2494 //non_empty_function_call_parameter_list:
2495 // expr_without_variable
2498 // | non_empty_function_call_parameter_list ',' expr_without_variable
2499 // | non_empty_function_call_parameter_list ',' variable
2500 // | non_empty_function_call_parameter_list ',' '&' w_variable
2501 if (Scanner.TRACE) {
2502 System.out.println("TRACE: non_empty_function_call_parameter_list()");
2505 if (token == TokenNameAND) {
2509 // if (token == TokenNameIdentifier || token ==
2510 // TokenNameVariable
2511 // || token == TokenNameDOLLAR) {
2514 expr_without_variable(true);
2517 if (token != TokenNameCOMMA) {
2523 private void fully_qualified_class_name() {
2524 if (token == TokenNameIdentifier) {
2527 throwSyntaxError("Class name expected.");
2530 private void static_member() {
2532 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2533 // variable_without_objects
2534 if (Scanner.TRACE) {
2535 System.out.println("TRACE: static_member()");
2537 fully_qualified_class_name();
2538 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2539 throwSyntaxError("'::' expected after class name (static_member).");
2542 variable_without_objects();
2544 private void base_variable_with_function_calls() {
2545 // base_variable_with_function_calls:
2548 boolean functionCall = false;
2549 if (Scanner.TRACE) {
2550 System.out.println("TRACE: base_variable_with_function_calls()");
2552 // if (token == TokenNameIdentifier) {
2553 // functionCall = true;
2554 // } else if (token == TokenNameVariable) {
2555 // int tempToken = token;
2556 // int tempPosition = scanner.currentPosition;
2558 // if (token == TokenNameLPAREN) {
2559 // functionCall = true;
2561 // token = tempToken;
2562 // scanner.currentPosition = tempPosition;
2563 // scanner.phpMode = true;
2565 // if (functionCall) {
2571 private void base_variable() {
2573 // reference_variable
2574 // | simple_indirect_reference reference_variable
2576 if (Scanner.TRACE) {
2577 System.out.println("TRACE: base_variable()");
2579 if (token == TokenNameIdentifier) {
2582 while (token == TokenNameDOLLAR) {
2585 reference_variable();
2588 // private void simple_indirect_reference() {
2589 // // simple_indirect_reference:
2591 // //| simple_indirect_reference '$'
2593 private void reference_variable() {
2594 // reference_variable:
2595 // reference_variable '[' dim_offset ']'
2596 // | reference_variable '{' expr '}'
2597 // | compound_variable
2598 if (Scanner.TRACE) {
2599 System.out.println("TRACE: reference_variable()");
2601 compound_variable();
2603 if (token == TokenNameLBRACE) {
2606 if (token != TokenNameRBRACE) {
2607 throwSyntaxError("'}' expected in reference variable.");
2610 } else if (token == TokenNameLBRACKET) {
2612 if (token != TokenNameRBRACKET) {
2615 if (token != TokenNameRBRACKET) {
2616 throwSyntaxError("']' expected in reference variable.");
2625 private void compound_variable() {
2626 // compound_variable:
2628 // | '$' '{' expr '}'
2629 if (Scanner.TRACE) {
2630 System.out.println("TRACE: compound_variable()");
2632 if (token == TokenNameVariable) {
2635 // because of simple_indirect_reference
2636 while (token == TokenNameDOLLAR) {
2639 if (token != TokenNameLBRACE) {
2640 throwSyntaxError("'{' expected after compound variable token '$'.");
2644 if (token != TokenNameRBRACE) {
2645 throwSyntaxError("'}' expected after compound variable token '$'.");
2650 // private void dim_offset() {
2656 private void object_property() {
2659 //| variable_without_objects
2660 if (Scanner.TRACE) {
2661 System.out.println("TRACE: object_property()");
2663 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2664 variable_without_objects();
2669 private void object_dim_list() {
2671 // object_dim_list '[' dim_offset ']'
2672 //| object_dim_list '{' expr '}'
2674 if (Scanner.TRACE) {
2675 System.out.println("TRACE: object_dim_list()");
2679 if (token == TokenNameLBRACE) {
2682 if (token != TokenNameRBRACE) {
2683 throwSyntaxError("'}' expected in object_dim_list.");
2686 } else if (token == TokenNameLBRACKET) {
2688 if (token == TokenNameRBRACKET) {
2693 if (token != TokenNameRBRACKET) {
2694 throwSyntaxError("']' expected in object_dim_list.");
2702 private void variable_name() {
2706 if (Scanner.TRACE) {
2707 System.out.println("TRACE: variable_name()");
2709 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
2710 if (token > TokenNameKEYWORD) {
2711 // TODO show a warning "Keyword used as variable" ?
2715 if (token != TokenNameLBRACE) {
2716 throwSyntaxError("'{' expected in variable name.");
2720 if (token != TokenNameRBRACE) {
2721 throwSyntaxError("'}' expected in variable name.");
2726 private void r_variable() {
2729 private void w_variable() {
2732 private void rw_variable() {
2735 private void variable() {
2737 // base_variable_with_function_calls T_OBJECT_OPERATOR
2738 // object_property method_or_not variable_properties
2739 // | base_variable_with_function_calls
2740 base_variable_with_function_calls();
2741 if (token == TokenNameMINUS_GREATER) {
2745 variable_properties();
2747 // if (token == TokenNameDOLLAR_LBRACE) {
2751 // if (token != TokenNameRBRACE) {
2752 // throwSyntaxError("'}' expected after indirect variable token '${'.");
2756 // if (token == TokenNameVariable) {
2758 // if (token == TokenNameLBRACKET) {
2761 // if (token != TokenNameRBRACKET) {
2762 // throwSyntaxError("']' expected in variable-list.");
2765 // } else if (token == TokenNameEQUAL) {
2770 // throwSyntaxError("$-variable expected in variable-list.");
2774 private void variable_properties() {
2775 // variable_properties:
2776 // variable_properties variable_property
2778 while (token == TokenNameMINUS_GREATER) {
2779 variable_property();
2782 private void variable_property() {
2783 // variable_property:
2784 // T_OBJECT_OPERATOR object_property method_or_not
2785 if (Scanner.TRACE) {
2786 System.out.println("TRACE: variable_property()");
2788 if (token == TokenNameMINUS_GREATER) {
2793 throwSyntaxError("'->' expected in variable_property.");
2796 private void method_or_not() {
2798 // '(' function_call_parameter_list ')'
2800 if (Scanner.TRACE) {
2801 System.out.println("TRACE: method_or_not()");
2803 if (token == TokenNameLPAREN) {
2805 if (token == TokenNameRPAREN) {
2809 non_empty_function_call_parameter_list();
2810 if (token != TokenNameRPAREN) {
2811 throwSyntaxError("')' expected in method_or_not.");
2816 private void exit_expr() {
2820 if (token != TokenNameLPAREN) {
2824 if (token == TokenNameRPAREN) {
2829 if (token != TokenNameRPAREN) {
2830 throwSyntaxError("')' expected after keyword 'exit'");
2834 private void encaps_list() {
2835 // encaps_list encaps_var
2836 // | encaps_list T_STRING
2837 // | encaps_list T_NUM_STRING
2838 // | encaps_list T_ENCAPSED_AND_WHITESPACE
2839 // | encaps_list T_CHARACTER
2840 // | encaps_list T_BAD_CHARACTER
2841 // | encaps_list '['
2842 // | encaps_list ']'
2843 // | encaps_list '{'
2844 // | encaps_list '}'
2845 // | encaps_list T_OBJECT_OPERATOR
2849 case TokenNameSTRING :
2852 case TokenNameLBRACE :
2853 // scanner.encapsedStringStack.pop();
2856 case TokenNameRBRACE :
2857 // scanner.encapsedStringStack.pop();
2860 case TokenNameLBRACKET :
2861 // scanner.encapsedStringStack.pop();
2864 case TokenNameRBRACKET :
2865 // scanner.encapsedStringStack.pop();
2868 case TokenNameMINUS_GREATER :
2869 // scanner.encapsedStringStack.pop();
2872 case TokenNameVariable :
2873 case TokenNameDOLLAR_LBRACE :
2874 case TokenNameCURLY_OPEN :
2877 // case TokenNameDOLLAR :
2879 // if (token == TokenNameLBRACE) {
2880 // token = TokenNameDOLLAR_LBRACE;
2885 char encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
2886 if (encapsedChar == '$') {
2887 scanner.encapsedStringStack.pop();
2888 encapsedChar = ((Character) scanner.encapsedStringStack.peek()).charValue();
2889 switch (encapsedChar) {
2891 if (token == TokenNameEncapsedString0) {
2894 token = TokenNameSTRING;
2897 if (token == TokenNameEncapsedString1) {
2900 token = TokenNameSTRING;
2903 if (token == TokenNameEncapsedString2) {
2906 token = TokenNameSTRING;
2914 private void encaps_var() {
2916 // | T_VARIABLE '[' encaps_var_offset ']'
2917 // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
2918 // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
2919 // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
2920 // | T_CURLY_OPEN variable '}'
2922 case TokenNameVariable :
2924 if (token == TokenNameLBRACKET) {
2926 // if (token == TokenNameRBRACKET) {
2929 expr(); //encaps_var_offset();
2930 if (token != TokenNameRBRACKET) {
2931 throwSyntaxError("']' expected after variable.");
2933 // scanner.encapsedStringStack.pop();
2936 } else if (token == TokenNameMINUS_GREATER) {
2938 if (token != TokenNameIdentifier) {
2939 throwSyntaxError("Identifier expected after '->'.");
2941 // scanner.encapsedStringStack.pop();
2945 // // scanner.encapsedStringStack.pop();
2946 // int tempToken = TokenNameSTRING;
2947 // if (!scanner.encapsedStringStack.isEmpty()
2948 // && (token == TokenNameEncapsedString0
2949 // || token == TokenNameEncapsedString1
2950 // || token == TokenNameEncapsedString2 || token ==
2951 // TokenNameERROR)) {
2952 // char encapsedChar = ((Character)
2953 // scanner.encapsedStringStack.peek())
2956 // case TokenNameEncapsedString0 :
2957 // if (encapsedChar == '`') {
2958 // tempToken = TokenNameEncapsedString0;
2961 // case TokenNameEncapsedString1 :
2962 // if (encapsedChar == '\'') {
2963 // tempToken = TokenNameEncapsedString1;
2966 // case TokenNameEncapsedString2 :
2967 // if (encapsedChar == '"') {
2968 // tempToken = TokenNameEncapsedString2;
2971 // case TokenNameERROR :
2972 // if (scanner.source[scanner.currentPosition - 1] == '\\') {
2973 // scanner.currentPosition--;
2979 // token = tempToken;
2982 case TokenNameDOLLAR_LBRACE :
2984 if (token == TokenNameIdentifier) {
2986 if (token == TokenNameLBRACKET) {
2988 // if (token == TokenNameRBRACKET) {
2992 if (token != TokenNameRBRACKET) {
2993 throwSyntaxError("']' expected after '${'.");
2998 if (token != TokenNameRBRACE) {
2999 throwSyntaxError("'}' expected after '${'.");
3001 // scanner.encapsedStringStack.pop();
3005 if (token != TokenNameRBRACE) {
3006 throwSyntaxError("'}' expected.");
3008 // scanner.encapsedStringStack.pop();
3012 case TokenNameCURLY_OPEN :
3014 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3016 if (token == TokenNameLBRACKET) {
3018 // if (token == TokenNameRBRACKET) {
3022 if (token != TokenNameRBRACKET) {
3023 throwSyntaxError("']' expected after '{$'.");
3027 } else if (token == TokenNameMINUS_GREATER) {
3029 if (token != TokenNameIdentifier) {
3030 throwSyntaxError("String token expected.");
3034 // if (token != TokenNameRBRACE) {
3035 // throwSyntaxError("'}' expected after '{$'.");
3037 // // scanner.encapsedStringStack.pop();
3041 if (token != TokenNameRBRACE) {
3042 throwSyntaxError("'}' expected.");
3044 // scanner.encapsedStringStack.pop();
3050 private void encaps_var_offset() {
3055 case TokenNameSTRING :
3058 case TokenNameIntegerLiteral :
3061 case TokenNameVariable :
3064 case TokenNameIdentifier :
3068 throwSyntaxError("Variable or String token expected.");
3072 private void internal_functions_in_yacc() {
3074 ImportReference impt = null;
3076 case TokenNameisset :
3077 // T_ISSET '(' isset_variables ')'
3079 if (token != TokenNameLPAREN) {
3080 throwSyntaxError("'(' expected after keyword 'isset'");
3084 if (token != TokenNameRPAREN) {
3085 throwSyntaxError("')' expected after keyword 'isset'");
3089 case TokenNameempty :
3090 // T_EMPTY '(' variable ')'
3092 if (token != TokenNameLPAREN) {
3093 throwSyntaxError("'(' expected after keyword 'empty'");
3097 if (token != TokenNameRPAREN) {
3098 throwSyntaxError("')' expected after keyword 'empty'");
3102 case TokenNameinclude :
3104 start = scanner.getCurrentTokenStartPosition();
3108 impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3109 impt.declarationSourceEnd = impt.sourceEnd;
3110 impt.declarationEnd = impt.declarationSourceEnd;
3111 //endPosition is just before the ;
3112 impt.declarationSourceStart = start;
3113 includesList.add(impt);
3115 case TokenNameinclude_once :
3116 // T_INCLUDE_ONCE expr
3117 start = scanner.getCurrentTokenStartPosition();
3120 impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3121 impt.declarationSourceEnd = impt.sourceEnd;
3122 impt.declarationEnd = impt.declarationSourceEnd;
3123 //endPosition is just before the ;
3124 impt.declarationSourceStart = start;
3125 includesList.add(impt);
3127 case TokenNameeval :
3128 // T_EVAL '(' expr ')'
3130 if (token != TokenNameLPAREN) {
3131 throwSyntaxError("'(' expected after keyword 'eval'");
3135 if (token != TokenNameRPAREN) {
3136 throwSyntaxError("')' expected after keyword 'eval'");
3140 case TokenNamerequire :
3142 start = scanner.getCurrentTokenStartPosition();
3145 impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3146 impt.declarationSourceEnd = impt.sourceEnd;
3147 impt.declarationEnd = impt.declarationSourceEnd;
3148 //endPosition is just before the ;
3149 impt.declarationSourceStart = start;
3150 includesList.add(impt);
3152 case TokenNamerequire_once :
3153 // T_REQUIRE_ONCE expr
3154 start = scanner.getCurrentTokenStartPosition();
3157 impt = new ImportReference(scanner.getCurrentTokenSource(start), start, scanner.getCurrentTokenEndPosition(), false);
3158 impt.declarationSourceEnd = impt.sourceEnd;
3159 impt.declarationEnd = impt.declarationSourceEnd;
3160 //endPosition is just before the ;
3161 impt.declarationSourceStart = start;
3162 includesList.add(impt);
3166 private void isset_variables() {
3168 // | isset_variables ','
3169 if (token == TokenNameRPAREN) {
3170 throwSyntaxError("Variable expected after keyword 'isset'");
3174 if (token == TokenNameCOMMA) {
3181 private boolean common_scalar() {
3185 // | T_CONSTANT_ENCAPSED_STRING
3192 case TokenNameIntegerLiteral :
3195 case TokenNameDoubleLiteral :
3198 case TokenNameStringDoubleQuote :
3201 case TokenNameStringSingleQuote :
3204 case TokenNameStringInterpolated :
3207 case TokenNameFILE :
3210 case TokenNameLINE :
3213 case TokenNameCLASS_C :
3216 case TokenNameMETHOD_C :
3219 case TokenNameFUNC_C :
3225 private void scalar() {
3228 //| T_STRING_VARNAME
3231 //| '"' encaps_list '"'
3232 //| '\'' encaps_list '\''
3233 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3234 throwSyntaxError("Not yet implemented (scalar).");
3236 private void static_scalar() {
3237 // static_scalar: /* compile-time evaluated scalars */
3240 // | '+' static_scalar
3241 // | '-' static_scalar
3242 // | T_ARRAY '(' static_array_pair_list ')'
3243 // | static_class_constant
3244 if (common_scalar()) {
3248 case TokenNameIdentifier :
3250 // static_class_constant:
3251 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3252 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3254 if (token == TokenNameIdentifier) {
3257 throwSyntaxError("Identifier expected after '::' operator.");
3261 case TokenNameEncapsedString0 :
3263 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3264 while (scanner.currentCharacter != '`') {
3265 if (scanner.currentCharacter == '\\') {
3266 scanner.currentPosition++;
3268 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3271 } catch (IndexOutOfBoundsException e) {
3272 throwSyntaxError("'`' expected at end of static string.");
3275 case TokenNameEncapsedString1 :
3277 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3278 while (scanner.currentCharacter != '\'') {
3279 if (scanner.currentCharacter == '\\') {
3280 scanner.currentPosition++;
3282 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3285 } catch (IndexOutOfBoundsException e) {
3286 throwSyntaxError("'\'' expected at end of static string.");
3289 case TokenNameEncapsedString2 :
3291 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3292 while (scanner.currentCharacter != '"') {
3293 if (scanner.currentCharacter == '\\') {
3294 scanner.currentPosition++;
3296 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3299 } catch (IndexOutOfBoundsException e) {
3300 throwSyntaxError("'\"' expected at end of static string.");
3303 case TokenNamePLUS :
3307 case TokenNameMINUS :
3311 case TokenNamearray :
3313 if (token != TokenNameLPAREN) {
3314 throwSyntaxError("'(' expected after keyword 'array'");
3317 if (token == TokenNameRPAREN) {
3321 non_empty_static_array_pair_list();
3322 if (token != TokenNameRPAREN) {
3323 throwSyntaxError("')' expected after keyword 'array'");
3327 // case TokenNamenull :
3330 // case TokenNamefalse :
3333 // case TokenNametrue :
3337 throwSyntaxError("Static scalar/constant expected.");
3340 private void non_empty_static_array_pair_list() {
3341 // non_empty_static_array_pair_list:
3342 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3344 //| non_empty_static_array_pair_list ',' static_scalar
3345 //| static_scalar T_DOUBLE_ARROW static_scalar
3349 if (token == TokenNameEQUAL_GREATER) {
3353 if (token != TokenNameCOMMA) {
3357 if (token == TokenNameRPAREN) {
3362 public void reportSyntaxError() { //int act, int currentKind, int
3364 /* remember current scanner position */
3365 int startPos = scanner.startPosition;
3366 int currentPos = scanner.currentPosition;
3367 // String[] expectings;
3368 // String tokenName = name[symbol_index[currentKind]];
3369 //fetch all "accurate" possible terminals that could recover the error
3370 // int start, end = start = asi(stack[stateStackTop]);
3371 // while (asr[end] != 0)
3373 // int length = end - start;
3374 // expectings = new String[length];
3375 // if (length != 0) {
3376 // char[] indexes = new char[length];
3377 // System.arraycopy(asr, start, indexes, 0, length);
3378 // for (int i = 0; i < length; i++) {
3379 // expectings[i] = name[symbol_index[indexes[i]]];
3382 //if the pb is an EOF, try to tell the user that they are some
3383 // if (tokenName.equals(UNEXPECTED_EOF)) {
3384 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3385 // char[] tokenSource;
3387 // tokenSource = this.scanner.getCurrentTokenSource();
3388 // } catch (Exception e) {
3389 // tokenSource = new char[] {};
3391 // problemReporter().parseError(
3392 // this.scanner.startPosition,
3393 // this.scanner.currentPosition - 1,
3398 // } else { //the next test is HEAVILY grammar DEPENDENT.
3399 // if ((length == 14)
3400 // && (expectings[0] == "=") //$NON-NLS-1$
3401 // && (expectings[1] == "*=") //$NON-NLS-1$
3402 // && (expressionPtr > -1)) {
3403 // switch(currentKind) {
3404 // case TokenNameSEMICOLON:
3405 // case TokenNamePLUS:
3406 // case TokenNameMINUS:
3407 // case TokenNameDIVIDE:
3408 // case TokenNameREMAINDER:
3409 // case TokenNameMULTIPLY:
3410 // case TokenNameLEFT_SHIFT:
3411 // case TokenNameRIGHT_SHIFT:
3412 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3413 // case TokenNameLESS:
3414 // case TokenNameGREATER:
3415 // case TokenNameLESS_EQUAL:
3416 // case TokenNameGREATER_EQUAL:
3417 // case TokenNameEQUAL_EQUAL:
3418 // case TokenNameNOT_EQUAL:
3419 // case TokenNameXOR:
3420 // case TokenNameAND:
3421 // case TokenNameOR:
3422 // case TokenNameOR_OR:
3423 // case TokenNameAND_AND:
3424 // // the ; is not the expected token ==> it ends a statement when an
3425 // expression is not ended
3426 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3428 // case TokenNameRBRACE :
3429 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3432 // char[] tokenSource;
3434 // tokenSource = this.scanner.getCurrentTokenSource();
3435 // } catch (Exception e) {
3436 // tokenSource = new char[] {};
3438 // problemReporter().parseError(
3439 // this.scanner.startPosition,
3440 // this.scanner.currentPosition - 1,
3444 // this.checkAndReportBracketAnomalies(problemReporter());
3449 tokenSource = this.scanner.getCurrentTokenSource();
3450 } catch (Exception e) {
3451 tokenSource = new char[]{};
3453 // problemReporter().parseError(
3454 // this.scanner.startPosition,
3455 // this.scanner.currentPosition - 1,
3459 this.checkAndReportBracketAnomalies(problemReporter());
3462 /* reset scanner where it was */
3463 scanner.startPosition = startPos;
3464 scanner.currentPosition = currentPos;
3466 public static final int RoundBracket = 0;
3467 public static final int SquareBracket = 1;
3468 public static final int CurlyBracket = 2;
3469 public static final int BracketKinds = 3;
3470 protected int[] nestedMethod; //the ptr is nestedType
3471 protected int nestedType, dimensions;
3473 final static int AstStackIncrement = 100;
3474 protected int astPtr;
3475 protected AstNode[] astStack = new AstNode[AstStackIncrement];
3476 protected int astLengthPtr;
3477 protected int[] astLengthStack;
3478 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3479 public CompilationUnitDeclaration compilationUnit; /*
3480 * the result from parse()
3482 protected ReferenceContext referenceContext;
3483 protected ProblemReporter problemReporter;
3484 protected CompilerOptions options;
3485 private ArrayList includesList;
3486 // protected CompilationResult compilationResult;
3488 * Returns this parser's problem reporter initialized with its reference
3489 * context. Also it is assumed that a problem is going to be reported, so
3490 * initializes the compilation result's line positions.
3492 public ProblemReporter problemReporter() {
3493 if (scanner.recordLineSeparator) {
3494 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
3496 problemReporter.referenceContext = referenceContext;
3497 return problemReporter;
3500 * Reconsider the entire source looking for inconsistencies in {} () []
3502 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
3503 scanner.wasAcr = false;
3504 boolean anomaliesDetected = false;
3506 char[] source = scanner.source;
3507 int[] leftCount = {0, 0, 0};
3508 int[] rightCount = {0, 0, 0};
3509 int[] depths = {0, 0, 0};
3510 int[][] leftPositions = new int[][]{new int[10], new int[10], new int[10]};
3511 int[][] leftDepths = new int[][]{new int[10], new int[10], new int[10]};
3512 int[][] rightPositions = new int[][]{new int[10], new int[10], new int[10]};
3513 int[][] rightDepths = new int[][]{new int[10], new int[10], new int[10]};
3514 scanner.currentPosition = scanner.initialPosition; //starting
3516 // (first-zero-based
3518 while (scanner.currentPosition < scanner.eofPosition) { //loop for
3523 // ---------Consume white space and handles
3524 // startPosition---------
3525 boolean isWhiteSpace;
3527 scanner.startPosition = scanner.currentPosition;
3528 // if (((scanner.currentCharacter =
3529 // source[scanner.currentPosition++]) == '\\') &&
3530 // (source[scanner.currentPosition] == 'u')) {
3531 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3533 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3534 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3535 // only record line positions we have not
3537 scanner.pushLineSeparator();
3540 isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
3542 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
3543 // -------consume token until } is found---------
3544 switch (scanner.currentCharacter) {
3546 int index = leftCount[CurlyBracket]++;
3547 if (index == leftPositions[CurlyBracket].length) {
3548 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
3549 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
3551 leftPositions[CurlyBracket][index] = scanner.startPosition;
3552 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3556 int index = rightCount[CurlyBracket]++;
3557 if (index == rightPositions[CurlyBracket].length) {
3558 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
3559 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
3561 rightPositions[CurlyBracket][index] = scanner.startPosition;
3562 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3566 int index = leftCount[RoundBracket]++;
3567 if (index == leftPositions[RoundBracket].length) {
3568 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
3569 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
3571 leftPositions[RoundBracket][index] = scanner.startPosition;
3572 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3576 int index = rightCount[RoundBracket]++;
3577 if (index == rightPositions[RoundBracket].length) {
3578 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
3579 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
3581 rightPositions[RoundBracket][index] = scanner.startPosition;
3582 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3586 int index = leftCount[SquareBracket]++;
3587 if (index == leftPositions[SquareBracket].length) {
3588 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
3589 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
3591 leftPositions[SquareBracket][index] = scanner.startPosition;
3592 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3596 int index = rightCount[SquareBracket]++;
3597 if (index == rightPositions[SquareBracket].length) {
3598 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
3599 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
3601 rightPositions[SquareBracket][index] = scanner.startPosition;
3602 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3606 if (scanner.getNextChar('\\')) {
3607 scanner.scanEscapeCharacter();
3608 } else { // consume next character
3609 scanner.unicodeAsBackSlash = false;
3610 // if (((scanner.currentCharacter =
3611 // source[scanner.currentPosition++]) ==
3613 // (source[scanner.currentPosition] ==
3615 // scanner.getNextUnicodeChar();
3617 if (scanner.withoutUnicodePtr != 0) {
3618 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3622 scanner.getNextChar('\'');
3626 // consume next character
3627 scanner.unicodeAsBackSlash = false;
3628 // if (((scanner.currentCharacter =
3629 // source[scanner.currentPosition++]) == '\\') &&
3630 // (source[scanner.currentPosition] == 'u')) {
3631 // scanner.getNextUnicodeChar();
3633 if (scanner.withoutUnicodePtr != 0) {
3634 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3637 while (scanner.currentCharacter != '"') {
3638 if (scanner.currentCharacter == '\r') {
3639 if (source[scanner.currentPosition] == '\n')
3640 scanner.currentPosition++;
3641 break; // the string cannot go further that
3644 if (scanner.currentCharacter == '\n') {
3645 break; // the string cannot go further that
3648 if (scanner.currentCharacter == '\\') {
3649 scanner.scanEscapeCharacter();
3651 // consume next character
3652 scanner.unicodeAsBackSlash = false;
3653 // if (((scanner.currentCharacter =
3654 // source[scanner.currentPosition++]) == '\\')
3655 // && (source[scanner.currentPosition] == 'u'))
3657 // scanner.getNextUnicodeChar();
3659 if (scanner.withoutUnicodePtr != 0) {
3660 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3667 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3670 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3671 && (source[scanner.currentPosition] == 'u')) {
3672 //-------------unicode traitement
3674 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3675 scanner.currentPosition++;
3676 while (source[scanner.currentPosition] == 'u') {
3677 scanner.currentPosition++;
3679 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3680 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3681 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3682 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3686 scanner.currentCharacter = 'A';
3687 } //something different from \n and \r
3689 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3692 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
3694 scanner.startPosition = scanner.currentPosition;
3695 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3696 && (source[scanner.currentPosition] == 'u')) {
3697 //-------------unicode traitement
3699 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3700 scanner.currentPosition++;
3701 while (source[scanner.currentPosition] == 'u') {
3702 scanner.currentPosition++;
3704 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3705 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3706 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3707 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3711 scanner.currentCharacter = 'A';
3712 } //something different from \n
3715 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3719 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3720 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3721 // only record line positions we
3722 // have not recorded yet
3723 scanner.pushLineSeparator();
3724 if (this.scanner.taskTags != null) {
3725 this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner
3726 .getCurrentTokenEndPosition());
3732 if (test > 0) { //traditional and annotation
3734 boolean star = false;
3735 // consume next character
3736 scanner.unicodeAsBackSlash = false;
3737 // if (((scanner.currentCharacter =
3738 // source[scanner.currentPosition++]) ==
3740 // (source[scanner.currentPosition] ==
3742 // scanner.getNextUnicodeChar();
3744 if (scanner.withoutUnicodePtr != 0) {
3745 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3748 if (scanner.currentCharacter == '*') {
3752 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3753 && (source[scanner.currentPosition] == 'u')) {
3754 //-------------unicode traitement
3756 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3757 scanner.currentPosition++;
3758 while (source[scanner.currentPosition] == 'u') {
3759 scanner.currentPosition++;
3761 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3762 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3763 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3764 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3768 scanner.currentCharacter = 'A';
3769 } //something different from * and /
3771 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3774 //loop until end of comment */
3775 while ((scanner.currentCharacter != '/') || (!star)) {
3776 star = scanner.currentCharacter == '*';
3778 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3779 && (source[scanner.currentPosition] == 'u')) {
3780 //-------------unicode traitement
3782 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3783 scanner.currentPosition++;
3784 while (source[scanner.currentPosition] == 'u') {
3785 scanner.currentPosition++;
3787 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0
3788 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0
3789 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0
3790 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error
3794 scanner.currentCharacter = 'A';
3795 } //something different from * and
3798 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3802 if (this.scanner.taskTags != null) {
3803 this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
3810 if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
3811 scanner.scanIdentifierOrKeyword(false);
3814 if (Character.isDigit(scanner.currentCharacter)) {
3815 scanner.scanNumber(false);
3819 //-----------------end switch while
3820 // try--------------------
3821 } catch (IndexOutOfBoundsException e) {
3822 break; // read until EOF
3823 } catch (InvalidInputException e) {
3824 return false; // no clue
3827 if (scanner.recordLineSeparator) {
3828 // compilationUnit.compilationResult.lineSeparatorPositions =
3829 // scanner.getLineEnds();
3831 // check placement anomalies against other kinds of brackets
3832 for (int kind = 0; kind < BracketKinds; kind++) {
3833 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3834 int start = leftPositions[kind][leftIndex]; // deepest
3836 // find matching closing bracket
3837 int depth = leftDepths[kind][leftIndex];
3839 for (int i = 0; i < rightCount[kind]; i++) {
3840 int pos = rightPositions[kind][i];
3841 // want matching bracket further in source with same
3843 if ((pos > start) && (depth == rightDepths[kind][i])) {
3848 if (end < 0) { // did not find a good closing match
3849 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
3852 // check if even number of opening/closing other brackets
3853 // in between this pair of brackets
3855 for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); otherKind++) {
3856 for (int i = 0; i < leftCount[otherKind]; i++) {
3857 int pos = leftPositions[otherKind][i];
3858 if ((pos > start) && (pos < end))
3861 for (int i = 0; i < rightCount[otherKind]; i++) {
3862 int pos = rightPositions[otherKind][i];
3863 if ((pos > start) && (pos < end))
3867 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket
3873 // too many opening brackets ?
3874 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
3875 anomaliesDetected = true;
3876 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext,
3877 compilationUnit.compilationResult);
3879 // too many closing brackets ?
3880 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
3881 anomaliesDetected = true;
3882 problemReporter.unmatchedBracket(rightPositions[kind][i], 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;
3930 protected void resetModifiers() {
3931 this.modifiers = AccDefault;
3932 this.modifiersSourceStart = -1; // <-- see comment into
3933 // modifiersFlag(int)
3934 this.scanner.commentPtr = -1;