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.internal.compiler.ast.AbstractMethodDeclaration;
23 import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
24 import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
25 import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
26 import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference;
27 import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
28 import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
29 import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
31 import org.eclipse.core.resources.IFile;
32 public class Parser //extends PHPParserSuperclass
33 implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
34 //internal data for the automat
35 protected final static int StackIncrement = 255;
36 protected int stateStackTop;
37 protected int[] stack = new int[StackIncrement];
38 public int firstToken; // handle for multiple parsing goals
39 public int lastAct; //handle for multiple parsing goals
40 protected RecoveredElement currentElement;
41 public static boolean VERBOSE_RECOVERY = false;
42 protected boolean diet = false; //tells the scanner to jump over some
43 // parts of the code/expressions like
46 public Scanner scanner;
47 private ArrayList phpList;
48 private int currentPHPString;
49 private boolean phpEnd;
50 // private static HashMap keywordMap = null;
56 // row counter for syntax errors:
58 // column counter for syntax errors:
62 // // current identifier
66 private String stringValue;
67 /** Contains the current expression. */
68 // private StringBuffer expression;
69 //private boolean phpMode;
70 protected int modifiers;
71 protected int modifiersSourceStart;
72 protected Parser(ProblemReporter problemReporter) {
73 this.problemReporter = problemReporter;
74 this.options = problemReporter.options;
75 this.currentPHPString = 0;
76 // PHPParserSuperclass.fileToParse = fileToParse;
79 this.token = TokenNameEOF;
82 // this.columnCount = 0;
85 this.initializeScanner();
87 public void setFileToParse(IFile fileToParse) {
88 this.currentPHPString = 0;
89 // PHPParserSuperclass.fileToParse = fileToParse;
92 this.token = TokenNameEOF;
94 this.initializeScanner();
97 * ClassDeclaration Constructor.
101 * Description of Parameter
104 public Parser(IFile fileToParse) {
105 // if (keywordMap == null) {
106 // keywordMap = new HashMap();
107 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
108 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
111 this.currentPHPString = 0;
112 // PHPParserSuperclass.fileToParse = fileToParse;
115 this.token = TokenNameEOF;
117 // this.rowCount = 1;
118 // this.columnCount = 0;
121 this.initializeScanner();
123 public void initializeScanner() {
124 this.scanner = new Scanner(
126 false /* whitespace */,
127 this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */,
128 false, false, this.options.taskTags/* taskTags */,
129 this.options.taskPriorites/* taskPriorities */);
132 * Create marker for the parse error
134 // private void setMarker(String message, int charStart, int charEnd, int
136 // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
139 * This method will throw the SyntaxError. It will add the good lines and
140 * columns to the Error
144 * @throws SyntaxError
147 private void throwSyntaxError(String error) {
148 int problemStartPosition = scanner.getCurrentTokenStartPosition();
149 int problemEndPosition = scanner.getCurrentTokenEndPosition();
150 throwSyntaxError(error, problemStartPosition, problemEndPosition + 1);
153 * This method will throw the SyntaxError. It will add the good lines and
154 * columns to the Error
158 * @throws SyntaxError
161 // private void throwSyntaxError(String error, int startRow) {
162 // throw new SyntaxError(startRow, 0, " ", error);
164 private void throwSyntaxError(String error, int problemStartPosition,
165 int problemEndPosition) {
166 problemReporter.phpParsingError(new String[]{error},
167 problemStartPosition, problemEndPosition, referenceContext,
168 compilationUnit.compilationResult);
169 throw new SyntaxError(1, 0, " ", error);
171 private void reportSyntaxError(String error, int problemStartPosition,
172 int problemEndPosition) {
173 problemReporter.phpParsingError(new String[]{error},
174 problemStartPosition, problemEndPosition, referenceContext,
175 compilationUnit.compilationResult);
177 private void reportSyntaxWarning(String error, int problemStartPosition,
178 int problemEndPosition) {
179 problemReporter.phpParsingWarning(new String[]{error},
180 problemStartPosition, problemEndPosition, referenceContext,
181 compilationUnit.compilationResult);
184 * Method Declaration.
188 // private void getChar() {
189 // if (str.length() > chIndx) {
190 // ch = str.charAt(chIndx++);
195 // chIndx = str.length() + 1;
197 // // token = TokenNameEOF;
201 * gets the next token from input
203 private void getNextToken() {
205 token = scanner.getNextToken();
207 int currentEndPosition = scanner.getCurrentTokenEndPosition();
208 int currentStartPosition = scanner
209 .getCurrentTokenStartPosition();
210 System.out.print(currentStartPosition + ","
211 + currentEndPosition + ": ");
212 System.out.println(scanner.toStringAction(token));
214 } catch (InvalidInputException e) {
215 token = TokenNameERROR;
219 public void init(String s) {
221 this.token = TokenNameEOF;
223 // this.rowCount = 1;
224 // this.columnCount = 0;
226 // this.phpMode = false;
227 /* scanner initialization */
228 scanner.setSource(s.toCharArray());
229 scanner.setPHPMode(false);
231 protected void initialize(boolean phpMode) {
232 compilationUnit = null;
233 referenceContext = null;
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: "
265 + scanner.toStringAction(token) + ")");
267 if (token == TokenNameRPAREN) {
268 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
270 if (token == TokenNameRBRACE) {
271 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
273 if (token == TokenNameRBRACKET) {
274 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
276 if (token == TokenNameLPAREN) {
277 throwSyntaxError("Read character '('; end-of-file not reached.");
279 if (token == TokenNameLBRACE) {
280 throwSyntaxError("Read character '{'; end-of-file not reached.");
282 if (token == TokenNameLBRACKET) {
283 throwSyntaxError("Read character '['; end-of-file not reached.");
285 throwSyntaxError("End-of-file not reached.");
288 } catch (SyntaxError sytaxErr1) {
289 // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(),
291 // setMarker(sytaxErr1.getMessage(),
292 // scanner.getCurrentTokenStartPosition(),
293 // scanner.getCurrentTokenEndPosition(), ERROR);
295 // if an error occured,
296 // try to find keywords 'class' or 'function'
297 // to parse the rest of the string
298 while (token != TokenNameEOF && token != TokenNameERROR) {
299 if (token == TokenNameabstract
300 || token == TokenNamefinal
301 || token == TokenNameclass
302 || token == TokenNamefunction) {
307 if (token == TokenNameEOF || token == TokenNameERROR) {
310 } catch (SyntaxError sytaxErr2) {
311 // setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(),
313 // setMarker(sytaxErr2.getMessage(),
314 // scanner.getCurrentTokenStartPosition(),
315 // scanner.getCurrentTokenEndPosition(), ERROR);
324 protected CompilationUnitDeclaration endParse(int act) {
328 if (currentElement != null) {
329 currentElement.topElement().updateParseTree();
330 if (VERBOSE_RECOVERY) {
331 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
332 System.out.println("--------------------------"); //$NON-NLS-1$
333 System.out.println(compilationUnit);
334 System.out.println("----------------------------------"); //$NON-NLS-1$
337 if (diet & VERBOSE_RECOVERY) {
338 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
339 System.out.println("--------------------------"); //$NON-NLS-1$
340 System.out.println(compilationUnit);
341 System.out.println("----------------------------------"); //$NON-NLS-1$
344 if (scanner.recordLineSeparator) {
345 compilationUnit.compilationResult.lineSeparatorPositions = scanner
348 if (scanner.taskTags != null) {
349 for (int i = 0; i < scanner.foundTaskCount; i++) {
350 problemReporter().task(
351 new String(scanner.foundTaskTags[i]),
352 new String(scanner.foundTaskMessages[i]),
353 scanner.foundTaskPriorities[i] == null
355 : new String(scanner.foundTaskPriorities[i]),
356 scanner.foundTaskPositions[i][0],
357 scanner.foundTaskPositions[i][1]);
360 return compilationUnit;
362 // public PHPOutlineInfo parseInfo(Object parent, String s) {
363 // PHPOutlineInfo outlineInfo = new PHPOutlineInfo(parent);
364 // // Stack stack = new Stack();
365 // // stack.push(outlineInfo.getDeclarations());
367 // this.token = TokenNameEOF;
368 // // this.chIndx = 0;
369 // // this.rowCount = 1;
370 // // this.columnCount = 0;
371 // this.phpEnd = false;
372 // this.phpMode = false;
373 // scanner.setSource(s.toCharArray());
374 // scanner.setPHPMode(false);
377 // parseDeclarations(outlineInfo, outlineInfo.getDeclarations(), false);
379 // return outlineInfo;
381 private boolean isVariable() {
382 return token == TokenNameVariable; // || token == TokenNamethis;
384 // private void parseDeclarations(PHPOutlineInfo outlineInfo,
385 // OutlineableWithChildren current, boolean goBack) {
387 // // PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
388 // PHPSegmentWithChildren temp;
390 // IPreferenceStore store =
391 // PHPeclipsePlugin.getDefault().getPreferenceStore();
393 // while (token != TokenNameEOF && token != TokenNameERROR) {
394 // if (token == TokenNameVariable) {
395 // ident = scanner.getCurrentIdentifierSource();
396 // outlineInfo.addVariable(new String(ident));
398 // } else if (token == TokenNamevar) {
400 // if (token == TokenNameVariable
401 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
402 // ident = scanner.getCurrentIdentifierSource();
403 // //substring(1) added because PHPVarDeclaration doesn't
404 // // need the $ anymore
405 // String variableName = new String(ident).substring(1);
406 // outlineInfo.addVariable(variableName);
408 // if (token != TokenNameSEMICOLON) {
410 // ident = scanner.getCurrentTokenSource();
411 // if (token > TokenNameKEYWORD) {
412 // current.add(new PHPVarDeclaration(current, variableName,
413 // // chIndx - ident.length,
414 // scanner.getCurrentTokenStartPosition(), new String(ident)));
417 // case TokenNameVariable :
418 // case TokenNamethis :
419 // current.add(new PHPVarDeclaration(current, variableName,
422 // scanner.getCurrentTokenStartPosition(), new String(
425 // case TokenNameIdentifier :
426 // current.add(new PHPVarDeclaration(current, variableName,
429 // scanner.getCurrentTokenStartPosition(), new String(
432 // case TokenNameDoubleLiteral :
433 // current.add(new PHPVarDeclaration(current, variableName
437 // scanner.getCurrentTokenStartPosition(), new String(
440 // case TokenNameIntegerLiteral :
441 // current.add(new PHPVarDeclaration(current, variableName,
444 // scanner.getCurrentTokenStartPosition(), new String(
447 // case TokenNameStringInterpolated :
448 // case TokenNameStringLiteral :
449 // current.add(new PHPVarDeclaration(current, variableName,
452 // scanner.getCurrentTokenStartPosition(), new String(
455 // case TokenNameStringConstant :
456 // current.add(new PHPVarDeclaration(current, variableName,
459 // scanner.getCurrentTokenStartPosition(), new String(
463 // current.add(new PHPVarDeclaration(current, variableName,
466 // scanner.getCurrentTokenStartPosition()));
471 // ident = scanner.getCurrentIdentifierSource();
472 // current.add(new PHPVarDeclaration(current, variableName,
473 // // chIndx - ident.length
474 // scanner.getCurrentTokenStartPosition()));
477 // } else if (token == TokenNamefunction) {
479 // if (token == TokenNameAND) {
482 // if (token == TokenNameIdentifier
483 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
484 // ident = scanner.getCurrentIdentifierSource();
485 // outlineInfo.addVariable(new String(ident));
486 // temp = new PHPFunctionDeclaration(current, new String(ident),
487 // // chIndx - ident.length
488 // scanner.getCurrentTokenStartPosition());
489 // current.add(temp);
491 // parseDeclarations(outlineInfo, temp, true);
493 // } else if (token == TokenNameclass) {
495 // if (token == TokenNameIdentifier
496 // && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
497 // ident = scanner.getCurrentIdentifierSource();
498 // outlineInfo.addVariable(new String(ident));
499 // temp = new PHPClassDeclaration(current, new String(ident),
500 // // chIndx - ident.len
501 // scanner.getCurrentTokenStartPosition());
502 // current.add(temp);
503 // // stack.push(temp);
505 // //skip tokens for classname, extends and others until
506 // // we have the opening '{'
507 // while (token != TokenNameLBRACE && token != TokenNameEOF
508 // && token != TokenNameERROR) {
511 // parseDeclarations(outlineInfo, temp, true);
514 // } else if ((token == TokenNameLBRACE)
515 // || (token == TokenNameDOLLAR_LBRACE)) {
518 // } else if (token == TokenNameRBRACE) {
521 // if (counter == 0 && goBack) {
524 // } else if (token == TokenNamerequire || token == TokenNamerequire_once
525 // || token == TokenNameinclude || token == TokenNameinclude_once) {
526 // ident = scanner.getCurrentTokenSource();
528 // int startPosition = scanner.getCurrentTokenStartPosition();
530 // char[] expr = scanner.getCurrentTokenSource(startPosition);
531 // outlineInfo.addVariable(new String(ident));
532 // current.add(new PHPReqIncDeclaration(current, new String(ident),
533 // // chIndx - ident.length,
534 // startPosition, new String(expr)));
540 // } catch (SyntaxError sytaxErr) {
542 // // // setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
543 // // setMarker(sytaxErr.getMessage(),
544 // // scanner.getCurrentTokenStartPosition(),
545 // // scanner.getCurrentTokenEndPosition(), ERROR);
546 // // } catch (CoreException e) {
550 private void statementList() {
552 statement(TokenNameEOF);
553 if ((token == TokenNameRBRACE) || (token == TokenNamecase)
554 || (token == TokenNamedefault) || (token == TokenNameelse)
555 || (token == TokenNameelseif) || (token == TokenNameendif)
556 || (token == TokenNameendfor)
557 || (token == TokenNameendforeach)
558 || (token == TokenNameendwhile)
559 || (token == TokenNameendswitch) || (token == TokenNameEOF)
560 || (token == TokenNameERROR)) {
565 private void functionBody(MethodDeclaration methodDecl) {
566 // '{' [statement-list] '}'
567 if (token == TokenNameLBRACE) {
570 throwSyntaxError("'{' expected in compound-statement.");
572 if (token != TokenNameRBRACE) {
575 if (token == TokenNameRBRACE) {
576 methodDecl.declarationSourceEnd = scanner
577 .getCurrentTokenEndPosition();
580 throwSyntaxError("'}' expected in compound-statement.");
583 private void statement(int previousToken) {
584 // if (token > TokenNameKEYWORD && token != TokenNamelist && token !=
586 // char[] ident = scanner.getCurrentIdentifierSource();
587 // String keyword = new String(ident);
588 // if (token == TokenNameAT) {
590 // if (token != TokenNamerequire && token != TokenNamerequire_once
591 // && token != TokenNameinclude && token != TokenNameinclude_once
592 // && token != TokenNameIdentifier && token != TokenNameVariable
593 // && token != TokenNameStringInterpolated) {
594 // throwSyntaxError("identifier expected after '@'.");
597 // if (token == TokenNameinclude || token == TokenNameinclude_once) {
599 // if (token == TokenNameLPAREN) {
601 // if (token == TokenNameSEMICOLON) {
604 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
605 // throwSyntaxError("';' expected after 'include' or 'include_once'.");
607 // // getNextToken();
610 // concatenationExpression();
613 // } else if (token == TokenNamerequire || token ==
614 // TokenNamerequire_once)
618 // if (token == TokenNameLPAREN) {
620 // if (token == TokenNameSEMICOLON) {
623 // if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
624 // throwSyntaxError("';' expected after 'require' or 'require_once'.");
626 // // getNextToken();
629 // concatenationExpression();
633 if (token == TokenNameif) {
635 if (token == TokenNameLPAREN) {
638 throwSyntaxError("'(' expected after 'if' keyword.");
641 if (token == TokenNameRPAREN) {
644 throwSyntaxError("')' expected after 'if' condition.");
648 } else if (token == TokenNameswitch) {
650 if (token == TokenNameLPAREN) {
653 throwSyntaxError("'(' expected after 'switch' keyword.");
656 if (token == TokenNameRPAREN) {
659 throwSyntaxError("')' expected after 'switch' condition.");
663 } else if (token == TokenNamefor) {
665 if (token == TokenNameLPAREN) {
668 throwSyntaxError("'(' expected after 'for' keyword.");
670 if (token == TokenNameSEMICOLON) {
674 if (token == TokenNameSEMICOLON) {
677 throwSyntaxError("';' expected after 'for'.");
680 if (token == TokenNameSEMICOLON) {
684 if (token == TokenNameSEMICOLON) {
687 throwSyntaxError("';' expected after 'for'.");
690 if (token == TokenNameRPAREN) {
694 if (token == TokenNameRPAREN) {
697 throwSyntaxError("')' expected after 'for'.");
702 } else if (token == TokenNamewhile) {
704 if (token == TokenNameLPAREN) {
707 throwSyntaxError("'(' expected after 'while' keyword.");
710 if (token == TokenNameRPAREN) {
713 throwSyntaxError("')' expected after 'while' condition.");
717 } else if (token == TokenNamedo) {
719 if (token == TokenNameLBRACE) {
721 if (token != TokenNameRBRACE) {
724 if (token == TokenNameRBRACE) {
727 throwSyntaxError("'}' expected after 'do' keyword.");
730 statement(TokenNameEOF);
732 if (token == TokenNamewhile) {
734 if (token == TokenNameLPAREN) {
737 throwSyntaxError("'(' expected after 'while' keyword.");
740 if (token == TokenNameRPAREN) {
743 throwSyntaxError("')' expected after 'while' condition.");
746 throwSyntaxError("'while' expected after 'do' keyword.");
748 if (token == TokenNameSEMICOLON) {
751 if (token != TokenNameINLINE_HTML) {
752 throwSyntaxError("';' expected after do-while statement.");
757 } else if (token == TokenNameforeach) {
759 if (token == TokenNameLPAREN) {
762 throwSyntaxError("'(' expected after 'foreach' keyword.");
765 if (token == TokenNameas) {
768 throwSyntaxError("'as' expected after 'foreach' exxpression.");
772 foreach_optional_arg();
773 if (token == TokenNameEQUAL_GREATER) {
777 if (token == TokenNameRPAREN) {
780 throwSyntaxError("')' expected after 'foreach' expression.");
784 } else if (token == TokenNamecontinue || token == TokenNamebreak
785 || token == TokenNamereturn) {
787 if (token != TokenNameSEMICOLON) {
790 if (token == TokenNameSEMICOLON) {
793 if (token != TokenNameINLINE_HTML) {
794 throwSyntaxError("';' expected after 'continue', 'break' or 'return'.");
799 } else if (token == TokenNameecho) {
802 if (token == TokenNameSEMICOLON) {
805 if (token != TokenNameINLINE_HTML) {
806 throwSyntaxError("';' expected after 'echo' statement.");
811 } else if (token == TokenNameINLINE_HTML) {
814 // } else if (token == TokenNameprint) {
817 // if (token == TokenNameSEMICOLON) {
820 // if (token != TokenNameStopPHP) {
821 // throwSyntaxError("';' expected after 'print' statement.");
826 } else if (token == TokenNameglobal) {
829 if (token == TokenNameSEMICOLON) {
832 if (token != TokenNameINLINE_HTML) {
833 throwSyntaxError("';' expected after 'global' statement.");
838 } else if (token == TokenNamestatic) {
841 if (token == TokenNameSEMICOLON) {
844 if (token != TokenNameINLINE_HTML) {
845 throwSyntaxError("';' expected after 'static' statement.");
850 } else if (token == TokenNameunset) {
852 if (token == TokenNameLPAREN) {
855 throwSyntaxError("'(' expected after 'unset' statement.");
858 if (token == TokenNameRPAREN) {
861 throwSyntaxError("')' expected after 'unset' statement.");
863 if (token == TokenNameSEMICOLON) {
866 if (token != TokenNameINLINE_HTML) {
867 throwSyntaxError("';' expected after 'unset' statement.");
872 } else if (token == TokenNamefunction) {
873 MethodDeclaration methodDecl = new MethodDeclaration(
874 this.compilationUnit.compilationResult);
875 methodDecl.declarationSourceStart = scanner
876 .getCurrentTokenStartPosition();
878 functionDefinition(methodDecl);
880 } else if (token == TokenNametry) {
882 if (token != TokenNameLBRACE) {
883 throwSyntaxError("'{' expected in 'try' statement.");
887 if (token != TokenNameRBRACE) {
888 throwSyntaxError("'}' expected in 'try' statement.");
892 } else if (token == TokenNamecatch) {
894 if (token != TokenNameLPAREN) {
895 throwSyntaxError("'(' expected in 'catch' statement.");
898 fully_qualified_class_name();
899 if (token != TokenNameVariable) {
900 throwSyntaxError("Variable expected in 'catch' statement.");
903 if (token != TokenNameRPAREN) {
904 throwSyntaxError("')' expected in 'catch' statement.");
907 if (token != TokenNameLBRACE) {
908 throwSyntaxError("'{' expected in 'catch' statement.");
911 if (token != TokenNameRBRACE) {
913 if (token != TokenNameRBRACE) {
914 throwSyntaxError("'}' expected in 'catch' statement.");
918 additional_catches();
920 } else if (token == TokenNamethrow) {
923 if (token == TokenNameSEMICOLON) {
926 throwSyntaxError("';' expected after 'throw' exxpression.");
929 } else if (token == TokenNamefinal || token == TokenNameabstract
930 || token == TokenNameclass || token == TokenNameinterface) {
931 TypeDeclaration typeDecl = new TypeDeclaration(
932 this.compilationUnit.compilationResult);
933 typeDecl.declarationSourceStart = scanner
934 .getCurrentTokenStartPosition();
935 // default super class
936 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT,
938 compilationUnit.types.add(typeDecl);
940 pushOnAstStack(typeDecl);
941 unticked_class_declaration_statement(typeDecl);
942 // classBody(typeDecl);
949 // throwSyntaxError("Unexpected keyword '" + keyword + "'");
950 } else if (token == TokenNameLBRACE) {
952 if (token != TokenNameRBRACE) {
955 if (token == TokenNameRBRACE) {
959 throwSyntaxError("'}' expected.");
962 if (token != TokenNameSEMICOLON) {
965 if (token == TokenNameSEMICOLON) {
969 if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
970 throwSyntaxError("';' expected after expression (Found token: "
971 + scanner.toStringAction(token) + ")");
977 private void additional_catches() {
978 while (token == TokenNamecatch) {
980 if (token != TokenNameLPAREN) {
981 throwSyntaxError("'(' expected in 'catch' statement.");
984 fully_qualified_class_name();
985 if (token != TokenNameVariable) {
986 throwSyntaxError("Variable expected in 'catch' statement.");
989 if (token != TokenNameRPAREN) {
990 throwSyntaxError("')' expected in 'catch' statement.");
993 if (token != TokenNameLBRACE) {
994 throwSyntaxError("'{' expected in 'catch' statement.");
998 if (token != TokenNameRBRACE) {
999 throwSyntaxError("'}' expected in 'catch' statement.");
1004 private void foreach_variable() {
1007 if (token == TokenNameAND) {
1012 private void foreach_optional_arg() {
1014 //| T_DOUBLE_ARROW foreach_variable
1015 if (token == TokenNameEQUAL_GREATER) {
1020 private void global_var_list() {
1022 // global_var_list ',' global_var
1026 if (token != TokenNameCOMMA) {
1032 private void global_var() {
1036 //| '$' '{' expr '}'
1037 if (token == TokenNameVariable) {
1039 } else if (token == TokenNameDOLLAR) {
1041 if (token == TokenNameLPAREN) {
1044 if (token != TokenNameLPAREN) {
1045 throwSyntaxError("')' expected in global variable.");
1053 private void static_var_list() {
1055 // static_var_list ',' T_VARIABLE
1056 //| static_var_list ',' T_VARIABLE '=' static_scalar
1058 //| T_VARIABLE '=' static_scalar
1060 if (token == TokenNameVariable) {
1062 if (token == TokenNameEQUAL) {
1066 if (token != TokenNameCOMMA) {
1075 private void unset_variables() {
1078 // | unset_variables ',' unset_variable
1083 if (token != TokenNameCOMMA) {
1089 private final void initializeModifiers() {
1091 this.modifiersSourceStart = -1;
1093 private final void checkAndSetModifiers(int flag) {
1094 this.modifiers |= flag;
1095 if (this.modifiersSourceStart < 0)
1096 this.modifiersSourceStart = this.scanner.startPosition;
1098 private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
1099 initializeModifiers();
1100 if (token == TokenNameinterface) {
1101 // interface_entry T_STRING
1102 // interface_extends_list
1103 // '{' class_statement_list '}'
1104 checkAndSetModifiers(AccInterface);
1106 typeDecl.modifiers = this.modifiers;
1107 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1108 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1109 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1110 typeDecl.name = scanner.getCurrentIdentifierSource();
1111 if (token > TokenNameKEYWORD) {
1113 "Don't use a keyword for interface declaration ["
1114 + scanner.toStringAction(token) + "].",
1115 typeDecl.sourceStart, typeDecl.sourceEnd);
1118 interface_extends_list();
1120 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1121 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1122 typeDecl.name = new char[]{' '};
1124 "Interface name expected after keyword 'interface'.",
1125 typeDecl.sourceStart, typeDecl.sourceEnd);
1129 // class_entry_type T_STRING extends_from
1131 // '{' class_statement_list'}'
1133 typeDecl.modifiers = this.modifiers;
1135 //identifier 'extends' identifier
1136 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
1137 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1138 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1139 typeDecl.name = scanner.getCurrentIdentifierSource();
1140 if (token > TokenNameKEYWORD) {
1142 "Don't use a keyword for class declaration ["
1143 + scanner.toStringAction(token) + "].",
1144 typeDecl.sourceStart, typeDecl.sourceEnd);
1149 // | T_EXTENDS fully_qualified_class_name
1150 if (token == TokenNameextends) {
1151 interface_extends_list();
1153 // if (token != TokenNameIdentifier) {
1154 // throwSyntaxError("Class name expected after keyword
1156 // scanner.getCurrentTokenStartPosition(), scanner
1157 // .getCurrentTokenEndPosition());
1162 typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1163 typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1164 typeDecl.name = new char[]{' '};
1165 throwSyntaxError("Class name expected after keyword 'class'.",
1166 typeDecl.sourceStart, typeDecl.sourceEnd);
1170 // '{' class_statement_list '}'
1171 if (token == TokenNameLBRACE) {
1173 if (token != TokenNameRBRACE) {
1174 ArrayList list = new ArrayList();
1175 class_statement_list(list);
1176 typeDecl.fields = new FieldDeclaration[list.size()];
1177 for (int i = 0; i < list.size(); i++) {
1178 typeDecl.fields[i] = (FieldDeclaration) list.get(i);
1181 if (token == TokenNameRBRACE) {
1182 typeDecl.declarationSourceEnd = scanner
1183 .getCurrentTokenEndPosition();
1186 throwSyntaxError("'}' expected at end of class body.");
1189 throwSyntaxError("'{' expected at start of class body.");
1192 private void class_entry_type() {
1194 // | T_ABSTRACT T_CLASS
1195 // | T_FINAL T_CLASS
1196 if (token == TokenNameclass) {
1198 } else if (token == TokenNameabstract) {
1199 checkAndSetModifiers(AccAbstract);
1201 if (token != TokenNameclass) {
1202 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
1205 } else if (token == TokenNamefinal) {
1206 checkAndSetModifiers(AccFinal);
1208 if (token != TokenNameclass) {
1209 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
1213 throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
1216 private void interface_extends_list() {
1218 // | T_EXTENDS interface_list
1219 if (token == TokenNameextends) {
1224 private void implements_list() {
1226 // | T_IMPLEMENTS interface_list
1227 if (token == TokenNameimplements) {
1232 private void interface_list() {
1234 // fully_qualified_class_name
1235 //| interface_list ',' fully_qualified_class_name
1237 if (token == TokenNameIdentifier) {
1240 throwSyntaxError("Interface name expected after keyword 'implements'.");
1242 if (token != TokenNameCOMMA) {
1248 // private void classBody(TypeDeclaration typeDecl) {
1249 // //'{' [class-element-list] '}'
1250 // if (token == TokenNameLBRACE) {
1252 // if (token != TokenNameRBRACE) {
1253 // class_statement_list();
1255 // if (token == TokenNameRBRACE) {
1256 // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1259 // throwSyntaxError("'}' expected at end of class body.");
1262 // throwSyntaxError("'{' expected at start of class body.");
1265 private void class_statement_list(ArrayList list) {
1267 class_statement(list);
1268 } while (token == TokenNamepublic || token == TokenNameprotected
1269 || token == TokenNameprivate || token == TokenNamestatic
1270 || token == TokenNameabstract || token == TokenNamefinal
1271 || token == TokenNamefunction || token == TokenNamevar
1272 || token == TokenNameconst);
1274 private void class_statement(ArrayList list) {
1276 // variable_modifiers class_variable_declaration ';'
1277 // | class_constant_declaration ';'
1278 // | method_modifiers T_FUNCTION is_reference T_STRING
1279 // '(' parameter_list ')' method_body
1280 initializeModifiers();
1281 int declarationSourceStart = scanner.getCurrentTokenStartPosition();
1283 if (token == TokenNamevar) {
1284 checkAndSetModifiers(AccPublic);
1285 problemReporter.phpVarDeprecatedWarning(scanner
1286 .getCurrentTokenStartPosition(), scanner
1287 .getCurrentTokenEndPosition(), referenceContext,
1288 compilationUnit.compilationResult);
1290 class_variable_declaration(declarationSourceStart, list);
1291 } else if (token == TokenNameconst) {
1292 class_constant_declaration();
1293 if (token != TokenNameSEMICOLON) {
1294 throwSyntaxError("';' expected after class const declaration.");
1298 boolean hasModifiers = member_modifiers();
1299 if (token == TokenNamefunction) {
1300 if (!hasModifiers) {
1301 checkAndSetModifiers(AccPublic);
1303 MethodDeclaration methodDecl = new MethodDeclaration(
1304 this.compilationUnit.compilationResult);
1305 methodDecl.declarationSourceStart = scanner
1306 .getCurrentTokenStartPosition();
1307 methodDecl.modifiers = this.modifiers;
1309 functionDefinition(methodDecl);
1311 if (!hasModifiers) {
1312 throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
1314 class_variable_declaration(declarationSourceStart, list);
1317 // if (token == TokenNamefunction) {
1318 // MethodDeclaration methodDecl = new MethodDeclaration(
1319 // this.compilationUnit.compilationResult);
1320 // methodDecl.declarationSourceStart = scanner
1321 // .getCurrentTokenStartPosition();
1323 // functionDefinition(methodDecl);
1324 // } else if (token == TokenNamevar) {
1328 // throwSyntaxError("'function' or 'var' expected.");
1331 private void class_constant_declaration() {
1332 // class_constant_declaration ',' T_STRING '=' static_scalar
1333 // | T_CONST T_STRING '=' static_scalar
1334 if (token != TokenNameconst) {
1335 throwSyntaxError("'const' keyword expected in class declaration.");
1340 if (token != TokenNameIdentifier) {
1341 throwSyntaxError("Identifier expected in class const declaration.");
1344 if (token != TokenNameEQUAL) {
1345 throwSyntaxError("'=' expected in class const declaration.");
1349 if (token != TokenNameCOMMA) {
1350 break; // while(true)-loop
1355 // private void variable_modifiers() {
1356 // // variable_modifiers:
1357 // // non_empty_member_modifiers
1359 // initializeModifiers();
1360 // if (token == TokenNamevar) {
1361 // checkAndSetModifiers(AccPublic);
1362 // reportSyntaxError(
1363 // "Keyword 'var' is deprecated. Please use 'public' 'private' or
1365 // modifier for field declarations.",
1366 // scanner.getCurrentTokenStartPosition(), scanner
1367 // .getCurrentTokenEndPosition());
1370 // if (!member_modifiers()) {
1371 // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
1372 // field declarations.");
1376 // private void method_modifiers() {
1377 // //method_modifiers:
1379 // //| non_empty_member_modifiers
1380 // initializeModifiers();
1381 // if (!member_modifiers()) {
1382 // checkAndSetModifiers(AccPublic);
1385 private boolean member_modifiers() {
1392 boolean foundToken = false;
1394 if (token == TokenNamepublic) {
1395 checkAndSetModifiers(AccPublic);
1398 } else if (token == TokenNameprotected) {
1399 checkAndSetModifiers(AccProtected);
1402 } else if (token == TokenNameprivate) {
1403 checkAndSetModifiers(AccPrivate);
1406 } else if (token == TokenNamestatic) {
1407 checkAndSetModifiers(AccStatic);
1410 } else if (token == TokenNameabstract) {
1411 checkAndSetModifiers(AccAbstract);
1414 } else if (token == TokenNamefinal) {
1415 checkAndSetModifiers(AccFinal);
1424 private void class_variable_declaration(int declarationSourceStart,
1426 // class_variable_declaration:
1427 // class_variable_declaration ',' T_VARIABLE
1428 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
1430 // | T_VARIABLE '=' static_scalar
1432 if (token == TokenNameVariable) {
1433 FieldDeclaration fieldDeclaration = new FieldDeclaration(
1434 scanner.getCurrentIdentifierSource(), scanner
1435 .getCurrentTokenStartPosition(), scanner
1436 .getCurrentTokenEndPosition());
1437 fieldDeclaration.modifiers = this.modifiers;
1438 fieldDeclaration.declarationSourceStart = declarationSourceStart;
1439 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
1440 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
1441 // fieldDeclaration.type
1442 list.add(fieldDeclaration);
1444 if (token == TokenNameEQUAL) {
1449 // if (token == TokenNamethis) {
1450 // throwSyntaxError("'$this' not allowed after keyword 'public'
1451 // 'protected' 'private' 'var'.");
1453 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
1455 if (token != TokenNameCOMMA) {
1460 if (token != TokenNameSEMICOLON) {
1461 throwSyntaxError("';' expected after field declaration.");
1465 private void functionDefinition(MethodDeclaration methodDecl) {
1466 boolean isAbstract = false;
1468 compilationUnit.types.add(methodDecl);
1470 AstNode node = astStack[astPtr];
1471 if (node instanceof TypeDeclaration) {
1472 TypeDeclaration typeDecl = ((TypeDeclaration) node);
1473 if (typeDecl.methods == null) {
1474 typeDecl.methods = new AbstractMethodDeclaration[]{methodDecl};
1476 AbstractMethodDeclaration[] newMethods;
1481 newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1],
1482 1, typeDecl.methods.length);
1483 newMethods[0] = methodDecl;
1484 typeDecl.methods = newMethods;
1486 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
1488 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
1493 functionDeclarator(methodDecl);
1494 if (token == TokenNameSEMICOLON) {
1496 throwSyntaxError("Body declaration expected for method: "
1497 + new String(methodDecl.selector));
1502 functionBody(methodDecl);
1504 private void functionDeclarator(MethodDeclaration methodDecl) {
1505 //identifier '(' [parameter-list] ')'
1506 if (token == TokenNameAND) {
1509 if (token == TokenNameIdentifier) {
1510 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
1511 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
1512 methodDecl.selector = scanner.getCurrentIdentifierSource();
1514 if (token == TokenNameLPAREN) {
1517 throwSyntaxError("'(' expected in function declaration.");
1519 if (token != TokenNameRPAREN) {
1522 if (token != TokenNameRPAREN) {
1523 throwSyntaxError("')' expected in function declaration.");
1525 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
1529 if (token > TokenNameKEYWORD) {
1530 throwSyntaxError("Don't use keyword for function declaration ["
1533 throwSyntaxError("Function name expected after keyword 'function'.");
1537 private void parameter_list() {
1538 // non_empty_parameter_list
1540 non_empty_parameter_list(true);
1542 private void non_empty_parameter_list(boolean empty_allowed) {
1543 // optional_class_type T_VARIABLE
1544 // | optional_class_type '&' T_VARIABLE
1545 // | optional_class_type '&' T_VARIABLE '=' static_scalar
1546 // | optional_class_type T_VARIABLE '=' static_scalar
1547 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
1548 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
1549 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
1551 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
1553 if (token == TokenNameIdentifier || token == TokenNameVariable
1554 || token == TokenNameAND) {
1556 if (token == TokenNameIdentifier) {
1559 if (token == TokenNameAND) {
1562 if (token == TokenNameVariable) {
1564 if (token == TokenNameEQUAL) {
1569 throwSyntaxError("Variable expected in parameter list.");
1571 if (token != TokenNameCOMMA) {
1578 if (!empty_allowed) {
1579 throwSyntaxError("Identifier expected in parameter list.");
1582 private void optional_class_type() {
1586 private void parameterDeclaration() {
1588 //variable-reference
1589 if (token == TokenNameAND) {
1594 throwSyntaxError("Variable expected after reference operator '&'.");
1597 //variable '=' constant
1598 if (token == TokenNameVariable) {
1600 if (token == TokenNameEQUAL) {
1606 // if (token == TokenNamethis) {
1607 // throwSyntaxError("Reserved word '$this' not allowed in parameter
1611 private void labeledStatementList() {
1612 if (token != TokenNamecase && token != TokenNamedefault) {
1613 throwSyntaxError("'case' or 'default' expected.");
1616 if (token == TokenNamecase) {
1618 expr(); //constant();
1619 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
1621 if (token == TokenNamecase || token == TokenNamedefault) {
1622 // empty case statement ?
1627 // else if (token == TokenNameSEMICOLON) {
1629 // "':' expected after 'case' keyword (Found token: " +
1630 // scanner.toStringAction(token) + ")",
1631 // scanner.getCurrentTokenStartPosition(),
1632 // scanner.getCurrentTokenEndPosition(),
1635 // if (token == TokenNamecase) { // empty case statement ?
1641 throwSyntaxError("':' character after 'case' constant expected (Found token: "
1642 + scanner.toStringAction(token) + ")");
1644 } else { // TokenNamedefault
1646 if (token == TokenNameCOLON) {
1648 if (token == TokenNameRBRACE) {
1649 // empty default case
1654 throwSyntaxError("':' character after 'default' expected.");
1657 } while (token == TokenNamecase || token == TokenNamedefault);
1659 // public void labeledStatement() {
1660 // if (token == TokenNamecase) {
1663 // if (token == TokenNameDDOT) {
1667 // throwSyntaxError("':' character after 'case' constant expected.");
1670 // } else if (token == TokenNamedefault) {
1672 // if (token == TokenNameDDOT) {
1676 // throwSyntaxError("':' character after 'default' expected.");
1681 // public void expressionStatement() {
1683 // private void inclusionStatement() {
1685 // public void compoundStatement() {
1687 // public void selectionStatement() {
1690 // public void iterationStatement() {
1693 // public void jumpStatement() {
1696 // public void outputStatement() {
1699 // public void scopeStatement() {
1702 // public void flowStatement() {
1705 // public void definitionStatement() {
1707 private void ifStatement() {
1708 // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
1709 if (token == TokenNameCOLON) {
1711 if (token != TokenNameendif) {
1714 case TokenNameelse :
1716 if (token == TokenNameCOLON) {
1718 if (token != TokenNameendif) {
1722 if (token == TokenNameif) { //'else if'
1724 elseifStatementList();
1726 throwSyntaxError("':' expected after 'else'.");
1730 case TokenNameelseif :
1732 elseifStatementList();
1736 if (token != TokenNameendif) {
1737 throwSyntaxError("'endif' expected.");
1740 if (token != TokenNameSEMICOLON) {
1741 throwSyntaxError("';' expected after if-statement.");
1745 // statement [else-statement]
1746 statement(TokenNameEOF);
1747 if (token == TokenNameelseif) {
1749 if (token == TokenNameLPAREN) {
1752 throwSyntaxError("'(' expected after 'elseif' keyword.");
1755 if (token == TokenNameRPAREN) {
1758 throwSyntaxError("')' expected after 'elseif' condition.");
1761 } else if (token == TokenNameelse) {
1763 statement(TokenNameEOF);
1767 private void elseifStatementList() {
1771 case TokenNameelse :
1773 if (token == TokenNameCOLON) {
1775 if (token != TokenNameendif) {
1780 if (token == TokenNameif) { //'else if'
1783 throwSyntaxError("':' expected after 'else'.");
1787 case TokenNameelseif :
1795 private void elseifStatement() {
1796 if (token == TokenNameLPAREN) {
1799 if (token != TokenNameRPAREN) {
1800 throwSyntaxError("')' expected in else-if-statement.");
1803 if (token != TokenNameCOLON) {
1804 throwSyntaxError("':' expected in else-if-statement.");
1807 if (token != TokenNameendif) {
1812 private void switchStatement() {
1813 if (token == TokenNameCOLON) {
1814 // ':' [labeled-statement-list] 'endswitch' ';'
1816 labeledStatementList();
1817 if (token != TokenNameendswitch) {
1818 throwSyntaxError("'endswitch' expected.");
1821 if (token != TokenNameSEMICOLON) {
1822 throwSyntaxError("';' expected after switch-statement.");
1826 // '{' [labeled-statement-list] '}'
1827 if (token != TokenNameLBRACE) {
1828 throwSyntaxError("'{' expected in switch statement.");
1831 if (token != TokenNameRBRACE) {
1832 labeledStatementList();
1834 if (token != TokenNameRBRACE) {
1835 throwSyntaxError("'}' expected in switch statement.");
1840 private void forStatement() {
1841 if (token == TokenNameCOLON) {
1844 if (token != TokenNameendfor) {
1845 throwSyntaxError("'endfor' expected.");
1848 if (token != TokenNameSEMICOLON) {
1849 throwSyntaxError("';' expected after for-statement.");
1853 statement(TokenNameEOF);
1856 private void whileStatement() {
1857 // ':' statement-list 'endwhile' ';'
1858 if (token == TokenNameCOLON) {
1861 if (token != TokenNameendwhile) {
1862 throwSyntaxError("'endwhile' expected.");
1865 if (token != TokenNameSEMICOLON) {
1866 throwSyntaxError("';' expected after while-statement.");
1870 statement(TokenNameEOF);
1873 private void foreachStatement() {
1874 if (token == TokenNameCOLON) {
1877 if (token != TokenNameendforeach) {
1878 throwSyntaxError("'endforeach' expected.");
1881 if (token != TokenNameSEMICOLON) {
1882 throwSyntaxError("';' expected after foreach-statement.");
1886 statement(TokenNameEOF);
1889 // private void exitStatus() {
1890 // if (token == TokenNameLPAREN) {
1893 // throwSyntaxError("'(' expected in 'exit-status'.");
1895 // if (token != TokenNameRPAREN) {
1898 // if (token == TokenNameRPAREN) {
1901 // throwSyntaxError("')' expected after 'exit-status'.");
1904 private void expressionList() {
1907 if (token == TokenNameCOMMA) {
1914 private void expr() {
1916 // | expr_without_variable
1917 // if (token!=TokenNameEOF) {
1918 if (Scanner.TRACE) {
1919 System.out.println("TRACE: expr()");
1921 expr_without_variable(true);
1924 private void expr_without_variable(boolean only_variable) {
1925 // internal_functions_in_yacc
1934 // | T_INC rw_variable
1935 // | T_DEC rw_variable
1936 // | T_INT_CAST expr
1937 // | T_DOUBLE_CAST expr
1938 // | T_STRING_CAST expr
1939 // | T_ARRAY_CAST expr
1940 // | T_OBJECT_CAST expr
1941 // | T_BOOL_CAST expr
1942 // | T_UNSET_CAST expr
1943 // | T_EXIT exit_expr
1945 // | T_ARRAY '(' array_pair_list ')'
1946 // | '`' encaps_list '`'
1947 // | T_LIST '(' assignment_list ')' '=' expr
1948 // | T_NEW class_name_reference ctor_arguments
1949 // | variable '=' expr
1950 // | variable '=' '&' variable
1951 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
1952 // | variable T_PLUS_EQUAL expr
1953 // | variable T_MINUS_EQUAL expr
1954 // | variable T_MUL_EQUAL expr
1955 // | variable T_DIV_EQUAL expr
1956 // | variable T_CONCAT_EQUAL expr
1957 // | variable T_MOD_EQUAL expr
1958 // | variable T_AND_EQUAL expr
1959 // | variable T_OR_EQUAL expr
1960 // | variable T_XOR_EQUAL expr
1961 // | variable T_SL_EQUAL expr
1962 // | variable T_SR_EQUAL expr
1963 // | rw_variable T_INC
1964 // | rw_variable T_DEC
1965 // | expr T_BOOLEAN_OR expr
1966 // | expr T_BOOLEAN_AND expr
1967 // | expr T_LOGICAL_OR expr
1968 // | expr T_LOGICAL_AND expr
1969 // | expr T_LOGICAL_XOR expr
1981 // | expr T_IS_IDENTICAL expr
1982 // | expr T_IS_NOT_IDENTICAL expr
1983 // | expr T_IS_EQUAL expr
1984 // | expr T_IS_NOT_EQUAL expr
1986 // | expr T_IS_SMALLER_OR_EQUAL expr
1988 // | expr T_IS_GREATER_OR_EQUAL expr
1989 // | expr T_INSTANCEOF class_name_reference
1990 // | expr '?' expr ':' expr
1991 if (Scanner.TRACE) {
1992 System.out.println("TRACE: expr_without_variable() PART 1");
1995 case TokenNameisset :
1996 case TokenNameempty :
1997 case TokenNameeval :
1998 case TokenNameinclude :
1999 case TokenNameinclude_once :
2000 case TokenNamerequire :
2001 case TokenNamerequire_once :
2002 internal_functions_in_yacc();
2005 case TokenNameLPAREN :
2008 if (token == TokenNameRPAREN) {
2011 throwSyntaxError("')' expected in expression.");
2021 // | T_INT_CAST expr
2022 // | T_DOUBLE_CAST expr
2023 // | T_STRING_CAST expr
2024 // | T_ARRAY_CAST expr
2025 // | T_OBJECT_CAST expr
2026 // | T_BOOL_CAST expr
2027 // | T_UNSET_CAST expr
2028 case TokenNameclone :
2029 case TokenNameprint :
2031 case TokenNamePLUS :
2032 case TokenNameMINUS :
2034 case TokenNameTWIDDLE :
2035 case TokenNameintCAST :
2036 case TokenNamedoubleCAST :
2037 case TokenNamestringCAST :
2038 case TokenNamearrayCAST :
2039 case TokenNameobjectCAST :
2040 case TokenNameboolCAST :
2041 case TokenNameunsetCAST :
2045 case TokenNameexit :
2051 //| T_STRING_VARNAME
2053 //| T_START_HEREDOC encaps_list T_END_HEREDOC
2054 // | '`' encaps_list '`'
2056 // | '`' encaps_list '`'
2057 case TokenNameEncapsedString0 :
2058 scanner.encapsedStringStack.push(new Character('`'));
2061 if (token == TokenNameEncapsedString0) {
2064 if (token != TokenNameEncapsedString0) {
2065 throwSyntaxError("\'`\' expected at end of string"
2067 + scanner.toStringAction(token) + " )");
2071 scanner.encapsedStringStack.pop();
2075 // | '\'' encaps_list '\''
2076 case TokenNameEncapsedString1 :
2077 scanner.encapsedStringStack.push(new Character('\''));
2080 if (token == TokenNameEncapsedString1) {
2083 if (token != TokenNameEncapsedString1) {
2084 throwSyntaxError("\'\'\' expected at end of string"
2086 + scanner.toStringAction(token) + " )");
2090 scanner.encapsedStringStack.pop();
2094 //| '"' encaps_list '"'
2095 case TokenNameEncapsedString2 :
2096 scanner.encapsedStringStack.push(new Character('"'));
2099 if (token == TokenNameEncapsedString2) {
2102 if (token != TokenNameEncapsedString2) {
2103 throwSyntaxError("'\"' expected at end of string"
2105 + scanner.toStringAction(token) + " )");
2109 scanner.encapsedStringStack.pop();
2113 case TokenNameIntegerLiteral :
2114 case TokenNameDoubleLiteral :
2115 case TokenNameStringLiteral :
2116 case TokenNameStringConstant :
2117 case TokenNameStringInterpolated :
2118 case TokenNameFILE :
2119 case TokenNameLINE :
2120 case TokenNameCLASS_C :
2121 case TokenNameMETHOD_C :
2122 case TokenNameFUNC_C :
2125 case TokenNameHEREDOC :
2128 case TokenNamearray :
2129 // T_ARRAY '(' array_pair_list ')'
2131 if (token == TokenNameLPAREN) {
2133 if (token == TokenNameRPAREN) {
2138 if (token != TokenNameRPAREN) {
2139 throwSyntaxError("')' expected after keyword 'array'"
2141 + scanner.toStringAction(token) + ")");
2145 throwSyntaxError("'(' expected after keyword 'array'"
2146 + "(Found token: " + scanner.toStringAction(token)
2150 case TokenNamelist :
2151 // | T_LIST '(' assignment_list ')' '=' expr
2153 if (token == TokenNameLPAREN) {
2156 if (token != TokenNameRPAREN) {
2157 throwSyntaxError("')' expected after 'list' keyword.");
2160 if (token != TokenNameEQUAL) {
2161 throwSyntaxError("'=' expected after 'list' keyword.");
2166 throwSyntaxError("'(' expected after 'list' keyword.");
2170 // | T_NEW class_name_reference ctor_arguments
2172 class_name_reference();
2175 // | T_INC rw_variable
2176 // | T_DEC rw_variable
2177 case TokenNamePLUS_PLUS :
2178 case TokenNameMINUS_MINUS :
2182 // | variable '=' expr
2183 // | variable '=' '&' variable
2184 // | variable '=' '&' T_NEW class_name_reference ctor_arguments
2185 // | variable T_PLUS_EQUAL expr
2186 // | variable T_MINUS_EQUAL expr
2187 // | variable T_MUL_EQUAL expr
2188 // | variable T_DIV_EQUAL expr
2189 // | variable T_CONCAT_EQUAL expr
2190 // | variable T_MOD_EQUAL expr
2191 // | variable T_AND_EQUAL expr
2192 // | variable T_OR_EQUAL expr
2193 // | variable T_XOR_EQUAL expr
2194 // | variable T_SL_EQUAL expr
2195 // | variable T_SR_EQUAL expr
2196 // | rw_variable T_INC
2197 // | rw_variable T_DEC
2198 case TokenNameIdentifier :
2199 case TokenNameVariable :
2200 case TokenNameDOLLAR :
2203 case TokenNameEQUAL :
2205 if (token == TokenNameAND) {
2207 if (token == TokenNamenew) {
2208 // | variable '=' '&' T_NEW class_name_reference
2211 class_name_reference();
2220 case TokenNamePLUS_EQUAL :
2221 case TokenNameMINUS_EQUAL :
2222 case TokenNameMULTIPLY_EQUAL :
2223 case TokenNameDIVIDE_EQUAL :
2224 case TokenNameDOT_EQUAL :
2225 case TokenNameREMAINDER_EQUAL :
2226 case TokenNameAND_EQUAL :
2227 case TokenNameOR_EQUAL :
2228 case TokenNameXOR_EQUAL :
2229 case TokenNameRIGHT_SHIFT_EQUAL :
2230 case TokenNameLEFT_SHIFT_EQUAL :
2234 case TokenNamePLUS_PLUS :
2235 case TokenNameMINUS_MINUS :
2239 if (!only_variable) {
2240 throwSyntaxError("Variable expression not allowed (found token '"
2241 + scanner.toStringAction(token) + "').");
2246 if (token != TokenNameINLINE_HTML) {
2247 if (token > TokenNameKEYWORD) {
2251 throwSyntaxError("Error in expression (found token '"
2252 + scanner.toStringAction(token) + "').");
2257 if (Scanner.TRACE) {
2258 System.out.println("TRACE: expr_without_variable() PART 2");
2260 // | expr T_BOOLEAN_OR expr
2261 // | expr T_BOOLEAN_AND expr
2262 // | expr T_LOGICAL_OR expr
2263 // | expr T_LOGICAL_AND expr
2264 // | expr T_LOGICAL_XOR expr
2276 // | expr T_IS_IDENTICAL expr
2277 // | expr T_IS_NOT_IDENTICAL expr
2278 // | expr T_IS_EQUAL expr
2279 // | expr T_IS_NOT_EQUAL expr
2281 // | expr T_IS_SMALLER_OR_EQUAL expr
2283 // | expr T_IS_GREATER_OR_EQUAL expr
2286 case TokenNameOR_OR :
2287 case TokenNameAND_AND :
2295 case TokenNamePLUS :
2296 case TokenNameMINUS :
2297 case TokenNameMULTIPLY :
2298 case TokenNameDIVIDE :
2299 case TokenNameREMAINDER :
2300 case TokenNameLEFT_SHIFT :
2301 case TokenNameRIGHT_SHIFT :
2302 case TokenNameEQUAL_EQUAL_EQUAL :
2303 case TokenNameNOT_EQUAL_EQUAL :
2304 case TokenNameEQUAL_EQUAL :
2305 case TokenNameNOT_EQUAL :
2306 case TokenNameLESS :
2307 case TokenNameLESS_EQUAL :
2308 case TokenNameGREATER :
2309 case TokenNameGREATER_EQUAL :
2313 // | expr T_INSTANCEOF class_name_reference
2314 // | expr '?' expr ':' expr
2315 case TokenNameinstanceof :
2317 class_name_reference();
2319 case TokenNameQUESTION :
2322 if (token == TokenNameCOLON) {
2332 private void class_name_reference() {
2333 // class_name_reference:
2335 //| dynamic_class_name_reference
2336 if (Scanner.TRACE) {
2337 System.out.println("TRACE: class_name_reference()");
2339 if (token == TokenNameIdentifier) {
2342 dynamic_class_name_reference();
2345 private void dynamic_class_name_reference() {
2346 //dynamic_class_name_reference:
2347 // base_variable T_OBJECT_OPERATOR object_property
2348 // dynamic_class_name_variable_properties
2350 if (Scanner.TRACE) {
2351 System.out.println("TRACE: dynamic_class_name_reference()");
2354 if (token == TokenNameMINUS_GREATER) {
2357 dynamic_class_name_variable_properties();
2360 private void dynamic_class_name_variable_properties() {
2361 // dynamic_class_name_variable_properties:
2362 // dynamic_class_name_variable_properties
2363 // dynamic_class_name_variable_property
2365 if (Scanner.TRACE) {
2367 .println("TRACE: dynamic_class_name_variable_properties()");
2369 while (token == TokenNameMINUS_GREATER) {
2370 dynamic_class_name_variable_property();
2373 private void dynamic_class_name_variable_property() {
2374 // dynamic_class_name_variable_property:
2375 // T_OBJECT_OPERATOR object_property
2376 if (Scanner.TRACE) {
2377 System.out.println("TRACE: dynamic_class_name_variable_property()");
2379 if (token == TokenNameMINUS_GREATER) {
2384 private void ctor_arguments() {
2387 //| '(' function_call_parameter_list ')'
2388 if (token == TokenNameLPAREN) {
2390 if (token == TokenNameRPAREN) {
2394 non_empty_function_call_parameter_list();
2395 if (token != TokenNameRPAREN) {
2396 throwSyntaxError("')' expected in ctor_arguments.");
2401 private void assignment_list() {
2403 // assignment_list ',' assignment_list_element
2404 //| assignment_list_element
2406 assignment_list_element();
2407 if (token != TokenNameCOMMA) {
2413 private void assignment_list_element() {
2414 //assignment_list_element:
2416 //| T_LIST '(' assignment_list ')'
2418 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2421 if (token == TokenNamelist) {
2423 if (token == TokenNameLPAREN) {
2426 if (token != TokenNameRPAREN) {
2427 throwSyntaxError("')' expected after 'list' keyword.");
2431 throwSyntaxError("'(' expected after 'list' keyword.");
2436 private void array_pair_list() {
2439 //| non_empty_array_pair_list possible_comma
2440 non_empty_array_pair_list();
2441 if (token == TokenNameCOMMA) {
2445 private void non_empty_array_pair_list() {
2446 //non_empty_array_pair_list:
2447 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
2448 //| non_empty_array_pair_list ',' expr
2449 //| expr T_DOUBLE_ARROW expr
2451 //| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
2452 //| non_empty_array_pair_list ',' '&' w_variable
2453 //| expr T_DOUBLE_ARROW '&' w_variable
2456 if (token == TokenNameAND) {
2461 if (token == TokenNameAND) {
2464 } else if (token == TokenNameEQUAL_GREATER) {
2466 if (token == TokenNameAND) {
2474 if (token != TokenNameCOMMA) {
2478 if (token == TokenNameRPAREN) {
2483 // private void variableList() {
2486 // if (token == TokenNameCOMMA) {
2493 private void variable_without_objects() {
2494 // variable_without_objects:
2495 // reference_variable
2496 // | simple_indirect_reference reference_variable
2497 if (Scanner.TRACE) {
2498 System.out.println("TRACE: variable_without_objects()");
2500 while (token == TokenNameDOLLAR) {
2503 reference_variable();
2505 private void function_call() {
2507 // T_STRING '(' function_call_parameter_list ')'
2508 //| class_constant '(' function_call_parameter_list ')'
2509 //| static_member '(' function_call_parameter_list ')'
2510 //| variable_without_objects '(' function_call_parameter_list ')'
2511 if (Scanner.TRACE) {
2512 System.out.println("TRACE: function_call()");
2514 if (token == TokenNameIdentifier) {
2517 case TokenNamePAAMAYIM_NEKUDOTAYIM :
2520 if (token == TokenNameIdentifier) {
2525 variable_without_objects();
2530 variable_without_objects();
2532 if (token != TokenNameLPAREN) {
2533 // TODO is this ok ?
2535 // throwSyntaxError("'(' expected in function call.");
2538 if (token == TokenNameRPAREN) {
2542 non_empty_function_call_parameter_list();
2543 if (token != TokenNameRPAREN) {
2544 throwSyntaxError("')' expected in function call.");
2548 // private void function_call_parameter_list() {
2549 // function_call_parameter_list:
2550 // non_empty_function_call_parameter_list { $$ = $1; }
2553 private void non_empty_function_call_parameter_list() {
2554 //non_empty_function_call_parameter_list:
2555 // expr_without_variable
2558 // | non_empty_function_call_parameter_list ',' expr_without_variable
2559 // | non_empty_function_call_parameter_list ',' variable
2560 // | non_empty_function_call_parameter_list ',' '&' w_variable
2561 if (Scanner.TRACE) {
2563 .println("TRACE: non_empty_function_call_parameter_list()");
2566 if (token == TokenNameAND) {
2570 // if (token == TokenNameIdentifier || token ==
2571 // TokenNameVariable
2572 // || token == TokenNameDOLLAR) {
2575 expr_without_variable(true);
2578 if (token != TokenNameCOMMA) {
2584 private void fully_qualified_class_name() {
2585 if (token == TokenNameIdentifier) {
2588 throwSyntaxError("Class name expected.");
2591 private void static_member() {
2593 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
2594 // variable_without_objects
2595 if (Scanner.TRACE) {
2596 System.out.println("TRACE: static_member()");
2598 fully_qualified_class_name();
2599 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
2600 throwSyntaxError("'::' expected after class name (static_member).");
2603 variable_without_objects();
2605 private void base_variable_with_function_calls() {
2606 // base_variable_with_function_calls:
2609 boolean functionCall = false;
2610 if (Scanner.TRACE) {
2611 System.out.println("TRACE: base_variable_with_function_calls()");
2613 // if (token == TokenNameIdentifier) {
2614 // functionCall = true;
2615 // } else if (token == TokenNameVariable) {
2616 // int tempToken = token;
2617 // int tempPosition = scanner.currentPosition;
2619 // if (token == TokenNameLPAREN) {
2620 // functionCall = true;
2622 // token = tempToken;
2623 // scanner.currentPosition = tempPosition;
2624 // scanner.phpMode = true;
2626 // if (functionCall) {
2632 private void base_variable() {
2634 // reference_variable
2635 // | simple_indirect_reference reference_variable
2637 if (Scanner.TRACE) {
2638 System.out.println("TRACE: base_variable()");
2640 if (token == TokenNameIdentifier) {
2643 while (token == TokenNameDOLLAR) {
2646 reference_variable();
2649 // private void simple_indirect_reference() {
2650 // // simple_indirect_reference:
2652 // //| simple_indirect_reference '$'
2654 private void reference_variable() {
2655 // reference_variable:
2656 // reference_variable '[' dim_offset ']'
2657 // | reference_variable '{' expr '}'
2658 // | compound_variable
2659 if (Scanner.TRACE) {
2660 System.out.println("TRACE: reference_variable()");
2662 compound_variable();
2664 if (token == TokenNameLBRACE) {
2667 if (token != TokenNameRBRACE) {
2668 throwSyntaxError("'}' expected in reference variable.");
2671 } else if (token == TokenNameLBRACKET) {
2673 if (token != TokenNameRBRACKET) {
2676 if (token != TokenNameRBRACKET) {
2677 throwSyntaxError("']' expected in reference variable.");
2686 private void compound_variable() {
2687 // compound_variable:
2689 // | '$' '{' expr '}'
2690 if (Scanner.TRACE) {
2691 System.out.println("TRACE: compound_variable()");
2693 if (token == TokenNameVariable) {
2696 // because of simple_indirect_reference
2697 while (token == TokenNameDOLLAR) {
2700 if (token != TokenNameLBRACE) {
2701 throwSyntaxError("'{' expected after compound variable token '$'.");
2705 if (token != TokenNameRBRACE) {
2706 throwSyntaxError("'}' expected after compound variable token '$'.");
2711 // private void dim_offset() {
2717 private void object_property() {
2720 //| variable_without_objects
2721 if (Scanner.TRACE) {
2722 System.out.println("TRACE: object_property()");
2724 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
2725 variable_without_objects();
2730 private void object_dim_list() {
2732 // object_dim_list '[' dim_offset ']'
2733 //| object_dim_list '{' expr '}'
2735 if (Scanner.TRACE) {
2736 System.out.println("TRACE: object_dim_list()");
2740 if (token == TokenNameLBRACE) {
2743 if (token != TokenNameRBRACE) {
2744 throwSyntaxError("'}' expected in object_dim_list.");
2747 } else if (token == TokenNameLBRACKET) {
2749 if (token == TokenNameRBRACKET) {
2754 if (token != TokenNameRBRACKET) {
2755 throwSyntaxError("']' expected in object_dim_list.");
2763 private void variable_name() {
2767 if (Scanner.TRACE) {
2768 System.out.println("TRACE: variable_name()");
2770 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
2771 if (token > TokenNameKEYWORD) {
2772 // TODO show a warning "Keyword used as variable" ?
2776 if (token != TokenNameLBRACE) {
2777 throwSyntaxError("'{' expected in variable name.");
2781 if (token != TokenNameRBRACE) {
2782 throwSyntaxError("'}' expected in variable name.");
2787 private void r_variable() {
2790 private void w_variable() {
2793 private void rw_variable() {
2796 private void variable() {
2798 // base_variable_with_function_calls T_OBJECT_OPERATOR
2799 // object_property method_or_not variable_properties
2800 // | base_variable_with_function_calls
2801 base_variable_with_function_calls();
2802 if (token == TokenNameMINUS_GREATER) {
2806 variable_properties();
2808 // if (token == TokenNameDOLLAR_LBRACE) {
2812 // if (token != TokenNameRBRACE) {
2813 // throwSyntaxError("'}' expected after indirect variable token '${'.");
2817 // if (token == TokenNameVariable) {
2819 // if (token == TokenNameLBRACKET) {
2822 // if (token != TokenNameRBRACKET) {
2823 // throwSyntaxError("']' expected in variable-list.");
2826 // } else if (token == TokenNameEQUAL) {
2831 // throwSyntaxError("$-variable expected in variable-list.");
2835 private void variable_properties() {
2836 // variable_properties:
2837 // variable_properties variable_property
2839 while (token == TokenNameMINUS_GREATER) {
2840 variable_property();
2843 private void variable_property() {
2844 // variable_property:
2845 // T_OBJECT_OPERATOR object_property method_or_not
2846 if (Scanner.TRACE) {
2847 System.out.println("TRACE: variable_property()");
2849 if (token == TokenNameMINUS_GREATER) {
2854 throwSyntaxError("'->' expected in variable_property.");
2857 private void method_or_not() {
2859 // '(' function_call_parameter_list ')'
2861 if (Scanner.TRACE) {
2862 System.out.println("TRACE: method_or_not()");
2864 if (token == TokenNameLPAREN) {
2866 if (token == TokenNameRPAREN) {
2870 non_empty_function_call_parameter_list();
2871 if (token != TokenNameRPAREN) {
2872 throwSyntaxError("')' expected in method_or_not.");
2877 private void exit_expr() {
2881 if (token != TokenNameLPAREN) {
2885 if (token == TokenNameRPAREN) {
2890 if (token != TokenNameRPAREN) {
2891 throwSyntaxError("')' expected after keyword 'exit'");
2895 private void encaps_list() {
2896 // encaps_list encaps_var
2897 // | encaps_list T_STRING
2898 // | encaps_list T_NUM_STRING
2899 // | encaps_list T_ENCAPSED_AND_WHITESPACE
2900 // | encaps_list T_CHARACTER
2901 // | encaps_list T_BAD_CHARACTER
2902 // | encaps_list '['
2903 // | encaps_list ']'
2904 // | encaps_list '{'
2905 // | encaps_list '}'
2906 // | encaps_list T_OBJECT_OPERATOR
2910 case TokenNameSTRING :
2913 case TokenNameLBRACE :
2914 // scanner.encapsedStringStack.pop();
2917 case TokenNameRBRACE :
2918 // scanner.encapsedStringStack.pop();
2921 case TokenNameLBRACKET :
2922 // scanner.encapsedStringStack.pop();
2925 case TokenNameRBRACKET :
2926 // scanner.encapsedStringStack.pop();
2929 case TokenNameMINUS_GREATER :
2930 // scanner.encapsedStringStack.pop();
2933 case TokenNameVariable :
2934 case TokenNameDOLLAR_LBRACE :
2935 case TokenNameCURLY_OPEN :
2938 // case TokenNameDOLLAR :
2940 // if (token == TokenNameLBRACE) {
2941 // token = TokenNameDOLLAR_LBRACE;
2946 char encapsedChar = ((Character) scanner.encapsedStringStack
2947 .peek()).charValue();
2948 if (encapsedChar == '$') {
2949 scanner.encapsedStringStack.pop();
2950 encapsedChar = ((Character) scanner.encapsedStringStack
2951 .peek()).charValue();
2952 switch (encapsedChar) {
2954 if (token == TokenNameEncapsedString0) {
2957 token = TokenNameSTRING;
2960 if (token == TokenNameEncapsedString1) {
2963 token = TokenNameSTRING;
2966 if (token == TokenNameEncapsedString2) {
2969 token = TokenNameSTRING;
2977 private void encaps_var() {
2979 // | T_VARIABLE '[' encaps_var_offset ']'
2980 // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
2981 // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
2982 // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
2983 // | T_CURLY_OPEN variable '}'
2985 case TokenNameVariable :
2987 if (token == TokenNameLBRACKET) {
2989 // if (token == TokenNameRBRACKET) {
2992 expr(); //encaps_var_offset();
2993 if (token != TokenNameRBRACKET) {
2994 throwSyntaxError("']' expected after variable.");
2996 // scanner.encapsedStringStack.pop();
2999 } else if (token == TokenNameMINUS_GREATER) {
3001 if (token != TokenNameIdentifier) {
3002 throwSyntaxError("Identifier expected after '->'.");
3004 // scanner.encapsedStringStack.pop();
3008 // // scanner.encapsedStringStack.pop();
3009 // int tempToken = TokenNameSTRING;
3010 // if (!scanner.encapsedStringStack.isEmpty()
3011 // && (token == TokenNameEncapsedString0
3012 // || token == TokenNameEncapsedString1
3013 // || token == TokenNameEncapsedString2 || token ==
3014 // TokenNameERROR)) {
3015 // char encapsedChar = ((Character)
3016 // scanner.encapsedStringStack.peek())
3019 // case TokenNameEncapsedString0 :
3020 // if (encapsedChar == '`') {
3021 // tempToken = TokenNameEncapsedString0;
3024 // case TokenNameEncapsedString1 :
3025 // if (encapsedChar == '\'') {
3026 // tempToken = TokenNameEncapsedString1;
3029 // case TokenNameEncapsedString2 :
3030 // if (encapsedChar == '"') {
3031 // tempToken = TokenNameEncapsedString2;
3034 // case TokenNameERROR :
3035 // if (scanner.source[scanner.currentPosition - 1] == '\\') {
3036 // scanner.currentPosition--;
3042 // token = tempToken;
3045 case TokenNameDOLLAR_LBRACE :
3047 if (token == TokenNameIdentifier) {
3049 if (token == TokenNameLBRACKET) {
3051 // if (token == TokenNameRBRACKET) {
3055 if (token != TokenNameRBRACKET) {
3056 throwSyntaxError("']' expected after '${'.");
3061 if (token != TokenNameRBRACE) {
3062 throwSyntaxError("'}' expected after '${'.");
3064 // scanner.encapsedStringStack.pop();
3068 if (token != TokenNameRBRACE) {
3069 throwSyntaxError("'}' expected.");
3071 // scanner.encapsedStringStack.pop();
3075 case TokenNameCURLY_OPEN :
3077 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
3079 if (token == TokenNameLBRACKET) {
3081 // if (token == TokenNameRBRACKET) {
3085 if (token != TokenNameRBRACKET) {
3086 throwSyntaxError("']' expected after '{$'.");
3090 } else if (token == TokenNameMINUS_GREATER) {
3092 if (token != TokenNameIdentifier) {
3093 throwSyntaxError("String token expected.");
3097 // if (token != TokenNameRBRACE) {
3098 // throwSyntaxError("'}' expected after '{$'.");
3100 // // scanner.encapsedStringStack.pop();
3104 if (token != TokenNameRBRACE) {
3105 throwSyntaxError("'}' expected.");
3107 // scanner.encapsedStringStack.pop();
3113 private void encaps_var_offset() {
3118 case TokenNameSTRING :
3121 case TokenNameIntegerLiteral :
3124 case TokenNameVariable :
3127 case TokenNameIdentifier :
3131 throwSyntaxError("Variable or String token expected.");
3135 private void internal_functions_in_yacc() {
3137 case TokenNameisset :
3138 // T_ISSET '(' isset_variables ')'
3140 if (token != TokenNameLPAREN) {
3141 throwSyntaxError("'(' expected after keyword 'isset'");
3145 if (token != TokenNameRPAREN) {
3146 throwSyntaxError("')' expected after keyword 'isset'");
3150 case TokenNameempty :
3151 // T_EMPTY '(' variable ')'
3153 if (token != TokenNameLPAREN) {
3154 throwSyntaxError("'(' expected after keyword 'empty'");
3158 if (token != TokenNameRPAREN) {
3159 throwSyntaxError("')' expected after keyword 'empty'");
3163 case TokenNameinclude :
3167 // ImportReference impt = new ImportReference(tokens, positions,
3168 // false, AccDefault);
3169 // impt.declarationSourceEnd = impt.sourceEnd;
3170 // impt.declarationEnd = impt.declarationSourceEnd;
3171 // //endPosition is just before the ;
3172 // impt.declarationSourceStart = this.intStack[this.intPtr--];
3174 case TokenNameinclude_once :
3175 // T_INCLUDE_ONCE expr
3179 case TokenNameeval :
3180 // T_EVAL '(' expr ')'
3182 if (token != TokenNameLPAREN) {
3183 throwSyntaxError("'(' expected after keyword 'eval'");
3187 if (token != TokenNameRPAREN) {
3188 throwSyntaxError("')' expected after keyword 'eval'");
3192 case TokenNamerequire :
3197 case TokenNamerequire_once :
3198 // T_REQUIRE_ONCE expr
3204 private void isset_variables() {
3206 // | isset_variables ','
3207 if (token == TokenNameRPAREN) {
3208 throwSyntaxError("Variable expected after keyword 'isset'");
3212 if (token == TokenNameCOMMA) {
3219 private boolean common_scalar() {
3223 // | T_CONSTANT_ENCAPSED_STRING
3230 case TokenNameIntegerLiteral :
3233 case TokenNameDoubleLiteral :
3236 case TokenNameStringLiteral :
3239 case TokenNameStringConstant :
3242 case TokenNameStringInterpolated :
3245 case TokenNameFILE :
3248 case TokenNameLINE :
3251 case TokenNameCLASS_C :
3254 case TokenNameMETHOD_C :
3257 case TokenNameFUNC_C :
3263 private void scalar() {
3266 //| T_STRING_VARNAME
3269 //| '"' encaps_list '"'
3270 //| '\'' encaps_list '\''
3271 //| T_START_HEREDOC encaps_list T_END_HEREDOC
3272 throwSyntaxError("Not yet implemented (scalar).");
3274 private void static_scalar() {
3275 // static_scalar: /* compile-time evaluated scalars */
3278 // | '+' static_scalar
3279 // | '-' static_scalar
3280 // | T_ARRAY '(' static_array_pair_list ')'
3281 // | static_class_constant
3282 if (common_scalar()) {
3286 case TokenNameIdentifier :
3288 // static_class_constant:
3289 // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
3290 if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
3292 if (token == TokenNameIdentifier) {
3295 throwSyntaxError("Identifier expected after '::' operator.");
3299 case TokenNameEncapsedString0 :
3301 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3302 while (scanner.currentCharacter != '`') {
3303 if (scanner.currentCharacter == '\\') {
3304 scanner.currentPosition++;
3306 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3309 } catch (IndexOutOfBoundsException e) {
3310 throwSyntaxError("'`' expected at end of static string.");
3313 case TokenNameEncapsedString1 :
3315 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3316 while (scanner.currentCharacter != '\'') {
3317 if (scanner.currentCharacter == '\\') {
3318 scanner.currentPosition++;
3320 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3323 } catch (IndexOutOfBoundsException e) {
3324 throwSyntaxError("'\'' expected at end of static string.");
3327 case TokenNameEncapsedString2 :
3329 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3330 while (scanner.currentCharacter != '"') {
3331 if (scanner.currentCharacter == '\\') {
3332 scanner.currentPosition++;
3334 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
3337 } catch (IndexOutOfBoundsException e) {
3338 throwSyntaxError("'\"' expected at end of static string.");
3341 case TokenNamePLUS :
3345 case TokenNameMINUS :
3349 case TokenNamearray :
3351 if (token != TokenNameLPAREN) {
3352 throwSyntaxError("'(' expected after keyword 'array'");
3355 if (token == TokenNameRPAREN) {
3359 non_empty_static_array_pair_list();
3360 if (token != TokenNameRPAREN) {
3361 throwSyntaxError("')' expected after keyword 'array'");
3365 // case TokenNamenull :
3368 // case TokenNamefalse :
3371 // case TokenNametrue :
3375 throwSyntaxError("Static scalar/constant expected.");
3378 private void non_empty_static_array_pair_list() {
3379 // non_empty_static_array_pair_list:
3380 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
3382 //| non_empty_static_array_pair_list ',' static_scalar
3383 //| static_scalar T_DOUBLE_ARROW static_scalar
3387 if (token == TokenNameEQUAL_GREATER) {
3391 if (token != TokenNameCOMMA) {
3395 if (token == TokenNameRPAREN) {
3400 public void reportSyntaxError() { //int act, int currentKind, int
3402 /* remember current scanner position */
3403 int startPos = scanner.startPosition;
3404 int currentPos = scanner.currentPosition;
3405 // String[] expectings;
3406 // String tokenName = name[symbol_index[currentKind]];
3407 //fetch all "accurate" possible terminals that could recover the error
3408 // int start, end = start = asi(stack[stateStackTop]);
3409 // while (asr[end] != 0)
3411 // int length = end - start;
3412 // expectings = new String[length];
3413 // if (length != 0) {
3414 // char[] indexes = new char[length];
3415 // System.arraycopy(asr, start, indexes, 0, length);
3416 // for (int i = 0; i < length; i++) {
3417 // expectings[i] = name[symbol_index[indexes[i]]];
3420 //if the pb is an EOF, try to tell the user that they are some
3421 // if (tokenName.equals(UNEXPECTED_EOF)) {
3422 // if (!this.checkAndReportBracketAnomalies(problemReporter())) {
3423 // char[] tokenSource;
3425 // tokenSource = this.scanner.getCurrentTokenSource();
3426 // } catch (Exception e) {
3427 // tokenSource = new char[] {};
3429 // problemReporter().parseError(
3430 // this.scanner.startPosition,
3431 // this.scanner.currentPosition - 1,
3436 // } else { //the next test is HEAVILY grammar DEPENDENT.
3437 // if ((length == 14)
3438 // && (expectings[0] == "=") //$NON-NLS-1$
3439 // && (expectings[1] == "*=") //$NON-NLS-1$
3440 // && (expressionPtr > -1)) {
3441 // switch(currentKind) {
3442 // case TokenNameSEMICOLON:
3443 // case TokenNamePLUS:
3444 // case TokenNameMINUS:
3445 // case TokenNameDIVIDE:
3446 // case TokenNameREMAINDER:
3447 // case TokenNameMULTIPLY:
3448 // case TokenNameLEFT_SHIFT:
3449 // case TokenNameRIGHT_SHIFT:
3450 //// case TokenNameUNSIGNED_RIGHT_SHIFT:
3451 // case TokenNameLESS:
3452 // case TokenNameGREATER:
3453 // case TokenNameLESS_EQUAL:
3454 // case TokenNameGREATER_EQUAL:
3455 // case TokenNameEQUAL_EQUAL:
3456 // case TokenNameNOT_EQUAL:
3457 // case TokenNameXOR:
3458 // case TokenNameAND:
3459 // case TokenNameOR:
3460 // case TokenNameOR_OR:
3461 // case TokenNameAND_AND:
3462 // // the ; is not the expected token ==> it ends a statement when an
3463 // expression is not ended
3464 // problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
3466 // case TokenNameRBRACE :
3467 // problemReporter().missingSemiColon(expressionStack[expressionPtr]);
3470 // char[] tokenSource;
3472 // tokenSource = this.scanner.getCurrentTokenSource();
3473 // } catch (Exception e) {
3474 // tokenSource = new char[] {};
3476 // problemReporter().parseError(
3477 // this.scanner.startPosition,
3478 // this.scanner.currentPosition - 1,
3482 // this.checkAndReportBracketAnomalies(problemReporter());
3487 tokenSource = this.scanner.getCurrentTokenSource();
3488 } catch (Exception e) {
3489 tokenSource = new char[]{};
3491 // problemReporter().parseError(
3492 // this.scanner.startPosition,
3493 // this.scanner.currentPosition - 1,
3497 this.checkAndReportBracketAnomalies(problemReporter());
3500 /* reset scanner where it was */
3501 scanner.startPosition = startPos;
3502 scanner.currentPosition = currentPos;
3504 public static final int RoundBracket = 0;
3505 public static final int SquareBracket = 1;
3506 public static final int CurlyBracket = 2;
3507 public static final int BracketKinds = 3;
3508 protected int[] nestedMethod; //the ptr is nestedType
3509 protected int nestedType, dimensions;
3511 final static int AstStackIncrement = 100;
3512 protected int astPtr;
3513 protected AstNode[] astStack = new AstNode[AstStackIncrement];
3514 protected int astLengthPtr;
3515 protected int[] astLengthStack;
3516 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
3517 public CompilationUnitDeclaration compilationUnit; /*
3521 protected ReferenceContext referenceContext;
3522 protected ProblemReporter problemReporter;
3523 protected CompilerOptions options;
3524 // protected CompilationResult compilationResult;
3526 * Returns this parser's problem reporter initialized with its reference
3527 * context. Also it is assumed that a problem is going to be reported, so
3528 * initializes the compilation result's line positions.
3530 public ProblemReporter problemReporter() {
3531 if (scanner.recordLineSeparator) {
3532 compilationUnit.compilationResult.lineSeparatorPositions = scanner
3535 problemReporter.referenceContext = referenceContext;
3536 return problemReporter;
3539 * Reconsider the entire source looking for inconsistencies in {} () []
3541 public boolean checkAndReportBracketAnomalies(
3542 ProblemReporter problemReporter) {
3543 scanner.wasAcr = false;
3544 boolean anomaliesDetected = false;
3546 char[] source = scanner.source;
3547 int[] leftCount = {0, 0, 0};
3548 int[] rightCount = {0, 0, 0};
3549 int[] depths = {0, 0, 0};
3550 int[][] leftPositions = new int[][]{new int[10], new int[10],
3552 int[][] leftDepths = new int[][]{new int[10], new int[10],
3554 int[][] rightPositions = new int[][]{new int[10], new int[10],
3556 int[][] rightDepths = new int[][]{new int[10], new int[10],
3558 scanner.currentPosition = scanner.initialPosition; //starting
3560 // (first-zero-based
3562 while (scanner.currentPosition < scanner.eofPosition) { //loop for
3567 // ---------Consume white space and handles
3568 // startPosition---------
3569 boolean isWhiteSpace;
3571 scanner.startPosition = scanner.currentPosition;
3572 // if (((scanner.currentCharacter =
3573 // source[scanner.currentPosition++]) == '\\') &&
3574 // (source[scanner.currentPosition] == 'u')) {
3575 // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
3577 if (scanner.recordLineSeparator
3578 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3579 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3580 // only record line positions we have not
3582 scanner.pushLineSeparator();
3585 isWhiteSpace = CharOperation
3586 .isWhitespace(scanner.currentCharacter);
3588 } while (isWhiteSpace
3589 && (scanner.currentPosition < scanner.eofPosition));
3590 // -------consume token until } is found---------
3591 switch (scanner.currentCharacter) {
3593 int index = leftCount[CurlyBracket]++;
3594 if (index == leftPositions[CurlyBracket].length) {
3597 leftPositions[CurlyBracket],
3599 (leftPositions[CurlyBracket] = new int[index * 2]),
3603 leftDepths[CurlyBracket],
3605 (leftDepths[CurlyBracket] = new int[index * 2]),
3608 leftPositions[CurlyBracket][index] = scanner.startPosition;
3609 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
3613 int index = rightCount[CurlyBracket]++;
3614 if (index == rightPositions[CurlyBracket].length) {
3617 rightPositions[CurlyBracket],
3619 (rightPositions[CurlyBracket] = new int[index * 2]),
3623 rightDepths[CurlyBracket],
3625 (rightDepths[CurlyBracket] = new int[index * 2]),
3628 rightPositions[CurlyBracket][index] = scanner.startPosition;
3629 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
3633 int index = leftCount[RoundBracket]++;
3634 if (index == leftPositions[RoundBracket].length) {
3637 leftPositions[RoundBracket],
3639 (leftPositions[RoundBracket] = new int[index * 2]),
3643 leftDepths[RoundBracket],
3645 (leftDepths[RoundBracket] = new int[index * 2]),
3648 leftPositions[RoundBracket][index] = scanner.startPosition;
3649 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
3653 int index = rightCount[RoundBracket]++;
3654 if (index == rightPositions[RoundBracket].length) {
3657 rightPositions[RoundBracket],
3659 (rightPositions[RoundBracket] = new int[index * 2]),
3663 rightDepths[RoundBracket],
3665 (rightDepths[RoundBracket] = new int[index * 2]),
3668 rightPositions[RoundBracket][index] = scanner.startPosition;
3669 rightDepths[RoundBracket][index] = --depths[RoundBracket];
3673 int index = leftCount[SquareBracket]++;
3674 if (index == leftPositions[SquareBracket].length) {
3677 leftPositions[SquareBracket],
3679 (leftPositions[SquareBracket] = new int[index * 2]),
3683 leftDepths[SquareBracket],
3685 (leftDepths[SquareBracket] = new int[index * 2]),
3688 leftPositions[SquareBracket][index] = scanner.startPosition;
3689 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
3693 int index = rightCount[SquareBracket]++;
3694 if (index == rightPositions[SquareBracket].length) {
3697 rightPositions[SquareBracket],
3699 (rightPositions[SquareBracket] = new int[index * 2]),
3703 rightDepths[SquareBracket],
3705 (rightDepths[SquareBracket] = new int[index * 2]),
3708 rightPositions[SquareBracket][index] = scanner.startPosition;
3709 rightDepths[SquareBracket][index] = --depths[SquareBracket];
3713 if (scanner.getNextChar('\\')) {
3714 scanner.scanEscapeCharacter();
3715 } else { // consume next character
3716 scanner.unicodeAsBackSlash = false;
3717 // if (((scanner.currentCharacter =
3718 // source[scanner.currentPosition++]) ==
3720 // (source[scanner.currentPosition] ==
3722 // scanner.getNextUnicodeChar();
3724 if (scanner.withoutUnicodePtr != 0) {
3725 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3729 scanner.getNextChar('\'');
3733 // consume next character
3734 scanner.unicodeAsBackSlash = false;
3735 // if (((scanner.currentCharacter =
3736 // source[scanner.currentPosition++]) == '\\') &&
3737 // (source[scanner.currentPosition] == 'u')) {
3738 // scanner.getNextUnicodeChar();
3740 if (scanner.withoutUnicodePtr != 0) {
3741 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3744 while (scanner.currentCharacter != '"') {
3745 if (scanner.currentCharacter == '\r') {
3746 if (source[scanner.currentPosition] == '\n')
3747 scanner.currentPosition++;
3748 break; // the string cannot go further that
3751 if (scanner.currentCharacter == '\n') {
3752 break; // the string cannot go further that
3755 if (scanner.currentCharacter == '\\') {
3756 scanner.scanEscapeCharacter();
3758 // consume next character
3759 scanner.unicodeAsBackSlash = false;
3760 // if (((scanner.currentCharacter =
3761 // source[scanner.currentPosition++]) == '\\')
3762 // && (source[scanner.currentPosition] == 'u'))
3764 // scanner.getNextUnicodeChar();
3766 if (scanner.withoutUnicodePtr != 0) {
3767 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3774 if ((test = scanner.getNextChar('/', '*')) == 0) { //line
3777 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3778 && (source[scanner.currentPosition] == 'u')) {
3779 //-------------unicode traitement
3781 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3782 scanner.currentPosition++;
3783 while (source[scanner.currentPosition] == 'u') {
3784 scanner.currentPosition++;
3787 .getNumericValue(source[scanner.currentPosition++])) > 15
3790 .getNumericValue(source[scanner.currentPosition++])) > 15
3793 .getNumericValue(source[scanner.currentPosition++])) > 15
3796 .getNumericValue(source[scanner.currentPosition++])) > 15
3797 || c4 < 0) { //error don't
3800 scanner.currentCharacter = 'A';
3801 } //something different from \n and \r
3803 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3806 while (scanner.currentCharacter != '\r'
3807 && scanner.currentCharacter != '\n') {
3809 scanner.startPosition = scanner.currentPosition;
3810 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3811 && (source[scanner.currentPosition] == 'u')) {
3812 //-------------unicode traitement
3814 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3815 scanner.currentPosition++;
3816 while (source[scanner.currentPosition] == 'u') {
3817 scanner.currentPosition++;
3820 .getNumericValue(source[scanner.currentPosition++])) > 15
3823 .getNumericValue(source[scanner.currentPosition++])) > 15
3826 .getNumericValue(source[scanner.currentPosition++])) > 15
3829 .getNumericValue(source[scanner.currentPosition++])) > 15
3830 || c4 < 0) { //error don't
3833 scanner.currentCharacter = 'A';
3834 } //something different from \n
3837 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3841 if (scanner.recordLineSeparator
3842 && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
3843 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
3844 // only record line positions we
3845 // have not recorded yet
3846 scanner.pushLineSeparator();
3847 if (this.scanner.taskTags != null) {
3851 .getCurrentTokenStartPosition(),
3853 .getCurrentTokenEndPosition());
3859 if (test > 0) { //traditional and annotation
3861 boolean star = false;
3862 // consume next character
3863 scanner.unicodeAsBackSlash = false;
3864 // if (((scanner.currentCharacter =
3865 // source[scanner.currentPosition++]) ==
3867 // (source[scanner.currentPosition] ==
3869 // scanner.getNextUnicodeChar();
3871 if (scanner.withoutUnicodePtr != 0) {
3872 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
3875 if (scanner.currentCharacter == '*') {
3879 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3880 && (source[scanner.currentPosition] == 'u')) {
3881 //-------------unicode traitement
3883 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3884 scanner.currentPosition++;
3885 while (source[scanner.currentPosition] == 'u') {
3886 scanner.currentPosition++;
3889 .getNumericValue(source[scanner.currentPosition++])) > 15
3892 .getNumericValue(source[scanner.currentPosition++])) > 15
3895 .getNumericValue(source[scanner.currentPosition++])) > 15
3898 .getNumericValue(source[scanner.currentPosition++])) > 15
3899 || c4 < 0) { //error don't
3902 scanner.currentCharacter = 'A';
3903 } //something different from * and /
3905 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3908 //loop until end of comment */
3909 while ((scanner.currentCharacter != '/')
3911 star = scanner.currentCharacter == '*';
3913 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
3914 && (source[scanner.currentPosition] == 'u')) {
3915 //-------------unicode traitement
3917 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
3918 scanner.currentPosition++;
3919 while (source[scanner.currentPosition] == 'u') {
3920 scanner.currentPosition++;
3923 .getNumericValue(source[scanner.currentPosition++])) > 15
3926 .getNumericValue(source[scanner.currentPosition++])) > 15
3929 .getNumericValue(source[scanner.currentPosition++])) > 15
3932 .getNumericValue(source[scanner.currentPosition++])) > 15
3933 || c4 < 0) { //error don't
3936 scanner.currentCharacter = 'A';
3937 } //something different from * and
3940 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
3944 if (this.scanner.taskTags != null) {
3948 .getCurrentTokenStartPosition(),
3950 .getCurrentTokenEndPosition());
3958 .isPHPIdentifierStart(scanner.currentCharacter)) {
3959 scanner.scanIdentifierOrKeyword(false);
3962 if (Character.isDigit(scanner.currentCharacter)) {
3963 scanner.scanNumber(false);
3967 //-----------------end switch while
3968 // try--------------------
3969 } catch (IndexOutOfBoundsException e) {
3970 break; // read until EOF
3971 } catch (InvalidInputException e) {
3972 return false; // no clue
3975 if (scanner.recordLineSeparator) {
3976 // compilationUnit.compilationResult.lineSeparatorPositions =
3977 // scanner.getLineEnds();
3979 // check placement anomalies against other kinds of brackets
3980 for (int kind = 0; kind < BracketKinds; kind++) {
3981 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
3982 int start = leftPositions[kind][leftIndex]; // deepest
3984 // find matching closing bracket
3985 int depth = leftDepths[kind][leftIndex];
3987 for (int i = 0; i < rightCount[kind]; i++) {
3988 int pos = rightPositions[kind][i];
3989 // want matching bracket further in source with same
3991 if ((pos > start) && (depth == rightDepths[kind][i])) {
3996 if (end < 0) { // did not find a good closing match
3997 problemReporter.unmatchedBracket(start,
3999 compilationUnit.compilationResult);
4002 // check if even number of opening/closing other brackets
4003 // in between this pair of brackets
4005 for (int otherKind = 0; (balance == 0)
4006 && (otherKind < BracketKinds); otherKind++) {
4007 for (int i = 0; i < leftCount[otherKind]; i++) {
4008 int pos = leftPositions[otherKind][i];
4009 if ((pos > start) && (pos < end))
4012 for (int i = 0; i < rightCount[otherKind]; i++) {
4013 int pos = rightPositions[otherKind][i];
4014 if ((pos > start) && (pos < end))
4018 problemReporter.unmatchedBracket(start,
4020 compilationUnit.compilationResult); //bracket
4026 // too many opening brackets ?
4027 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
4028 anomaliesDetected = true;
4031 leftPositions[kind][leftCount[kind] - i - 1],
4033 compilationUnit.compilationResult);
4035 // too many closing brackets ?
4036 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
4037 anomaliesDetected = true;
4039 .unmatchedBracket(rightPositions[kind][i],
4041 compilationUnit.compilationResult);
4043 if (anomaliesDetected)
4046 return anomaliesDetected;
4047 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
4048 return anomaliesDetected;
4049 } catch (NullPointerException e) { // jdk1.2.2 jit bug
4050 return anomaliesDetected;
4053 protected void pushOnAstLengthStack(int pos) {
4055 astLengthStack[++astLengthPtr] = pos;
4056 } catch (IndexOutOfBoundsException e) {
4057 int oldStackLength = astLengthStack.length;
4058 int[] oldPos = astLengthStack;
4059 astLengthStack = new int[oldStackLength + StackIncrement];
4060 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
4061 astLengthStack[astLengthPtr] = pos;
4064 protected void pushOnAstStack(AstNode node) {
4066 * add a new obj on top of the ast stack
4069 astStack[++astPtr] = node;
4070 } catch (IndexOutOfBoundsException e) {
4071 int oldStackLength = astStack.length;
4072 AstNode[] oldStack = astStack;
4073 astStack = new AstNode[oldStackLength + AstStackIncrement];
4074 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
4075 astPtr = oldStackLength;
4076 astStack[astPtr] = node;
4079 astLengthStack[++astLengthPtr] = 1;
4080 } catch (IndexOutOfBoundsException e) {
4081 int oldStackLength = astLengthStack.length;
4082 int[] oldPos = astLengthStack;
4083 astLengthStack = new int[oldStackLength + AstStackIncrement];
4084 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
4085 astLengthStack[astLengthPtr] = 1;
4089 protected void resetModifiers() {
4090 this.modifiers = AccDefault;
4091 this.modifiersSourceStart = -1; // <-- see comment into
4092 // modifiersFlag(int)
4093 this.scanner.commentPtr = -1;