1 /***********************************************************************************************************************************
 
   2  * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the
 
   3  * terms of the Common Public License v1.0 which accompanies this distribution, and is available at
 
   4  * http://www.eclipse.org/legal/cpl-v10.html
 
   6  * Contributors: www.phpeclipse.de
 
   7  **********************************************************************************************************************************/
 
   8 package net.sourceforge.phpdt.internal.compiler.parser;
 
  10 import java.util.ArrayList;
 
  11 import java.util.HashMap;
 
  12 import java.util.HashSet;
 
  14 import net.sourceforge.phpdt.core.compiler.CharOperation;
 
  15 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
  16 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 
  17 import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression;
 
  18 import net.sourceforge.phpdt.internal.compiler.ast.ASTNode;
 
  19 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
 
  20 import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression;
 
  21 import net.sourceforge.phpdt.internal.compiler.ast.Block;
 
  22 import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement;
 
  23 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
 
  24 import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
 
  25 import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement;
 
  26 import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression;
 
  27 import net.sourceforge.phpdt.internal.compiler.ast.Expression;
 
  28 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
 
  29 import net.sourceforge.phpdt.internal.compiler.ast.FieldReference;
 
  30 import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
 
  31 import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
 
  32 import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
 
  33 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
 
  34 import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression;
 
  35 import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
 
  36 import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
 
  37 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
 
  38 import net.sourceforge.phpdt.internal.compiler.ast.Statement;
 
  39 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
 
  40 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ;
 
  41 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ;
 
  42 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
 
  43 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
 
  44 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
 
  45 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
 
  46 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
 
  47 import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
 
  48 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 
  49 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
 
  50 import net.sourceforge.phpdt.internal.compiler.util.Util;
 
  51 import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil;
 
  52 import net.sourceforge.phpeclipse.builder.IdentifierIndexManager;
 
  53 import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil;
 
  55 import org.eclipse.core.resources.IFile;
 
  56 import org.eclipse.core.resources.IProject;
 
  57 import org.eclipse.core.resources.IResource;
 
  58 import org.eclipse.core.runtime.IPath;
 
  60 public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation {
 
  61         protected final static int StackIncrement = 255;
 
  63         protected int stateStackTop;
 
  65         // protected int[] stack = new int[StackIncrement];
 
  67         public int firstToken; // handle for multiple parsing goals
 
  69         public int lastAct; // handle for multiple parsing goals
 
  71         // protected RecoveredElement currentElement;
 
  73         public static boolean VERBOSE_RECOVERY = false;
 
  75         protected boolean diet = false; // tells the scanner to jump over some
 
  78          * the PHP token scanner
 
  80         public Scanner scanner;
 
  84         protected int modifiers;
 
  86         protected int modifiersSourceStart;
 
  88         protected Parser(ProblemReporter problemReporter) {
 
  89                 this.problemReporter = problemReporter;
 
  90                 this.options = problemReporter.options;
 
  91                 this.token = TokenNameEOF;
 
  92                 this.initializeScanner();
 
  95         public void setFileToParse(IFile fileToParse) {
 
  96                 this.token = TokenNameEOF;
 
  97                 this.initializeScanner();
 
 101          * ClassDeclaration Constructor.
 
 105          *          Description of Parameter
 
 108         public Parser(IFile fileToParse) {
 
 109                 // if (keywordMap == null) {
 
 110                 // keywordMap = new HashMap();
 
 111                 // for (int i = 0; i < PHP_KEYWORS.length; i++) {
 
 112                 // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
 
 115                 // this.currentPHPString = 0;
 
 116                 // PHPParserSuperclass.fileToParse = fileToParse;
 
 117                 // this.phpList = null;
 
 118                 this.includesList = null;
 
 120                 this.token = TokenNameEOF;
 
 122                 // this.rowCount = 1;
 
 123                 // this.columnCount = 0;
 
 124                 // this.phpEnd = false;
 
 126                 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 */, true/* isTaskCaseSensitive */);
 
 136          * Create marker for the parse error
 
 138         // private void setMarker(String message, int charStart, int charEnd, int
 
 140         // setMarker(fileToParse, message, charStart, charEnd, errorLevel);
 
 143          * This method will throw the SyntaxError. It will add the good lines and
 
 144          * columns to the Error
 
 148          * @throws SyntaxError
 
 151         private void throwSyntaxError(String error) {
 
 152                 int problemStartPosition = scanner.getCurrentTokenStartPosition();
 
 153                 int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1;
 
 154                 if (scanner.source.length <= problemEndPosition && problemEndPosition > 0) {
 
 155                         problemEndPosition = scanner.source.length - 1;
 
 156                         if (problemStartPosition > 0 && problemStartPosition >= problemEndPosition && problemEndPosition > 0) {
 
 157                                 problemStartPosition = problemEndPosition - 1;
 
 160                 throwSyntaxError(error, problemStartPosition, problemEndPosition);
 
 164          * This method will throw the SyntaxError. It will add the good lines and
 
 165          * columns to the Error
 
 169          * @throws SyntaxError
 
 172         // private void throwSyntaxError(String error, int startRow) {
 
 173         // throw new SyntaxError(startRow, 0, " ", error);
 
 175         private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
 
 176                 if (referenceContext != null) {
 
 177                         problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext,
 
 178                                         compilationUnit.compilationResult);
 
 180                 throw new SyntaxError(1, 0, " ", error);
 
 183         private void reportSyntaxError(String error) {
 
 184                 int problemStartPosition = scanner.getCurrentTokenStartPosition();
 
 185                 int problemEndPosition = scanner.getCurrentTokenEndPosition();
 
 186                 reportSyntaxError(error, problemStartPosition, problemEndPosition + 1);
 
 189         private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
 
 190                 if (referenceContext != null) {
 
 191                         problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext,
 
 192                                         compilationUnit.compilationResult);
 
 196         // private void reportSyntaxWarning(String error, int problemStartPosition,
 
 197         // int problemEndPosition) {
 
 198         // if (referenceContext != null) {
 
 199         // problemReporter.phpParsingWarning(new String[] { error },
 
 200         // problemStartPosition, problemEndPosition, referenceContext,
 
 201         // compilationUnit.compilationResult);
 
 206          * gets the next token from input
 
 208         private void getNextToken() {
 
 210                         token = scanner.getNextToken();
 
 212                                 int currentEndPosition = scanner.getCurrentTokenEndPosition();
 
 213                                 int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
 214                                 System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
 
 215                                 System.out.println(scanner.toStringAction(token));
 
 217                 } catch (InvalidInputException e) {
 
 218                         token = TokenNameERROR;
 
 219                         String detailedMessage = e.getMessage();
 
 221                         if (detailedMessage == Scanner.UNTERMINATED_STRING) {
 
 222                                 throwSyntaxError("Unterminated string.");
 
 223                         } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) {
 
 224                                 throwSyntaxError("Unterminated commment.");
 
 230         public void init(String s) {
 
 232                 this.token = TokenNameEOF;
 
 233                 this.includesList = new ArrayList();
 
 235                 // this.rowCount = 1;
 
 236                 // this.columnCount = 0;
 
 237                 // this.phpEnd = false;
 
 238                 // this.phpMode = false;
 
 239                 /* scanner initialization */
 
 240                 scanner.setSource(s.toCharArray());
 
 241                 scanner.setPHPMode(false);
 
 245         protected void initialize(boolean phpMode) {
 
 246                 initialize(phpMode, null);
 
 249         protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) {
 
 250                 compilationUnit = null;
 
 251                 referenceContext = null;
 
 252                 this.includesList = new ArrayList();
 
 253                 // this.indexManager = indexManager;
 
 255                 this.token = TokenNameEOF;
 
 257                 // this.rowCount = 1;
 
 258                 // this.columnCount = 0;
 
 259                 // this.phpEnd = false;
 
 260                 // this.phpMode = phpMode;
 
 261                 scanner.setPHPMode(phpMode);
 
 266          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 269         public void parse(String s) {
 
 274          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 277         public void parse(String s, HashMap variables) {
 
 278                 fMethodVariables = variables;
 
 279                 fStackUnassigned = new ArrayList();
 
 285          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 288         protected void parse() {
 
 289                 if (scanner.compilationUnit != null) {
 
 290                         IResource resource = scanner.compilationUnit.getResource();
 
 291                         if (resource != null && resource instanceof IFile) {
 
 292                                 // set the package name
 
 293                                 consumePackageDeclarationName((IFile) resource);
 
 299                                 if (token != TokenNameEOF && token != TokenNameERROR) {
 
 302                                 if (token != TokenNameEOF) {
 
 303                                         if (token == TokenNameERROR) {
 
 304                                                 throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
 
 306                                         if (token == TokenNameRPAREN) {
 
 307                                                 throwSyntaxError("Too many closing ')'; end-of-file not reached.");
 
 309                                         if (token == TokenNameRBRACE) {
 
 310                                                 throwSyntaxError("Too many closing '}'; end-of-file not reached.");
 
 312                                         if (token == TokenNameRBRACKET) {
 
 313                                                 throwSyntaxError("Too many closing ']'; end-of-file not reached.");
 
 315                                         if (token == TokenNameLPAREN) {
 
 316                                                 throwSyntaxError("Read character '('; end-of-file not reached.");
 
 318                                         if (token == TokenNameLBRACE) {
 
 319                                                 throwSyntaxError("Read character '{';  end-of-file not reached.");
 
 321                                         if (token == TokenNameLBRACKET) {
 
 322                                                 throwSyntaxError("Read character '[';  end-of-file not reached.");
 
 324                                         throwSyntaxError("End-of-file not reached.");
 
 327                         } catch (SyntaxError syntaxError) {
 
 328                                 // syntaxError.printStackTrace();
 
 337          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 340         public void parseFunction(String s, HashMap variables) {
 
 342                 scanner.phpMode = true;
 
 343                 parseFunction(variables);
 
 347          * Parses a string with php tags i.e. '<body> <?php phpinfo() ?>
 
 350         protected void parseFunction(HashMap variables) {
 
 352                 boolean hasModifiers = member_modifiers();
 
 353                 if (token == TokenNamefunction) {
 
 355                                 checkAndSetModifiers(AccPublic);
 
 357                         this.fMethodVariables = variables;
 
 359                         MethodDeclaration methodDecl = new MethodDeclaration(null);
 
 360                         methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
 361                         methodDecl.modifiers = this.modifiers;
 
 362                         methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
 
 365                                 functionDefinition(methodDecl);
 
 366                         } catch (SyntaxError sytaxErr1) {
 
 369                                 int sourceEnd = methodDecl.sourceEnd;
 
 370                                 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
 
 371                                         sourceEnd = methodDecl.declarationSourceStart + 1;
 
 373                                 methodDecl.sourceEnd = sourceEnd;
 
 374                                 methodDecl.declarationSourceEnd = sourceEnd;
 
 379         protected CompilationUnitDeclaration endParse(int act) {
 
 383                 // if (currentElement != null) {
 
 384                 // currentElement.topElement().updateParseTree();
 
 385                 // if (VERBOSE_RECOVERY) {
 
 386                 // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
 
 387                 // System.out.println("--------------------------"); //$NON-NLS-1$
 
 388                 // System.out.println(compilationUnit);
 
 389                 // System.out.println("----------------------------------"); //$NON-NLS-1$
 
 392                 if (diet & VERBOSE_RECOVERY) {
 
 393                         System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
 
 394                         System.out.println("--------------------------"); //$NON-NLS-1$
 
 395                         System.out.println(compilationUnit);
 
 396                         System.out.println("----------------------------------"); //$NON-NLS-1$
 
 399                 if (scanner.recordLineSeparator) {
 
 400                         compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
 
 402                 if (scanner.taskTags != null) {
 
 403                         for (int i = 0; i < scanner.foundTaskCount; i++) {
 
 404                                 problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]),
 
 405                                                 scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]),
 
 406                                                 scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]);
 
 409                 compilationUnit.imports = new ImportReference[includesList.size()];
 
 410                 for (int i = 0; i < includesList.size(); i++) {
 
 411                         compilationUnit.imports[i] = (ImportReference) includesList.get(i);
 
 413                 return compilationUnit;
 
 416         private Block statementList() {
 
 417                 boolean branchStatement = false;
 
 419                 int blockStart = scanner.getCurrentTokenStartPosition();
 
 420                 ArrayList blockStatements = new ArrayList();
 
 423                                 statement = statement();
 
 424                                 blockStatements.add(statement);
 
 425                                 if (token == TokenNameEOF) {
 
 428                                 if (branchStatement && statement != null) {
 
 429                                         // reportSyntaxError("Unreachable code", statement.sourceStart,
 
 430                                         // statement.sourceEnd);
 
 431                                         problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()), statement.sourceStart,
 
 432                                                         statement.sourceEnd, referenceContext, compilationUnit.compilationResult);
 
 434                                 if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
 
 435                                                 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
 
 436                                                 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
 
 437                                                 || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
 
 438                                         return createBlock(blockStart, blockStatements);
 
 440                                 branchStatement = checkUnreachableStatements(statement);
 
 441                         } catch (SyntaxError sytaxErr1) {
 
 442                                 // if an error occured,
 
 443                                 // try to find keywords
 
 444                                 // to parse the rest of the string
 
 445                                 boolean tokenize = scanner.tokenizeStrings;
 
 447                                         scanner.tokenizeStrings = true;
 
 450                                         while (token != TokenNameEOF) {
 
 451                                                 if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse)
 
 452                                                                 || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor)
 
 453                                                                 || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch)
 
 454                                                                 || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) {
 
 455                                                         return createBlock(blockStart, blockStatements);
 
 457                                                 if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile
 
 458                                                                 || token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak
 
 459                                                                 || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameglobal
 
 460                                                                 || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction || token == TokenNamedeclare
 
 461                                                                 || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow || token == TokenNamefinal
 
 462                                                                 || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
 
 465                                                 // System.out.println(scanner.toStringAction(token));
 
 467                                                 // System.out.println(scanner.toStringAction(token));
 
 469                                         if (token == TokenNameEOF) {
 
 473                                         scanner.tokenizeStrings = tokenize;
 
 483         private boolean checkUnreachableStatements(Statement statement) {
 
 484                 if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) {
 
 486                 } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) {
 
 494          * @param blockStatements
 
 497         private Block createBlock(int blockStart, ArrayList blockStatements) {
 
 498                 int blockEnd = scanner.getCurrentTokenEndPosition();
 
 499                 Block b = Block.EmptyWith(blockStart, blockEnd);
 
 500                 b.statements = new Statement[blockStatements.size()];
 
 501                 blockStatements.toArray(b.statements);
 
 505         private void functionBody(MethodDeclaration methodDecl) {
 
 506                 // '{' [statement-list] '}'
 
 507                 if (token == TokenNameLBRACE) {
 
 510                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
 511                         throwSyntaxError("'{' expected in compound-statement.");
 
 513                 if (token != TokenNameRBRACE) {
 
 516                 if (token == TokenNameRBRACE) {
 
 517                         methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
 520                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
 521                         throwSyntaxError("'}' expected in compound-statement.");
 
 525         private Statement statement() {
 
 526                 Statement statement = null;
 
 527                 Expression expression;
 
 528                 int sourceStart = scanner.getCurrentTokenStartPosition();
 
 530                 if (token == TokenNameif) {
 
 531                         // T_IF '(' expr ')' statement elseif_list else_single
 
 532                         // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
 
 533                         // new_else_single T_ENDIF ';'
 
 535                         if (token == TokenNameLPAREN) {
 
 538                                 throwSyntaxError("'(' expected after 'if' keyword.");
 
 541                         if (token == TokenNameRPAREN) {
 
 544                                 throwSyntaxError("')' expected after 'if' condition.");
 
 546                         // create basic IfStatement
 
 547                         IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1);
 
 548                         if (token == TokenNameCOLON) {
 
 550                                 ifStatementColon(ifStatement);
 
 552                                 ifStatement(ifStatement);
 
 555                 } else if (token == TokenNameswitch) {
 
 557                         if (token == TokenNameLPAREN) {
 
 560                                 throwSyntaxError("'(' expected after 'switch' keyword.");
 
 563                         if (token == TokenNameRPAREN) {
 
 566                                 throwSyntaxError("')' expected after 'switch' condition.");
 
 570                 } else if (token == TokenNamefor) {
 
 572                         if (token == TokenNameLPAREN) {
 
 575                                 throwSyntaxError("'(' expected after 'for' keyword.");
 
 577                         if (token == TokenNameSEMICOLON) {
 
 581                                 if (token == TokenNameSEMICOLON) {
 
 584                                         throwSyntaxError("';' expected after 'for'.");
 
 587                         if (token == TokenNameSEMICOLON) {
 
 591                                 if (token == TokenNameSEMICOLON) {
 
 594                                         throwSyntaxError("';' expected after 'for'.");
 
 597                         if (token == TokenNameRPAREN) {
 
 601                                 if (token == TokenNameRPAREN) {
 
 604                                         throwSyntaxError("')' expected after 'for'.");
 
 609                 } else if (token == TokenNamewhile) {
 
 611                         if (token == TokenNameLPAREN) {
 
 614                                 throwSyntaxError("'(' expected after 'while' keyword.");
 
 617                         if (token == TokenNameRPAREN) {
 
 620                                 throwSyntaxError("')' expected after 'while' condition.");
 
 624                 } else if (token == TokenNamedo) {
 
 626                         if (token == TokenNameLBRACE) {
 
 628                                 if (token != TokenNameRBRACE) {
 
 631                                 if (token == TokenNameRBRACE) {
 
 634                                         throwSyntaxError("'}' expected after 'do' keyword.");
 
 639                         if (token == TokenNamewhile) {
 
 641                                 if (token == TokenNameLPAREN) {
 
 644                                         throwSyntaxError("'(' expected after 'while' keyword.");
 
 647                                 if (token == TokenNameRPAREN) {
 
 650                                         throwSyntaxError("')' expected after 'while' condition.");
 
 653                                 throwSyntaxError("'while' expected after 'do' keyword.");
 
 655                         if (token == TokenNameSEMICOLON) {
 
 658                                 if (token != TokenNameINLINE_HTML) {
 
 659                                         throwSyntaxError("';' expected after do-while statement.");
 
 664                 } else if (token == TokenNameforeach) {
 
 666                         if (token == TokenNameLPAREN) {
 
 669                                 throwSyntaxError("'(' expected after 'foreach' keyword.");
 
 672                         if (token == TokenNameas) {
 
 675                                 throwSyntaxError("'as' expected after 'foreach' exxpression.");
 
 679                         foreach_optional_arg();
 
 680                         if (token == TokenNameEQUAL_GREATER) {
 
 682                                 variable(false, false);
 
 684                         if (token == TokenNameRPAREN) {
 
 687                                 throwSyntaxError("')' expected after 'foreach' expression.");
 
 691                 } else if (token == TokenNamebreak) {
 
 694                         if (token != TokenNameSEMICOLON) {
 
 697                         if (token == TokenNameSEMICOLON) {
 
 698                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 701                                 if (token != TokenNameINLINE_HTML) {
 
 702                                         throwSyntaxError("';' expected after 'break'.");
 
 704                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 707                         return new BreakStatement(null, sourceStart, sourceEnd);
 
 708                 } else if (token == TokenNamecontinue) {
 
 711                         if (token != TokenNameSEMICOLON) {
 
 714                         if (token == TokenNameSEMICOLON) {
 
 715                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 718                                 if (token != TokenNameINLINE_HTML) {
 
 719                                         throwSyntaxError("';' expected after 'continue'.");
 
 721                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 724                         return new ContinueStatement(null, sourceStart, sourceEnd);
 
 725                 } else if (token == TokenNamereturn) {
 
 728                         if (token != TokenNameSEMICOLON) {
 
 731                         if (token == TokenNameSEMICOLON) {
 
 732                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 735                                 if (token != TokenNameINLINE_HTML) {
 
 736                                         throwSyntaxError("';' expected after 'return'.");
 
 738                                 sourceEnd = scanner.getCurrentTokenEndPosition();
 
 741                         return new ReturnStatement(expression, sourceStart, sourceEnd);
 
 742                 } else if (token == TokenNameecho) {
 
 745                         if (token == TokenNameSEMICOLON) {
 
 748                                 if (token != TokenNameINLINE_HTML ) {
 
 749                                         throwSyntaxError("';' expected after 'echo' statement.");
 
 754                 } else if (token == TokenNameINLINE_HTML) {
 
 755 //                      if (scanner.phpExpressionTag) {
 
 756 //                              // start of <?= ... ?> block
 
 759 //                              if (token == TokenNameSEMICOLON) {
 
 762 //                              if (token != TokenNameINLINE_HTML) {
 
 763 //                                      throwSyntaxError("Missing '?>' for open PHP expression block ('<?=').");
 
 769                 } else if (token == TokenNameglobal) {
 
 772                         if (token == TokenNameSEMICOLON) {
 
 775                                 if (token != TokenNameINLINE_HTML) {
 
 776                                         throwSyntaxError("';' expected after 'global' statement.");
 
 781                 } else if (token == TokenNamestatic) {
 
 784                         if (token == TokenNameSEMICOLON) {
 
 787                                 if (token != TokenNameINLINE_HTML) {
 
 788                                         throwSyntaxError("';' expected after 'static' statement.");
 
 793                 } else if (token == TokenNameunset) {
 
 795                         if (token == TokenNameLPAREN) {
 
 798                                 throwSyntaxError("'(' expected after 'unset' statement.");
 
 801                         if (token == TokenNameRPAREN) {
 
 804                                 throwSyntaxError("')' expected after 'unset' statement.");
 
 806                         if (token == TokenNameSEMICOLON) {
 
 809                                 if (token != TokenNameINLINE_HTML) {
 
 810                                         throwSyntaxError("';' expected after 'unset' statement.");
 
 815                 } else if (token == TokenNamefunction) {
 
 816                         MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
 
 817                         methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
 818                         methodDecl.modifiers = AccDefault;
 
 819                         methodDecl.type = MethodDeclaration.FUNCTION_DEFINITION;
 
 822                                 functionDefinition(methodDecl);
 
 824                                 sourceEnd = methodDecl.sourceEnd;
 
 825                                 if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
 
 826                                         sourceEnd = methodDecl.declarationSourceStart + 1;
 
 828                                 methodDecl.declarationSourceEnd = sourceEnd;
 
 829                                 methodDecl.sourceEnd = sourceEnd;
 
 832                 } else if (token == TokenNamedeclare) {
 
 833                         // T_DECLARE '(' declare_list ')' declare_statement
 
 835                         if (token != TokenNameLPAREN) {
 
 836                                 throwSyntaxError("'(' expected in 'declare' statement.");
 
 840                         if (token != TokenNameRPAREN) {
 
 841                                 throwSyntaxError("')' expected in 'declare' statement.");
 
 846                 } else if (token == TokenNametry) {
 
 848                         if (token != TokenNameLBRACE) {
 
 849                                 throwSyntaxError("'{' expected in 'try' statement.");
 
 853                         if (token != TokenNameRBRACE) {
 
 854                                 throwSyntaxError("'}' expected in 'try' statement.");
 
 858                 } else if (token == TokenNamecatch) {
 
 860                         if (token != TokenNameLPAREN) {
 
 861                                 throwSyntaxError("'(' expected in 'catch' statement.");
 
 864                         fully_qualified_class_name();
 
 865                         if (token != TokenNameVariable) {
 
 866                                 throwSyntaxError("Variable expected in 'catch' statement.");
 
 870                         if (token != TokenNameRPAREN) {
 
 871                                 throwSyntaxError("')' expected in 'catch' statement.");
 
 874                         if (token != TokenNameLBRACE) {
 
 875                                 throwSyntaxError("'{' expected in 'catch' statement.");
 
 878                         if (token != TokenNameRBRACE) {
 
 880                                 if (token != TokenNameRBRACE) {
 
 881                                         throwSyntaxError("'}' expected in 'catch' statement.");
 
 885                         additional_catches();
 
 887                 } else if (token == TokenNamethrow) {
 
 890                         if (token == TokenNameSEMICOLON) {
 
 893                                 throwSyntaxError("';' expected after 'throw' exxpression.");
 
 896                 } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
 
 898                                 TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
 
 899                                 typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
 900                                 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
 901                                 typeDecl.name = new char[] { ' ' };
 
 902                                 // default super class
 
 903                                 typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
 
 904                                 compilationUnit.types.add(typeDecl);
 
 905                                 pushOnAstStack(typeDecl);
 
 906                                 unticked_class_declaration_statement(typeDecl);
 
 914                         // throwSyntaxError("Unexpected keyword '" + keyword + "'");
 
 915                 } else if (token == TokenNameLBRACE) {
 
 917                         if (token != TokenNameRBRACE) {
 
 918                                 statement = statementList();
 
 920                         if (token == TokenNameRBRACE) {
 
 924                                 throwSyntaxError("'}' expected.");
 
 927                         if (token != TokenNameSEMICOLON) {
 
 930                         if (token == TokenNameSEMICOLON) {
 
 934                                 if (token == TokenNameRBRACE) {
 
 935                                         reportSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
 
 937                                         if (token != TokenNameINLINE_HTML && token != TokenNameEOF) {
 
 938                                                 throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
 
 948         private void declare_statement() {
 
 950                 // | ':' inner_statement_list T_ENDDECLARE ';'
 
 952                 if (token == TokenNameCOLON) {
 
 954                         // TODO: implement inner_statement_list();
 
 956                         if (token != TokenNameenddeclare) {
 
 957                                 throwSyntaxError("'enddeclare' expected in 'declare' statement.");
 
 960                         if (token != TokenNameSEMICOLON) {
 
 961                                 throwSyntaxError("';' expected after 'enddeclare' keyword.");
 
 969         private void declare_list() {
 
 970                 // T_STRING '=' static_scalar
 
 971                 // | declare_list ',' T_STRING '=' static_scalar
 
 973                         if (token != TokenNameIdentifier) {
 
 974                                 throwSyntaxError("Identifier expected in 'declare' list.");
 
 977                         if (token != TokenNameEQUAL) {
 
 978                                 throwSyntaxError("'=' expected in 'declare' list.");
 
 982                         if (token != TokenNameCOMMA) {
 
 989         private void additional_catches() {
 
 990                 while (token == TokenNamecatch) {
 
 992                         if (token != TokenNameLPAREN) {
 
 993                                 throwSyntaxError("'(' expected in 'catch' statement.");
 
 996                         fully_qualified_class_name();
 
 997                         if (token != TokenNameVariable) {
 
 998                                 throwSyntaxError("Variable expected in 'catch' statement.");
 
1002                         if (token != TokenNameRPAREN) {
 
1003                                 throwSyntaxError("')' expected in 'catch' statement.");
 
1006                         if (token != TokenNameLBRACE) {
 
1007                                 throwSyntaxError("'{' expected in 'catch' statement.");
 
1010                         if (token != TokenNameRBRACE) {
 
1013                         if (token != TokenNameRBRACE) {
 
1014                                 throwSyntaxError("'}' expected in 'catch' statement.");
 
1020         private void foreach_variable() {
 
1023                 if (token == TokenNameAND) {
 
1029         private void foreach_optional_arg() {
 
1031                 // | T_DOUBLE_ARROW foreach_variable
 
1032                 if (token == TokenNameEQUAL_GREATER) {
 
1038         private void global_var_list() {
 
1040                 // global_var_list ',' global_var
 
1042                 HashSet set = peekVariableSet();
 
1045                         if (token != TokenNameCOMMA) {
 
1052         private void global_var(HashSet set) {
 
1056                 // | '$' '{' expr '}'
 
1057                 if (token == TokenNameVariable) {
 
1058                         if (fMethodVariables != null) {
 
1059                                 VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR);
 
1060                                 fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
 
1062                         addVariableSet(set);
 
1064                 } else if (token == TokenNameDOLLAR) {
 
1066                         if (token == TokenNameLBRACE) {
 
1069                                 if (token != TokenNameRBRACE) {
 
1070                                         throwSyntaxError("'}' expected in global variable.");
 
1079         private void static_var_list() {
 
1081                 // static_var_list ',' T_VARIABLE
 
1082                 // | static_var_list ',' T_VARIABLE '=' static_scalar
 
1084                 // | T_VARIABLE '=' static_scalar,
 
1085                 HashSet set = peekVariableSet();
 
1087                         if (token == TokenNameVariable) {
 
1088                                 if (fMethodVariables != null) {
 
1089                                         VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR);
 
1090                                         fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
 
1092                                 addVariableSet(set);
 
1094                                 if (token == TokenNameEQUAL) {
 
1098                                 if (token != TokenNameCOMMA) {
 
1108         private void unset_variables() {
 
1111                 // | unset_variables ',' unset_variable
 
1115                         variable(false, false);
 
1116                         if (token != TokenNameCOMMA) {
 
1123         private final void initializeModifiers() {
 
1125                 this.modifiersSourceStart = -1;
 
1128         private final void checkAndSetModifiers(int flag) {
 
1129                 this.modifiers |= flag;
 
1130                 if (this.modifiersSourceStart < 0)
 
1131                         this.modifiersSourceStart = this.scanner.startPosition;
 
1134         private void unticked_class_declaration_statement(TypeDeclaration typeDecl) {
 
1135                 initializeModifiers();
 
1136                 if (token == TokenNameinterface) {
 
1137                         // interface_entry T_STRING
 
1138                         // interface_extends_list
 
1139                         // '{' class_statement_list '}'
 
1140                         checkAndSetModifiers(AccInterface);
 
1142                         typeDecl.modifiers = this.modifiers;
 
1143                         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1144                         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1145                         if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
1146                                 typeDecl.name = scanner.getCurrentIdentifierSource();
 
1147                                 if (token > TokenNameKEYWORD) {
 
1148                                         problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
 
1149                                                         scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
 
1150                                         // throwSyntaxError("Don't use a keyword for interface declaration ["
 
1151                                         // + scanner.toStringAction(token) + "].",
 
1152                                         // typeDecl.sourceStart, typeDecl.sourceEnd);
 
1155                                 interface_extends_list(typeDecl);
 
1157                                 typeDecl.name = new char[] { ' ' };
 
1158                                 throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd);
 
1162                         // class_entry_type T_STRING extends_from
 
1164                         // '{' class_statement_list'}'
 
1166                         typeDecl.modifiers = this.modifiers;
 
1167                         typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1168                         typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1170                         // identifier 'extends' identifier
 
1171                         if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
1172                                 typeDecl.name = scanner.getCurrentIdentifierSource();
 
1173                                 if (token > TokenNameKEYWORD) {
 
1174                                         problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
 
1175                                                         scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
 
1176                                         // throwSyntaxError("Don't use a keyword for class declaration [" +
 
1177                                         // scanner.toStringAction(token) + "].",
 
1178                                         // typeDecl.sourceStart, typeDecl.sourceEnd);
 
1183                                 // | T_EXTENDS fully_qualified_class_name
 
1184                                 if (token == TokenNameextends) {
 
1185                                         interface_extends_list(typeDecl);
 
1187                                         // if (token != TokenNameIdentifier) {
 
1188                                         // throwSyntaxError("Class name expected after keyword
 
1190                                         // scanner.getCurrentTokenStartPosition(), scanner
 
1191                                         // .getCurrentTokenEndPosition());
 
1194                                 implements_list(typeDecl);
 
1196                                 typeDecl.name = new char[] { ' ' };
 
1197                                 throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
 
1201                 // '{' class_statement_list '}'
 
1202                 if (token == TokenNameLBRACE) {
 
1204                         if (token != TokenNameRBRACE) {
 
1205                                 ArrayList list = new ArrayList();
 
1206                                 class_statement_list(list);
 
1207                                 typeDecl.fields = new FieldDeclaration[list.size()];
 
1208                                 for (int i = 0; i < list.size(); i++) {
 
1209                                         typeDecl.fields[i] = (FieldDeclaration) list.get(i);
 
1212                         if (token == TokenNameRBRACE) {
 
1213                                 typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1216                                 throwSyntaxError("'}' expected at end of class body.");
 
1219                         throwSyntaxError("'{' expected at start of class body.");
 
1223         private void class_entry_type() {
 
1225                 // | T_ABSTRACT T_CLASS
 
1226                 // | T_FINAL T_CLASS
 
1227                 if (token == TokenNameclass) {
 
1229                 } else if (token == TokenNameabstract) {
 
1230                         checkAndSetModifiers(AccAbstract);
 
1232                         if (token != TokenNameclass) {
 
1233                                 throwSyntaxError("Keyword 'class' expected after keyword 'abstract'.");
 
1236                 } else if (token == TokenNamefinal) {
 
1237                         checkAndSetModifiers(AccFinal);
 
1239                         if (token != TokenNameclass) {
 
1240                                 throwSyntaxError("Keyword 'class' expected after keyword 'final'.");
 
1244                         throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected");
 
1248         // private void class_extends(TypeDeclaration typeDecl) {
 
1250         // // | T_EXTENDS interface_list
 
1251         // if (token == TokenNameextends) {
 
1254         // if (token == TokenNameIdentifier) {
 
1257         // throwSyntaxError("Class name expected after keyword 'extends'.");
 
1262         private void interface_extends_list(TypeDeclaration typeDecl) {
 
1264                 // | T_EXTENDS interface_list
 
1265                 if (token == TokenNameextends) {
 
1271         private void implements_list(TypeDeclaration typeDecl) {
 
1273                 // | T_IMPLEMENTS interface_list
 
1274                 if (token == TokenNameimplements) {
 
1280         private void interface_list() {
 
1282                 // fully_qualified_class_name
 
1283                 // | interface_list ',' fully_qualified_class_name
 
1285                         if (token == TokenNameIdentifier) {
 
1288                                 throwSyntaxError("Interface name expected after keyword 'implements'.");
 
1290                         if (token != TokenNameCOMMA) {
 
1297         // private void classBody(TypeDeclaration typeDecl) {
 
1298         // //'{' [class-element-list] '}'
 
1299         // if (token == TokenNameLBRACE) {
 
1301         // if (token != TokenNameRBRACE) {
 
1302         // class_statement_list();
 
1304         // if (token == TokenNameRBRACE) {
 
1305         // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1308         // throwSyntaxError("'}' expected at end of class body.");
 
1311         // throwSyntaxError("'{' expected at start of class body.");
 
1314         private void class_statement_list(ArrayList list) {
 
1317                                 class_statement(list);
 
1318                                 if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
 
1319                                                 || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
 
1320                                                 || token == TokenNameconst) {
 
1323                                 if (token == TokenNameRBRACE) {
 
1326                                 throwSyntaxError("'}' at end of class statement.");
 
1327                         } catch (SyntaxError sytaxErr1) {
 
1328                                 boolean tokenize = scanner.tokenizeStrings;
 
1330                                         scanner.tokenizeStrings = true;
 
1333                                         // if an error occured,
 
1334                                         // try to find keywords
 
1335                                         // to parse the rest of the string
 
1336                                         while (token != TokenNameEOF) {
 
1337                                                 if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic
 
1338                                                                 || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar
 
1339                                                                 || token == TokenNameconst) {
 
1342                                                 // System.out.println(scanner.toStringAction(token));
 
1345                                         if (token == TokenNameEOF) {
 
1349                                         scanner.tokenizeStrings = tokenize;
 
1355         private void class_statement(ArrayList list) {
 
1357                 // variable_modifiers class_variable_declaration ';'
 
1358                 // | class_constant_declaration ';'
 
1359                 // | method_modifiers T_FUNCTION is_reference T_STRING
 
1360                 // '(' parameter_list ')' method_body
 
1361                 initializeModifiers();
 
1362                 int declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1364                 if (token == TokenNamevar) {
 
1365                         checkAndSetModifiers(AccPublic);
 
1366                         problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(),
 
1367                                         referenceContext, compilationUnit.compilationResult);
 
1369                         class_variable_declaration(declarationSourceStart, list);
 
1370                 } else if (token == TokenNameconst) {
 
1371                         checkAndSetModifiers(AccFinal | AccPublic);
 
1372                         class_constant_declaration(declarationSourceStart, list);
 
1373                         if (token != TokenNameSEMICOLON) {
 
1374                                 throwSyntaxError("';' expected after class const declaration.");
 
1378                         boolean hasModifiers = member_modifiers();
 
1379                         if (token == TokenNamefunction) {
 
1380                                 if (!hasModifiers) {
 
1381                                         checkAndSetModifiers(AccPublic);
 
1383                                 MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
 
1384                                 methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
 
1385                                 methodDecl.modifiers = this.modifiers;
 
1386                                 methodDecl.type = MethodDeclaration.METHOD_DEFINITION;
 
1389                                         functionDefinition(methodDecl);
 
1391                                         int sourceEnd = methodDecl.sourceEnd;
 
1392                                         if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) {
 
1393                                                 sourceEnd = methodDecl.declarationSourceStart + 1;
 
1395                                         methodDecl.declarationSourceEnd = sourceEnd;
 
1396                                         methodDecl.sourceEnd = sourceEnd;
 
1399                                 if (!hasModifiers) {
 
1400                                         throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations.");
 
1402                                 class_variable_declaration(declarationSourceStart, list);
 
1407         private void class_constant_declaration(int declarationSourceStart, ArrayList list) {
 
1408                 // class_constant_declaration ',' T_STRING '=' static_scalar
 
1409                 // | T_CONST T_STRING '=' static_scalar
 
1410                 if (token != TokenNameconst) {
 
1411                         throwSyntaxError("'const' keyword expected in class declaration.");
 
1416                         if (token != TokenNameIdentifier) {
 
1417                                 throwSyntaxError("Identifier expected in class const declaration.");
 
1419                         FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner
 
1420                                         .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
 
1421                         fieldDeclaration.modifiers = this.modifiers;
 
1422                         fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1423                         fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1424                         fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1425                         // fieldDeclaration.type
 
1426                         list.add(fieldDeclaration);
 
1428                         if (token != TokenNameEQUAL) {
 
1429                                 throwSyntaxError("'=' expected in class const declaration.");
 
1433                         if (token != TokenNameCOMMA) {
 
1434                                 break; // while(true)-loop
 
1440         // private void variable_modifiers() {
 
1441         // // variable_modifiers:
 
1442         // // non_empty_member_modifiers
 
1444         // initializeModifiers();
 
1445         // if (token == TokenNamevar) {
 
1446         // checkAndSetModifiers(AccPublic);
 
1447         // reportSyntaxError(
 
1448         // "Keyword 'var' is deprecated. Please use 'public' 'private' or
 
1450         // modifier for field declarations.",
 
1451         // scanner.getCurrentTokenStartPosition(), scanner
 
1452         // .getCurrentTokenEndPosition());
 
1455         // if (!member_modifiers()) {
 
1456         // throwSyntaxError("'public' 'private' or 'protected' modifier expected for
 
1457         // field declarations.");
 
1461         // private void method_modifiers() {
 
1462         // //method_modifiers:
 
1464         // //| non_empty_member_modifiers
 
1465         // initializeModifiers();
 
1466         // if (!member_modifiers()) {
 
1467         // checkAndSetModifiers(AccPublic);
 
1470         private boolean member_modifiers() {
 
1477                 boolean foundToken = false;
 
1479                         if (token == TokenNamepublic) {
 
1480                                 checkAndSetModifiers(AccPublic);
 
1483                         } else if (token == TokenNameprotected) {
 
1484                                 checkAndSetModifiers(AccProtected);
 
1487                         } else if (token == TokenNameprivate) {
 
1488                                 checkAndSetModifiers(AccPrivate);
 
1491                         } else if (token == TokenNamestatic) {
 
1492                                 checkAndSetModifiers(AccStatic);
 
1495                         } else if (token == TokenNameabstract) {
 
1496                                 checkAndSetModifiers(AccAbstract);
 
1499                         } else if (token == TokenNamefinal) {
 
1500                                 checkAndSetModifiers(AccFinal);
 
1510         private void class_variable_declaration(int declarationSourceStart, ArrayList list) {
 
1511                 // class_variable_declaration:
 
1512                 // class_variable_declaration ',' T_VARIABLE
 
1513                 // | class_variable_declaration ',' T_VARIABLE '=' static_scalar
 
1515                 // | T_VARIABLE '=' static_scalar
 
1516                 char[] classVariable;
 
1518                         if (token == TokenNameVariable) {
 
1519                                 classVariable = scanner.getCurrentIdentifierSource();
 
1520                                 // indexManager.addIdentifierInformation('v', classVariable, buf, -1,
 
1522                                 FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner.getCurrentTokenStartPosition(), scanner
 
1523                                                 .getCurrentTokenEndPosition());
 
1524                                 fieldDeclaration.modifiers = this.modifiers;
 
1525                                 fieldDeclaration.declarationSourceStart = declarationSourceStart;
 
1526                                 fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
 
1527                                 fieldDeclaration.modifiersSourceStart = declarationSourceStart;
 
1528                                 list.add(fieldDeclaration);
 
1529                                 if (fTypeVariables != null) {
 
1530                                         VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_CLASS_UNIT);
 
1531                                         fTypeVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
 
1534                                 if (token == TokenNameEQUAL) {
 
1539                                 // if (token == TokenNamethis) {
 
1540                                 // throwSyntaxError("'$this' not allowed after keyword 'public'
 
1541                                 // 'protected' 'private' 'var'.");
 
1543                                 throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'.");
 
1545                         if (token != TokenNameCOMMA) {
 
1550                 if (token != TokenNameSEMICOLON) {
 
1551                         throwSyntaxError("';' expected after field declaration.");
 
1556         private void functionDefinition(MethodDeclaration methodDecl) {
 
1557                 boolean isAbstract = false;
 
1559                         if (compilationUnit != null) {
 
1560                                 compilationUnit.types.add(methodDecl);
 
1563                         ASTNode node = astStack[astPtr];
 
1564                         if (node instanceof TypeDeclaration) {
 
1565                                 TypeDeclaration typeDecl = ((TypeDeclaration) node);
 
1566                                 if (typeDecl.methods == null) {
 
1567                                         typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
 
1569                                         AbstractMethodDeclaration[] newMethods;
 
1570                                         System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 0,
 
1571                                                         typeDecl.methods.length);
 
1572                                         newMethods[typeDecl.methods.length] = methodDecl;
 
1573                                         typeDecl.methods = newMethods;
 
1575                                 if ((typeDecl.modifiers & AccAbstract) == AccAbstract) {
 
1577                                 } else if ((typeDecl.modifiers & AccInterface) == AccInterface) {
 
1583                         pushFunctionVariableSet();
 
1584                         functionDeclarator(methodDecl);
 
1585                         if (token == TokenNameSEMICOLON) {
 
1587                                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1588                                         throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector));
 
1593                         functionBody(methodDecl);
 
1595                         if (!fStackUnassigned.isEmpty()) {
 
1596                                 fStackUnassigned.remove(fStackUnassigned.size() - 1);
 
1601         private void functionDeclarator(MethodDeclaration methodDecl) {
 
1602                 // identifier '(' [parameter-list] ')'
 
1603                 if (token == TokenNameAND) {
 
1606                 methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
 
1607                 methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1608                 if (Scanner.isIdentifierOrKeyword(token)) {
 
1609                         methodDecl.selector = scanner.getCurrentIdentifierSource();
 
1610                         if (token > TokenNameKEYWORD) {
 
1611                                 problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(),
 
1612                                                 scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult);
 
1615                         if (token == TokenNameLPAREN) {
 
1618                                 methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1619                                 throwSyntaxError("'(' expected in function declaration.");
 
1621                         if (token != TokenNameRPAREN) {
 
1622                                 parameter_list(methodDecl);
 
1624                         if (token != TokenNameRPAREN) {
 
1625                                 methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1626                                 throwSyntaxError("')' expected in function declaration.");
 
1628                                 methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
 
1632                         methodDecl.selector = "<undefined>".toCharArray();
 
1633                         methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
 
1634                         throwSyntaxError("Function name expected after keyword 'function'.");
 
1639         private void parameter_list(MethodDeclaration methodDecl) {
 
1640                 // non_empty_parameter_list
 
1642                 non_empty_parameter_list(methodDecl, true);
 
1645         private void non_empty_parameter_list(MethodDeclaration methodDecl, boolean empty_allowed) {
 
1646                 // optional_class_type T_VARIABLE
 
1647                 // | optional_class_type '&' T_VARIABLE
 
1648                 // | optional_class_type '&' T_VARIABLE '=' static_scalar
 
1649                 // | optional_class_type T_VARIABLE '=' static_scalar
 
1650                 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE
 
1651                 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE
 
1652                 // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '='
 
1654                 // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
 
1656                 char[] typeIdentifier = null;
 
1657                 if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
 
1658                         HashSet set = peekVariableSet();
 
1660                                 if (token == TokenNameIdentifier) {
 
1661                                         typeIdentifier = scanner.getCurrentIdentifierSource();
 
1664                                 if (token == TokenNameAND) {
 
1667                                 if (token == TokenNameVariable) {
 
1668                                         if (fMethodVariables != null) {
 
1670                                                 if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) {
 
1671                                                         info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_FUNCTION_DEFINITION);
 
1673                                                         info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_METHOD_DEFINITION);
 
1675                                                 info.typeIdentifier = typeIdentifier;
 
1676                                                 fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info);
 
1678                                         addVariableSet(set);
 
1680                                         if (token == TokenNameEQUAL) {
 
1685                                         throwSyntaxError("Variable expected in parameter list.");
 
1687                                 if (token != TokenNameCOMMA) {
 
1694                 if (!empty_allowed) {
 
1695                         throwSyntaxError("Identifier expected in parameter list.");
 
1699         private void optional_class_type() {
 
1704         // private void parameterDeclaration() {
 
1706         // //variable-reference
 
1707         // if (token == TokenNameAND) {
 
1709         // if (isVariable()) {
 
1712         // throwSyntaxError("Variable expected after reference operator '&'.");
 
1715         // //variable '=' constant
 
1716         // if (token == TokenNameVariable) {
 
1718         // if (token == TokenNameEQUAL) {
 
1724         // // if (token == TokenNamethis) {
 
1725         // // throwSyntaxError("Reserved word '$this' not allowed in parameter
 
1726         // // declaration.");
 
1730         private void labeledStatementList() {
 
1731                 if (token != TokenNamecase && token != TokenNamedefault) {
 
1732                         throwSyntaxError("'case' or 'default' expected.");
 
1735                         if (token == TokenNamecase) {
 
1737                                 expr(); // constant();
 
1738                                 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
 
1740                                         if (token == TokenNamecase || token == TokenNamedefault) {
 
1741                                                 // empty case statement ?
 
1746                                 // else if (token == TokenNameSEMICOLON) {
 
1748                                 // "':' expected after 'case' keyword (Found token: " +
 
1749                                 // scanner.toStringAction(token) + ")",
 
1750                                 // scanner.getCurrentTokenStartPosition(),
 
1751                                 // scanner.getCurrentTokenEndPosition(),
 
1754                                 // if (token == TokenNamecase) { // empty case statement ?
 
1760                                         throwSyntaxError("':' character expected after 'case' constant (Found token: " + scanner.toStringAction(token) + ")");
 
1762                         } else { // TokenNamedefault
 
1764                                 if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
 
1766                                         if (token == TokenNameRBRACE) {
 
1767                                                 // empty default case
 
1770                                         if (token != TokenNamecase) {
 
1774                                         throwSyntaxError("':' character expected after 'default'.");
 
1777                 } while (token == TokenNamecase || token == TokenNamedefault);
 
1780         private void ifStatementColon(IfStatement iState) {
 
1781                 // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list
 
1782                 // new_else_single T_ENDIF ';'
 
1783                 HashSet assignedVariableSet = null;
 
1785                         Block b = inner_statement_list();
 
1786                         iState.thenStatement = b;
 
1787                         checkUnreachable(iState, b);
 
1789                         assignedVariableSet = removeIfVariableSet();
 
1791                 if (token == TokenNameelseif) {
 
1793                                 pushIfVariableSet();
 
1794                                 new_elseif_list(iState);
 
1796                                 HashSet set = removeIfVariableSet();
 
1797                                 if (assignedVariableSet != null && set != null) {
 
1798                                         assignedVariableSet.addAll(set);
 
1803                         pushIfVariableSet();
 
1804                         new_else_single(iState);
 
1806                         HashSet set = removeIfVariableSet();
 
1807                         if (assignedVariableSet != null) {
 
1808                                 HashSet topSet = peekVariableSet();
 
1809                                 if (topSet != null) {
 
1813                                         topSet.addAll(assignedVariableSet);
 
1817                 if (token != TokenNameendif) {
 
1818                         throwSyntaxError("'endif' expected.");
 
1821                 if (token != TokenNameSEMICOLON) {
 
1822                         reportSyntaxError("';' expected after if-statement.");
 
1823                         iState.sourceEnd = scanner.getCurrentTokenStartPosition();
 
1825                         iState.sourceEnd = scanner.getCurrentTokenEndPosition();
 
1830         private void ifStatement(IfStatement iState) {
 
1831                 // T_IF '(' expr ')' statement elseif_list else_single
 
1832                 HashSet assignedVariableSet = null;
 
1834                         pushIfVariableSet();
 
1835                         Statement s = statement();
 
1836                         iState.thenStatement = s;
 
1837                         checkUnreachable(iState, s);
 
1839                         assignedVariableSet = removeIfVariableSet();
 
1842                 if (token == TokenNameelseif) {
 
1844                                 pushIfVariableSet();
 
1845                                 elseif_list(iState);
 
1847                                 HashSet set = removeIfVariableSet();
 
1848                                 if (assignedVariableSet != null && set != null) {
 
1849                                         assignedVariableSet.addAll(set);
 
1854                         pushIfVariableSet();
 
1855                         else_single(iState);
 
1857                         HashSet set = removeIfVariableSet();
 
1858                         if (assignedVariableSet != null) {
 
1859                                 HashSet topSet = peekVariableSet();
 
1860                                 if (topSet != null) {
 
1864                                         topSet.addAll(assignedVariableSet);
 
1870         private void elseif_list(IfStatement iState) {
 
1872                 // | elseif_list T_ELSEIF '(' expr ')' statement
 
1873                 ArrayList conditionList = new ArrayList();
 
1874                 ArrayList statementList = new ArrayList();
 
1877                 while (token == TokenNameelseif) {
 
1879                         if (token == TokenNameLPAREN) {
 
1882                                 throwSyntaxError("'(' expected after 'elseif' keyword.");
 
1885                         conditionList.add(e);
 
1886                         if (token == TokenNameRPAREN) {
 
1889                                 throwSyntaxError("')' expected after 'elseif' condition.");
 
1892                         statementList.add(s);
 
1893                         checkUnreachable(iState, s);
 
1895                 iState.elseifConditions = new Expression[conditionList.size()];
 
1896                 iState.elseifStatements = new Statement[statementList.size()];
 
1897                 conditionList.toArray(iState.elseifConditions);
 
1898                 statementList.toArray(iState.elseifStatements);
 
1901         private void new_elseif_list(IfStatement iState) {
 
1903                 // | new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list
 
1904                 ArrayList conditionList = new ArrayList();
 
1905                 ArrayList statementList = new ArrayList();
 
1908                 while (token == TokenNameelseif) {
 
1910                         if (token == TokenNameLPAREN) {
 
1913                                 throwSyntaxError("'(' expected after 'elseif' keyword.");
 
1916                         conditionList.add(e);
 
1917                         if (token == TokenNameRPAREN) {
 
1920                                 throwSyntaxError("')' expected after 'elseif' condition.");
 
1922                         if (token == TokenNameCOLON) {
 
1925                                 throwSyntaxError("':' expected after 'elseif' keyword.");
 
1927                         b = inner_statement_list();
 
1928                         statementList.add(b);
 
1929                         checkUnreachable(iState, b);
 
1931                 iState.elseifConditions = new Expression[conditionList.size()];
 
1932                 iState.elseifStatements = new Statement[statementList.size()];
 
1933                 conditionList.toArray(iState.elseifConditions);
 
1934                 statementList.toArray(iState.elseifStatements);
 
1937         private void else_single(IfStatement iState) {
 
1940                 if (token == TokenNameelse) {
 
1942                         Statement s = statement();
 
1943                         iState.elseStatement = s;
 
1944                         checkUnreachable(iState, s);
 
1946                         iState.checkUnreachable = false;
 
1948                 iState.sourceEnd = scanner.getCurrentTokenStartPosition();
 
1951         private void new_else_single(IfStatement iState) {
 
1953                 // | T_ELSE ':' inner_statement_list
 
1954                 if (token == TokenNameelse) {
 
1956                         if (token == TokenNameCOLON) {
 
1959                                 throwSyntaxError("':' expected after 'else' keyword.");
 
1961                         Block b = inner_statement_list();
 
1962                         iState.elseStatement = b;
 
1963                         checkUnreachable(iState, b);
 
1965                         iState.checkUnreachable = false;
 
1969         private Block inner_statement_list() {
 
1970                 // inner_statement_list inner_statement
 
1972                 return statementList();
 
1979         private void checkUnreachable(IfStatement iState, Statement s) {
 
1980                 if (s instanceof Block) {
 
1981                         Block b = (Block) s;
 
1982                         if (b.statements == null || b.statements.length == 0) {
 
1983                                 iState.checkUnreachable = false;
 
1985                                 int off = b.statements.length - 1;
 
1986                                 if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement)
 
1987                                                 && !(b.statements[off] instanceof BreakStatement)) {
 
1988                                         if (!(b.statements[off] instanceof IfStatement) || !((IfStatement) b.statements[off]).checkUnreachable) {
 
1989                                                 iState.checkUnreachable = false;
 
1994                         if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) {
 
1995                                 if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) {
 
1996                                         iState.checkUnreachable = false;
 
2002         // private void elseifStatementList() {
 
2004         // elseifStatement();
 
2006         // case TokenNameelse:
 
2008         // if (token == TokenNameCOLON) {
 
2010         // if (token != TokenNameendif) {
 
2015         // if (token == TokenNameif) { //'else if'
 
2018         // throwSyntaxError("':' expected after 'else'.");
 
2022         // case TokenNameelseif:
 
2031         // private void elseifStatement() {
 
2032         // if (token == TokenNameLPAREN) {
 
2035         // if (token != TokenNameRPAREN) {
 
2036         // throwSyntaxError("')' expected in else-if-statement.");
 
2039         // if (token != TokenNameCOLON) {
 
2040         // throwSyntaxError("':' expected in else-if-statement.");
 
2043         // if (token != TokenNameendif) {
 
2049         private void switchStatement() {
 
2050                 if (token == TokenNameCOLON) {
 
2051                         // ':' [labeled-statement-list] 'endswitch' ';'
 
2053                         labeledStatementList();
 
2054                         if (token != TokenNameendswitch) {
 
2055                                 throwSyntaxError("'endswitch' expected.");
 
2058                         if (token != TokenNameSEMICOLON) {
 
2059                                 throwSyntaxError("';' expected after switch-statement.");
 
2063                         // '{' [labeled-statement-list] '}'
 
2064                         if (token != TokenNameLBRACE) {
 
2065                                 throwSyntaxError("'{' expected in switch statement.");
 
2068                         if (token != TokenNameRBRACE) {
 
2069                                 labeledStatementList();
 
2071                         if (token != TokenNameRBRACE) {
 
2072                                 throwSyntaxError("'}' expected in switch statement.");
 
2078         private void forStatement() {
 
2079                 if (token == TokenNameCOLON) {
 
2082                         if (token != TokenNameendfor) {
 
2083                                 throwSyntaxError("'endfor' expected.");
 
2086                         if (token != TokenNameSEMICOLON) {
 
2087                                 throwSyntaxError("';' expected after for-statement.");
 
2095         private void whileStatement() {
 
2096                 // ':' statement-list 'endwhile' ';'
 
2097                 if (token == TokenNameCOLON) {
 
2100                         if (token != TokenNameendwhile) {
 
2101                                 throwSyntaxError("'endwhile' expected.");
 
2104                         if (token != TokenNameSEMICOLON) {
 
2105                                 throwSyntaxError("';' expected after while-statement.");
 
2113         private void foreachStatement() {
 
2114                 if (token == TokenNameCOLON) {
 
2117                         if (token != TokenNameendforeach) {
 
2118                                 throwSyntaxError("'endforeach' expected.");
 
2121                         if (token != TokenNameSEMICOLON) {
 
2122                                 throwSyntaxError("';' expected after foreach-statement.");
 
2130         // private void exitStatus() {
 
2131         // if (token == TokenNameLPAREN) {
 
2134         // throwSyntaxError("'(' expected in 'exit-status'.");
 
2136         // if (token != TokenNameRPAREN) {
 
2139         // if (token == TokenNameRPAREN) {
 
2142         // throwSyntaxError("')' expected after 'exit-status'.");
 
2145         private void expressionList() {
 
2148                         if (token == TokenNameCOMMA) {
 
2156         private Expression expr() {
 
2158                 // | expr_without_variable
 
2159                 // if (token!=TokenNameEOF) {
 
2160                 if (Scanner.TRACE) {
 
2161                         System.out.println("TRACE: expr()");
 
2163                 return expr_without_variable(true);
 
2167         private Expression expr_without_variable(boolean only_variable) {
 
2168                 int exprSourceStart = scanner.getCurrentTokenStartPosition();
 
2169                 int exprSourceEnd = scanner.getCurrentTokenEndPosition();
 
2170                 Expression expression = new Expression();
 
2171                 expression.sourceStart = exprSourceStart;
 
2172                 // default, may be overwritten
 
2173                 expression.sourceEnd = exprSourceEnd;
 
2175                         // internal_functions_in_yacc
 
2184                         // | T_INC rw_variable
 
2185                         // | T_DEC rw_variable
 
2186                         // | T_INT_CAST expr
 
2187                         // | T_DOUBLE_CAST expr
 
2188                         // | T_STRING_CAST expr
 
2189                         // | T_ARRAY_CAST expr
 
2190                         // | T_OBJECT_CAST expr
 
2191                         // | T_BOOL_CAST expr
 
2192                         // | T_UNSET_CAST expr
 
2193                         // | T_EXIT exit_expr
 
2195                         // | T_ARRAY '(' array_pair_list ')'
 
2196                         // | '`' encaps_list '`'
 
2197                         // | T_LIST '(' assignment_list ')' '=' expr
 
2198                         // | T_NEW class_name_reference ctor_arguments
 
2199                         // | variable '=' expr
 
2200                         // | variable '=' '&' variable
 
2201                         // | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
2202                         // | variable T_PLUS_EQUAL expr
 
2203                         // | variable T_MINUS_EQUAL expr
 
2204                         // | variable T_MUL_EQUAL expr
 
2205                         // | variable T_DIV_EQUAL expr
 
2206                         // | variable T_CONCAT_EQUAL expr
 
2207                         // | variable T_MOD_EQUAL expr
 
2208                         // | variable T_AND_EQUAL expr
 
2209                         // | variable T_OR_EQUAL expr
 
2210                         // | variable T_XOR_EQUAL expr
 
2211                         // | variable T_SL_EQUAL expr
 
2212                         // | variable T_SR_EQUAL expr
 
2213                         // | rw_variable T_INC
 
2214                         // | rw_variable T_DEC
 
2215                         // | expr T_BOOLEAN_OR expr
 
2216                         // | expr T_BOOLEAN_AND expr
 
2217                         // | expr T_LOGICAL_OR expr
 
2218                         // | expr T_LOGICAL_AND expr
 
2219                         // | expr T_LOGICAL_XOR expr
 
2231                         // | expr T_IS_IDENTICAL expr
 
2232                         // | expr T_IS_NOT_IDENTICAL expr
 
2233                         // | expr T_IS_EQUAL expr
 
2234                         // | expr T_IS_NOT_EQUAL expr
 
2236                         // | expr T_IS_SMALLER_OR_EQUAL expr
 
2238                         // | expr T_IS_GREATER_OR_EQUAL expr
 
2239                         // | expr T_INSTANCEOF class_name_reference
 
2240                         // | expr '?' expr ':' expr
 
2241                         if (Scanner.TRACE) {
 
2242                                 System.out.println("TRACE: expr_without_variable() PART 1");
 
2245                         case TokenNameisset:
 
2246                                 // T_ISSET '(' isset_variables ')'
 
2248                                 if (token != TokenNameLPAREN) {
 
2249                                         throwSyntaxError("'(' expected after keyword 'isset'");
 
2253                                 if (token != TokenNameRPAREN) {
 
2254                                         throwSyntaxError("')' expected after keyword 'isset'");
 
2258                         case TokenNameempty:
 
2260                                 if (token != TokenNameLPAREN) {
 
2261                                         throwSyntaxError("'(' expected after keyword 'empty'");
 
2264                                 variable(true, false);
 
2265                                 if (token != TokenNameRPAREN) {
 
2266                                         throwSyntaxError("')' expected after keyword 'empty'");
 
2271                         case TokenNameinclude:
 
2272                         case TokenNameinclude_once:
 
2273                         case TokenNamerequire:
 
2274                         case TokenNamerequire_once:
 
2275                                 internal_functions_in_yacc();
 
2278                         case TokenNameLPAREN:
 
2281                                 if (token == TokenNameRPAREN) {
 
2284                                         throwSyntaxError("')' expected in expression.");
 
2294                         // | T_INT_CAST expr
 
2295                         // | T_DOUBLE_CAST expr
 
2296                         // | T_STRING_CAST expr
 
2297                         // | T_ARRAY_CAST expr
 
2298                         // | T_OBJECT_CAST expr
 
2299                         // | T_BOOL_CAST expr
 
2300                         // | T_UNSET_CAST expr
 
2301                         case TokenNameclone:
 
2302                         case TokenNameprint:
 
2305                         case TokenNameMINUS:
 
2307                         case TokenNameTWIDDLE:
 
2308                         case TokenNameintCAST:
 
2309                         case TokenNamedoubleCAST:
 
2310                         case TokenNamestringCAST:
 
2311                         case TokenNamearrayCAST:
 
2312                         case TokenNameobjectCAST:
 
2313                         case TokenNameboolCAST:
 
2314                         case TokenNameunsetCAST:
 
2324                         // | T_STRING_VARNAME
 
2326                         // | T_START_HEREDOC encaps_list T_END_HEREDOC
 
2327                         // | '`' encaps_list '`'
 
2329                         // | '`' encaps_list '`'
 
2330                         // case TokenNameEncapsedString0:
 
2331                         // scanner.encapsedStringStack.push(new Character('`'));
 
2334                         // if (token == TokenNameEncapsedString0) {
 
2337                         // if (token != TokenNameEncapsedString0) {
 
2338                         // throwSyntaxError("\'`\' expected at end of string" + "(Found token: " +
 
2339                         // scanner.toStringAction(token) + " )");
 
2343                         // scanner.encapsedStringStack.pop();
 
2347                         // // | '\'' encaps_list '\''
 
2348                         // case TokenNameEncapsedString1:
 
2349                         // scanner.encapsedStringStack.push(new Character('\''));
 
2352                         // exprSourceStart = scanner.getCurrentTokenStartPosition();
 
2353                         // if (token == TokenNameEncapsedString1) {
 
2355                         // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2356                         // exprSourceStart, scanner
 
2357                         // .getCurrentTokenEndPosition());
 
2360                         // if (token != TokenNameEncapsedString1) {
 
2361                         // throwSyntaxError("\'\'\' expected at end of string" + "(Found token: "
 
2362                         // + scanner.toStringAction(token) + " )");
 
2365                         // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2366                         // exprSourceStart, scanner
 
2367                         // .getCurrentTokenEndPosition());
 
2371                         // scanner.encapsedStringStack.pop();
 
2375                         // //| '"' encaps_list '"'
 
2376                         // case TokenNameEncapsedString2:
 
2377                         // scanner.encapsedStringStack.push(new Character('"'));
 
2380                         // exprSourceStart = scanner.getCurrentTokenStartPosition();
 
2381                         // if (token == TokenNameEncapsedString2) {
 
2383                         // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2384                         // exprSourceStart, scanner
 
2385                         // .getCurrentTokenEndPosition());
 
2388                         // if (token != TokenNameEncapsedString2) {
 
2389                         // throwSyntaxError("'\"' expected at end of string" + "(Found token: " +
 
2390                         // scanner.toStringAction(token) + " )");
 
2393                         // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart),
 
2394                         // exprSourceStart, scanner
 
2395                         // .getCurrentTokenEndPosition());
 
2399                         // scanner.encapsedStringStack.pop();
 
2403                         case TokenNameStringDoubleQuote:
 
2404                                 expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
 
2405                                                 .getCurrentTokenEndPosition());
 
2408                         case TokenNameStringSingleQuote:
 
2409                                 expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner
 
2410                                                 .getCurrentTokenEndPosition());
 
2413                         case TokenNameIntegerLiteral:
 
2414                         case TokenNameDoubleLiteral:
 
2415                         case TokenNameStringInterpolated:
 
2418                         case TokenNameCLASS_C:
 
2419                         case TokenNameMETHOD_C:
 
2420                         case TokenNameFUNC_C:
 
2423                         case TokenNameHEREDOC:
 
2426                         case TokenNamearray:
 
2427                                 // T_ARRAY '(' array_pair_list ')'
 
2429                                 if (token == TokenNameLPAREN) {
 
2431                                         if (token == TokenNameRPAREN) {
 
2436                                         if (token != TokenNameRPAREN) {
 
2437                                                 throwSyntaxError("')' or ',' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
 
2441                                         throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")");
 
2445                                 // | T_LIST '(' assignment_list ')' '=' expr
 
2447                                 if (token == TokenNameLPAREN) {
 
2450                                         if (token != TokenNameRPAREN) {
 
2451                                                 throwSyntaxError("')' expected after 'list' keyword.");
 
2454                                         if (token != TokenNameEQUAL) {
 
2455                                                 throwSyntaxError("'=' expected after 'list' keyword.");
 
2460                                         throwSyntaxError("'(' expected after 'list' keyword.");
 
2464                                 // | T_NEW class_name_reference ctor_arguments
 
2466                                 Expression typeRef = class_name_reference();
 
2468                                 if (typeRef != null) {
 
2469                                         expression = typeRef;
 
2472                         // | T_INC rw_variable
 
2473                         // | T_DEC rw_variable
 
2474                         case TokenNamePLUS_PLUS:
 
2475                         case TokenNameMINUS_MINUS:
 
2479                         // | variable '=' expr
 
2480                         // | variable '=' '&' variable
 
2481                         // | variable '=' '&' T_NEW class_name_reference ctor_arguments
 
2482                         // | variable T_PLUS_EQUAL expr
 
2483                         // | variable T_MINUS_EQUAL expr
 
2484                         // | variable T_MUL_EQUAL expr
 
2485                         // | variable T_DIV_EQUAL expr
 
2486                         // | variable T_CONCAT_EQUAL expr
 
2487                         // | variable T_MOD_EQUAL expr
 
2488                         // | variable T_AND_EQUAL expr
 
2489                         // | variable T_OR_EQUAL expr
 
2490                         // | variable T_XOR_EQUAL expr
 
2491                         // | variable T_SL_EQUAL expr
 
2492                         // | variable T_SR_EQUAL expr
 
2493                         // | rw_variable T_INC
 
2494                         // | rw_variable T_DEC
 
2495                         case TokenNameIdentifier:
 
2496                         case TokenNameVariable:
 
2497                         case TokenNameDOLLAR:
 
2498                                 Expression lhs = null;
 
2499                                 boolean rememberedVar = false;
 
2500                                 if (token == TokenNameIdentifier) {
 
2501                                         lhs = identifier(true, true);
 
2506                                         lhs = variable(true, true);
 
2510                                         if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL
 
2511                                                         && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL
 
2512                                                         && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL
 
2513                                                         && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL
 
2514                                                         && token != TokenNameLEFT_SHIFT_EQUAL) {
 
2515                                                 FieldReference ref = (FieldReference) lhs;
 
2516                                                 if (!containsVariableSet(ref.token)) {
 
2517                                                         problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(),
 
2518                                                                         referenceContext, compilationUnit.compilationResult);
 
2519                                                         addVariableSet(ref.token);
 
2524                                 case TokenNameEQUAL:
 
2525                                         if (lhs != null && lhs instanceof FieldReference) {
 
2526                                                 addVariableSet(((FieldReference) lhs).token);
 
2529                                         if (token == TokenNameAND) {
 
2531                                                 if (token == TokenNamenew) {
 
2532                                                         // | variable '=' '&' T_NEW class_name_reference
 
2535                                                         SingleTypeReference classRef = class_name_reference();
 
2537                                                         if (classRef != null) {
 
2538                                                                 if (lhs != null && lhs instanceof FieldReference) {
 
2540                                                                         // $var = & new Object();
 
2541                                                                         if (fMethodVariables != null) {
 
2542                                                                                 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
 
2543                                                                                 lhsInfo.reference = classRef;
 
2544                                                                                 lhsInfo.typeIdentifier = classRef.token;
 
2545                                                                                 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
 
2546                                                                                 rememberedVar = true;
 
2551                                                         Expression rhs = variable(false, false);
 
2552                                                         if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) {
 
2555                                                                 if (fMethodVariables != null) {
 
2556                                                                         VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
 
2557                                                                         if (rhsInfo != null && rhsInfo.reference != null) {
 
2558                                                                                 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
 
2559                                                                                 lhsInfo.reference = rhsInfo.reference;
 
2560                                                                                 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
 
2561                                                                                 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
 
2562                                                                                 rememberedVar = true;
 
2568                                                 Expression rhs = expr();
 
2569                                                 if (lhs != null && lhs instanceof FieldReference) {
 
2570                                                         if (rhs != null && rhs instanceof FieldReference) {
 
2573                                                                 if (fMethodVariables != null) {
 
2574                                                                         VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
 
2575                                                                         if (rhsInfo != null && rhsInfo.reference != null) {
 
2576                                                                                 VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
 
2577                                                                                 lhsInfo.reference = rhsInfo.reference;
 
2578                                                                                 lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
 
2579                                                                                 fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
 
2580                                                                                 rememberedVar = true;
 
2583                                                         } else if (rhs != null && rhs instanceof SingleTypeReference) {
 
2585                                                                 // $var = new Object();
 
2586                                                                 if (fMethodVariables != null) {
 
2587                                                                         VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
 
2588                                                                         lhsInfo.reference = (SingleTypeReference) rhs;
 
2589                                                                         lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
 
2590                                                                         fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
 
2591                                                                         rememberedVar = true;
 
2596                                         if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) {
 
2597                                                 if (fMethodVariables != null) {
 
2598                                                         VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
 
2599                                                         fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
 
2603                                 case TokenNamePLUS_EQUAL:
 
2604                                 case TokenNameMINUS_EQUAL:
 
2605                                 case TokenNameMULTIPLY_EQUAL:
 
2606                                 case TokenNameDIVIDE_EQUAL:
 
2607                                 case TokenNameDOT_EQUAL:
 
2608                                 case TokenNameREMAINDER_EQUAL:
 
2609                                 case TokenNameAND_EQUAL:
 
2610                                 case TokenNameOR_EQUAL:
 
2611                                 case TokenNameXOR_EQUAL:
 
2612                                 case TokenNameRIGHT_SHIFT_EQUAL:
 
2613                                 case TokenNameLEFT_SHIFT_EQUAL:
 
2614                                         if (lhs != null && lhs instanceof FieldReference) {
 
2615                                                 addVariableSet(((FieldReference) lhs).token);
 
2620                                 case TokenNamePLUS_PLUS:
 
2621                                 case TokenNameMINUS_MINUS:
 
2625                                         if (!only_variable) {
 
2626                                                 throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "').");
 
2634                                 if (token != TokenNameINLINE_HTML) {
 
2635                                         if (token > TokenNameKEYWORD) {
 
2639                                                 // System.out.println(scanner.getCurrentTokenStartPosition());
 
2640                                                 // System.out.println(scanner.getCurrentTokenEndPosition());
 
2642                                                 throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "').");
 
2647                         if (Scanner.TRACE) {
 
2648                                 System.out.println("TRACE: expr_without_variable() PART 2");
 
2650                         // | expr T_BOOLEAN_OR expr
 
2651                         // | expr T_BOOLEAN_AND expr
 
2652                         // | expr T_LOGICAL_OR expr
 
2653                         // | expr T_LOGICAL_AND expr
 
2654                         // | expr T_LOGICAL_XOR expr
 
2666                         // | expr T_IS_IDENTICAL expr
 
2667                         // | expr T_IS_NOT_IDENTICAL expr
 
2668                         // | expr T_IS_EQUAL expr
 
2669                         // | expr T_IS_NOT_EQUAL expr
 
2671                         // | expr T_IS_SMALLER_OR_EQUAL expr
 
2673                         // | expr T_IS_GREATER_OR_EQUAL expr
 
2676                                 case TokenNameOR_OR:
 
2678                                         expression = new OR_OR_Expression(expression, expr(), token);
 
2680                                 case TokenNameAND_AND:
 
2682                                         expression = new AND_AND_Expression(expression, expr(), token);
 
2684                                 case TokenNameEQUAL_EQUAL:
 
2686                                         expression = new EqualExpression(expression, expr(), token);
 
2696                                 case TokenNameMINUS:
 
2697                                 case TokenNameMULTIPLY:
 
2698                                 case TokenNameDIVIDE:
 
2699                                 case TokenNameREMAINDER:
 
2700                                 case TokenNameLEFT_SHIFT:
 
2701                                 case TokenNameRIGHT_SHIFT:
 
2702                                 case TokenNameEQUAL_EQUAL_EQUAL:
 
2703                                 case TokenNameNOT_EQUAL_EQUAL:
 
2704                                 case TokenNameNOT_EQUAL:
 
2706                                 case TokenNameLESS_EQUAL:
 
2707                                 case TokenNameGREATER:
 
2708                                 case TokenNameGREATER_EQUAL:
 
2710                                         expression = new BinaryExpression(expression, expr(), token);
 
2712                                 // | expr T_INSTANCEOF class_name_reference
 
2713                                 // | expr '?' expr ':' expr
 
2714                                 case TokenNameinstanceof:
 
2716                                         TypeReference classRef = class_name_reference();
 
2717                                         if (classRef != null) {
 
2718                                                 expression = new InstanceOfExpression(expression, classRef, OperatorIds.INSTANCEOF);
 
2719                                                 expression.sourceStart = exprSourceStart;
 
2720                                                 expression.sourceEnd = scanner.getCurrentTokenEndPosition();
 
2723                                 case TokenNameQUESTION:
 
2725                                         Expression valueIfTrue = expr();
 
2726                                         if (token != TokenNameCOLON) {
 
2727                                                 throwSyntaxError("':' expected in conditional expression.");
 
2730                                         Expression valueIfFalse = expr();
 
2732                                         expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse);
 
2738                 } catch (SyntaxError e) {
 
2739                         // try to find next token after expression with errors:
 
2740                         if (token == TokenNameSEMICOLON) {
 
2744                         if (token == TokenNameRBRACE || token == TokenNameRPAREN || token == TokenNameRBRACKET) {
 
2752         private SingleTypeReference class_name_reference() {
 
2753                 // class_name_reference:
 
2755                 // | dynamic_class_name_reference
 
2756                 SingleTypeReference ref = null;
 
2757                 if (Scanner.TRACE) {
 
2758                         System.out.println("TRACE: class_name_reference()");
 
2760                 if (token == TokenNameIdentifier) {
 
2761                         ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
 
2765                         dynamic_class_name_reference();
 
2770         private void dynamic_class_name_reference() {
 
2771                 // dynamic_class_name_reference:
 
2772                 // base_variable T_OBJECT_OPERATOR object_property
 
2773                 // dynamic_class_name_variable_properties
 
2775                 if (Scanner.TRACE) {
 
2776                         System.out.println("TRACE: dynamic_class_name_reference()");
 
2778                 base_variable(true);
 
2779                 if (token == TokenNameMINUS_GREATER) {
 
2782                         dynamic_class_name_variable_properties();
 
2786         private void dynamic_class_name_variable_properties() {
 
2787                 // dynamic_class_name_variable_properties:
 
2788                 // dynamic_class_name_variable_properties
 
2789                 // dynamic_class_name_variable_property
 
2791                 if (Scanner.TRACE) {
 
2792                         System.out.println("TRACE: dynamic_class_name_variable_properties()");
 
2794                 while (token == TokenNameMINUS_GREATER) {
 
2795                         dynamic_class_name_variable_property();
 
2799         private void dynamic_class_name_variable_property() {
 
2800                 // dynamic_class_name_variable_property:
 
2801                 // T_OBJECT_OPERATOR object_property
 
2802                 if (Scanner.TRACE) {
 
2803                         System.out.println("TRACE: dynamic_class_name_variable_property()");
 
2805                 if (token == TokenNameMINUS_GREATER) {
 
2811         private void ctor_arguments() {
 
2814                 // | '(' function_call_parameter_list ')'
 
2815                 if (token == TokenNameLPAREN) {
 
2817                         if (token == TokenNameRPAREN) {
 
2821                         non_empty_function_call_parameter_list();
 
2822                         if (token != TokenNameRPAREN) {
 
2823                                 throwSyntaxError("')' expected in ctor_arguments.");
 
2829         private void assignment_list() {
 
2831                 // assignment_list ',' assignment_list_element
 
2832                 // | assignment_list_element
 
2834                         assignment_list_element();
 
2835                         if (token != TokenNameCOMMA) {
 
2842         private void assignment_list_element() {
 
2843                 // assignment_list_element:
 
2845                 // | T_LIST '(' assignment_list ')'
 
2847                 if (token == TokenNameVariable) {
 
2848                         variable(true, false);
 
2849                 } else if (token == TokenNameDOLLAR) {
 
2850                         variable(false, false);
 
2852                         if (token == TokenNamelist) {
 
2854                                 if (token == TokenNameLPAREN) {
 
2857                                         if (token != TokenNameRPAREN) {
 
2858                                                 throwSyntaxError("')' expected after 'list' keyword.");
 
2862                                         throwSyntaxError("'(' expected after 'list' keyword.");
 
2868         private void array_pair_list() {
 
2871                 // | non_empty_array_pair_list possible_comma
 
2872                 non_empty_array_pair_list();
 
2873                 if (token == TokenNameCOMMA) {
 
2878         private void non_empty_array_pair_list() {
 
2879                 // non_empty_array_pair_list:
 
2880                 // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
 
2881                 // | non_empty_array_pair_list ',' expr
 
2882                 // | expr T_DOUBLE_ARROW expr
 
2884                 // | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
 
2885                 // | non_empty_array_pair_list ',' '&' w_variable
 
2886                 // | expr T_DOUBLE_ARROW '&' w_variable
 
2889                         if (token == TokenNameAND) {
 
2891                                 variable(true, false);
 
2894                                 if (token == TokenNameAND) {
 
2896                                         variable(true, false);
 
2897                                 } else if (token == TokenNameEQUAL_GREATER) {
 
2899                                         if (token == TokenNameAND) {
 
2901                                                 variable(true, false);
 
2907                         if (token != TokenNameCOMMA) {
 
2911                         if (token == TokenNameRPAREN) {
 
2917         // private void variableList() {
 
2920         // if (token == TokenNameCOMMA) {
 
2927         private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) {
 
2928                 // variable_without_objects:
 
2929                 // reference_variable
 
2930                 // | simple_indirect_reference reference_variable
 
2931                 if (Scanner.TRACE) {
 
2932                         System.out.println("TRACE: variable_without_objects()");
 
2934                 while (token == TokenNameDOLLAR) {
 
2937                 return reference_variable(lefthandside, ignoreVar);
 
2940         private Expression function_call(boolean lefthandside, boolean ignoreVar) {
 
2942                 // T_STRING '(' function_call_parameter_list ')'
 
2943                 // | class_constant '(' function_call_parameter_list ')'
 
2944                 // | static_member '(' function_call_parameter_list ')'
 
2945                 // | variable_without_objects '(' function_call_parameter_list ')'
 
2946                 char[] defineName = null;
 
2947                 char[] ident = null;
 
2950                 Expression ref = null;
 
2951                 if (Scanner.TRACE) {
 
2952                         System.out.println("TRACE: function_call()");
 
2954                 if (token == TokenNameIdentifier) {
 
2955                         ident = scanner.getCurrentIdentifierSource();
 
2957                         startPos = scanner.getCurrentTokenStartPosition();
 
2958                         endPos = scanner.getCurrentTokenEndPosition();
 
2961                         case TokenNamePAAMAYIM_NEKUDOTAYIM:
 
2965                                 if (token == TokenNameIdentifier) {
 
2970                                         variable_without_objects(true, false);
 
2975                         ref = variable_without_objects(lefthandside, ignoreVar);
 
2977                 if (token != TokenNameLPAREN) {
 
2978                         if (defineName != null) {
 
2979                                 // does this identifier contain only uppercase characters?
 
2980                                 if (defineName.length == 3) {
 
2981                                         if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') {
 
2984                                 } else if (defineName.length == 4) {
 
2985                                         if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') {
 
2987                                         } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') {
 
2990                                 } else if (defineName.length == 5) {
 
2991                                         if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') {
 
2995                                 if (defineName != null) {
 
2996                                         for (int i = 0; i < defineName.length; i++) {
 
2997                                                 if (Character.isLowerCase(defineName[i])) {
 
2998                                                         problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult);
 
3006                         if (token == TokenNameRPAREN) {
 
3010                         non_empty_function_call_parameter_list();
 
3011                         if (token != TokenNameRPAREN) {
 
3012                                 String functionName;
 
3013                                 if (ident == null) {
 
3014                                         functionName = new String(" ");
 
3016                                         functionName = new String(ident);
 
3018                                 throwSyntaxError("')' expected in function call (" + functionName + ").");
 
3025         // private void function_call_parameter_list() {
 
3026         // function_call_parameter_list:
 
3027         // non_empty_function_call_parameter_list { $$ = $1; }
 
3030         private void non_empty_function_call_parameter_list() {
 
3031                 // non_empty_function_call_parameter_list:
 
3032                 // expr_without_variable
 
3035                 // | non_empty_function_call_parameter_list ',' expr_without_variable
 
3036                 // | non_empty_function_call_parameter_list ',' variable
 
3037                 // | non_empty_function_call_parameter_list ',' '&' w_variable
 
3038                 if (Scanner.TRACE) {
 
3039                         System.out.println("TRACE: non_empty_function_call_parameter_list()");
 
3042                         if (token == TokenNameAND) {
 
3046                                 // if (token == TokenNameIdentifier || token ==
 
3047                                 // TokenNameVariable
 
3048                                 // || token == TokenNameDOLLAR) {
 
3051                                 expr_without_variable(true);
 
3054                         if (token != TokenNameCOMMA) {
 
3061         private void fully_qualified_class_name() {
 
3062                 if (token == TokenNameIdentifier) {
 
3065                         throwSyntaxError("Class name expected.");
 
3069         private void static_member() {
 
3071                 // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM
 
3072                 // variable_without_objects
 
3073                 if (Scanner.TRACE) {
 
3074                         System.out.println("TRACE: static_member()");
 
3076                 fully_qualified_class_name();
 
3077                 if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) {
 
3078                         throwSyntaxError("'::' expected after class name (static_member).");
 
3081                 variable_without_objects(false, false);
 
3084         private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) {
 
3085                 // base_variable_with_function_calls:
 
3088                 if (Scanner.TRACE) {
 
3089                         System.out.println("TRACE: base_variable_with_function_calls()");
 
3091                 return function_call(lefthandside, ignoreVar);
 
3094         private Expression base_variable(boolean lefthandside) {
 
3096                 // reference_variable
 
3097                 // | simple_indirect_reference reference_variable
 
3099                 Expression ref = null;
 
3100                 if (Scanner.TRACE) {
 
3101                         System.out.println("TRACE: base_variable()");
 
3103                 if (token == TokenNameIdentifier) {
 
3106                         while (token == TokenNameDOLLAR) {
 
3109                         reference_variable(lefthandside, false);
 
3114         // private void simple_indirect_reference() {
 
3115         // // simple_indirect_reference:
 
3117         // //| simple_indirect_reference '$'
 
3119         private Expression reference_variable(boolean lefthandside, boolean ignoreVar) {
 
3120                 // reference_variable:
 
3121                 // reference_variable '[' dim_offset ']'
 
3122                 // | reference_variable '{' expr '}'
 
3123                 // | compound_variable
 
3124                 Expression ref = null;
 
3125                 if (Scanner.TRACE) {
 
3126                         System.out.println("TRACE: reference_variable()");
 
3128                 ref = compound_variable(lefthandside, ignoreVar);
 
3130                         if (token == TokenNameLBRACE) {
 
3134                                 if (token != TokenNameRBRACE) {
 
3135                                         throwSyntaxError("'}' expected in reference variable.");
 
3138                         } else if (token == TokenNameLBRACKET) {
 
3139                                 if (ref != null && ref instanceof FieldReference) {
 
3140                                         FieldReference fref = (FieldReference) ref;
 
3141                                         addVariableSet(fref.token);
 
3145                                 if (token != TokenNameRBRACKET) {
 
3148                                         if (token != TokenNameRBRACKET) {
 
3149                                                 throwSyntaxError("']' expected in reference variable.");
 
3160         private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
 
3161                 // compound_variable:
 
3163                 // | '$' '{' expr '}'
 
3164                 if (Scanner.TRACE) {
 
3165                         System.out.println("TRACE: compound_variable()");
 
3167                 if (token == TokenNameVariable) {
 
3168                         if (!lefthandside) {
 
3169                                 if (!containsVariableSet()) {
 
3170                                         // reportSyntaxError("The local variable " + new
 
3171                                         // String(scanner.getCurrentIdentifierSource())
 
3172                                         // + " may not have been initialized");
 
3173                                         problemReporter.uninitializedLocalVariable(new String(scanner.getCurrentIdentifierSource()), scanner
 
3174                                                         .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext,
 
3175                                                         compilationUnit.compilationResult);
 
3182                         FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition());
 
3186                         // because of simple_indirect_reference
 
3187                         while (token == TokenNameDOLLAR) {
 
3190                         if (token != TokenNameLBRACE) {
 
3191                                 reportSyntaxError("'{' expected after compound variable token '$'.");
 
3196                         if (token != TokenNameRBRACE) {
 
3197                                 throwSyntaxError("'}' expected after compound variable token '$'.");
 
3202         } // private void dim_offset() { // // dim_offset: // // /* empty */
 
3207         private void object_property() {
 
3210                 // | variable_without_objects
 
3211                 if (Scanner.TRACE) {
 
3212                         System.out.println("TRACE: object_property()");
 
3214                 if (token == TokenNameVariable || token == TokenNameDOLLAR) {
 
3215                         variable_without_objects(false, false);
 
3221         private void object_dim_list() {
 
3223                 // object_dim_list '[' dim_offset ']'
 
3224                 // | object_dim_list '{' expr '}'
 
3226                 if (Scanner.TRACE) {
 
3227                         System.out.println("TRACE: object_dim_list()");
 
3231                         if (token == TokenNameLBRACE) {
 
3234                                 if (token != TokenNameRBRACE) {
 
3235                                         throwSyntaxError("'}' expected in object_dim_list.");
 
3238                         } else if (token == TokenNameLBRACKET) {
 
3240                                 if (token == TokenNameRBRACKET) {
 
3245                                 if (token != TokenNameRBRACKET) {
 
3246                                         throwSyntaxError("']' expected in object_dim_list.");
 
3255         private void variable_name() {
 
3259                 if (Scanner.TRACE) {
 
3260                         System.out.println("TRACE: variable_name()");
 
3262                 if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
3263                         if (token > TokenNameKEYWORD) {
 
3264                                 // TODO show a warning "Keyword used as variable" ?
 
3268                         if (token != TokenNameLBRACE) {
 
3269                                 throwSyntaxError("'{' expected in variable name.");
 
3273                         if (token != TokenNameRBRACE) {
 
3274                                 throwSyntaxError("'}' expected in variable name.");
 
3280         private void r_variable() {
 
3281                 variable(false, false);
 
3284         private void w_variable(boolean lefthandside) {
 
3285                 variable(lefthandside, false);
 
3288         private void rw_variable() {
 
3289                 variable(false, false);
 
3292         private Expression variable(boolean lefthandside, boolean ignoreVar) {
 
3294                 // base_variable_with_function_calls T_OBJECT_OPERATOR
 
3295                 // object_property method_or_not variable_properties
 
3296                 // | base_variable_with_function_calls
 
3297                 Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar);
 
3298                 if (token == TokenNameMINUS_GREATER) {
 
3303                         variable_properties();
 
3308         private void variable_properties() {
 
3309                 // variable_properties:
 
3310                 // variable_properties variable_property
 
3312                 while (token == TokenNameMINUS_GREATER) {
 
3313                         variable_property();
 
3317         private void variable_property() {
 
3318                 // variable_property:
 
3319                 // T_OBJECT_OPERATOR object_property method_or_not
 
3320                 if (Scanner.TRACE) {
 
3321                         System.out.println("TRACE: variable_property()");
 
3323                 if (token == TokenNameMINUS_GREATER) {
 
3328                         throwSyntaxError("'->' expected in variable_property.");
 
3332         private Expression identifier(boolean lefthandside, boolean ignoreVar) {
 
3334                 // base_variable_with_function_calls T_OBJECT_OPERATOR
 
3335                 // object_property method_or_not variable_properties
 
3336                 // | base_variable_with_function_calls
 
3338                 // Expression ref = function_call(lefthandside, ignoreVar);
 
3341                 // T_STRING '(' function_call_parameter_list ')'
 
3342                 // | class_constant '(' function_call_parameter_list ')'
 
3343                 // | static_member '(' function_call_parameter_list ')'
 
3344                 // | variable_without_objects '(' function_call_parameter_list ')'
 
3345                 char[] defineName = null;
 
3346                 char[] ident = null;
 
3349                 Expression ref = null;
 
3350                 if (Scanner.TRACE) {
 
3351                         System.out.println("TRACE: function_call()");
 
3353                 if (token == TokenNameIdentifier) {
 
3354                         ident = scanner.getCurrentIdentifierSource();
 
3356                         startPos = scanner.getCurrentTokenStartPosition();
 
3357                         endPos = scanner.getCurrentTokenEndPosition();
 
3360                         if (token == TokenNameEQUAL || token == TokenNamePLUS_EQUAL || token == TokenNameMINUS_EQUAL
 
3361                                         || token == TokenNameMULTIPLY_EQUAL || token == TokenNameDIVIDE_EQUAL || token == TokenNameDOT_EQUAL
 
3362                                         || token == TokenNameREMAINDER_EQUAL || token == TokenNameAND_EQUAL || token == TokenNameOR_EQUAL
 
3363                                         || token == TokenNameXOR_EQUAL || token == TokenNameRIGHT_SHIFT_EQUAL || token == TokenNameLEFT_SHIFT_EQUAL) {
 
3364                                 String error = "Assignment operator '" + scanner.toStringAction(token) + "' not allowed after identifier '"
 
3365                                                 + new String(ident) + "' (use 'define(...)' to define constants).";
 
3366                                 reportSyntaxError(error);
 
3370                         case TokenNamePAAMAYIM_NEKUDOTAYIM:
 
3374                                 if (token == TokenNameIdentifier) {
 
3379                                         variable_without_objects(true, false);
 
3384                         ref = variable_without_objects(lefthandside, ignoreVar);
 
3386                 if (token != TokenNameLPAREN) {
 
3387                         if (defineName != null) {
 
3388                                 // does this identifier contain only uppercase characters?
 
3389                                 if (defineName.length == 3) {
 
3390                                         if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') {
 
3393                                 } else if (defineName.length == 4) {
 
3394                                         if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') {
 
3396                                         } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') {
 
3399                                 } else if (defineName.length == 5) {
 
3400                                         if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') {
 
3404                                 if (defineName != null) {
 
3405                                         for (int i = 0; i < defineName.length; i++) {
 
3406                                                 if (Character.isLowerCase(defineName[i])) {
 
3407                                                         problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult);
 
3413                         // TODO is this ok ?
 
3415                         // throwSyntaxError("'(' expected in function call.");
 
3419                         if (token == TokenNameRPAREN) {
 
3423                                 non_empty_function_call_parameter_list();
 
3424                                 if (token != TokenNameRPAREN) {
 
3425                                         String functionName;
 
3426                                         if (ident == null) {
 
3427                                                 functionName = new String(" ");
 
3429                                                 functionName = new String(ident);
 
3431                                         throwSyntaxError("')' expected in function call (" + functionName + ").");
 
3436                 if (token == TokenNameMINUS_GREATER) {
 
3441                         variable_properties();
 
3446         private void method_or_not() {
 
3448                 // '(' function_call_parameter_list ')'
 
3450                 if (Scanner.TRACE) {
 
3451                         System.out.println("TRACE: method_or_not()");
 
3453                 if (token == TokenNameLPAREN) {
 
3455                         if (token == TokenNameRPAREN) {
 
3459                         non_empty_function_call_parameter_list();
 
3460                         if (token != TokenNameRPAREN) {
 
3461                                 throwSyntaxError("')' expected in method_or_not.");
 
3467         private void exit_expr() {
 
3471                 if (token != TokenNameLPAREN) {
 
3475                 if (token == TokenNameRPAREN) {
 
3480                 if (token != TokenNameRPAREN) {
 
3481                         throwSyntaxError("')' expected after keyword 'exit'");
 
3486         // private void encaps_list() {
 
3487         // // encaps_list encaps_var
 
3488         // // | encaps_list T_STRING
 
3489         // // | encaps_list T_NUM_STRING
 
3490         // // | encaps_list T_ENCAPSED_AND_WHITESPACE
 
3491         // // | encaps_list T_CHARACTER
 
3492         // // | encaps_list T_BAD_CHARACTER
 
3493         // // | encaps_list '['
 
3494         // // | encaps_list ']'
 
3495         // // | encaps_list '{'
 
3496         // // | encaps_list '}'
 
3497         // // | encaps_list T_OBJECT_OPERATOR
 
3501         // case TokenNameSTRING:
 
3504         // case TokenNameLBRACE:
 
3505         // // scanner.encapsedStringStack.pop();
 
3508         // case TokenNameRBRACE:
 
3509         // // scanner.encapsedStringStack.pop();
 
3512         // case TokenNameLBRACKET:
 
3513         // // scanner.encapsedStringStack.pop();
 
3516         // case TokenNameRBRACKET:
 
3517         // // scanner.encapsedStringStack.pop();
 
3520         // case TokenNameMINUS_GREATER:
 
3521         // // scanner.encapsedStringStack.pop();
 
3524         // case TokenNameVariable:
 
3525         // case TokenNameDOLLAR_LBRACE:
 
3526         // case TokenNameLBRACE_DOLLAR:
 
3530         // char encapsedChar = ((Character)
 
3531         // scanner.encapsedStringStack.peek()).charValue();
 
3532         // if (encapsedChar == '$') {
 
3533         // scanner.encapsedStringStack.pop();
 
3534         // encapsedChar = ((Character)
 
3535         // scanner.encapsedStringStack.peek()).charValue();
 
3536         // switch (encapsedChar) {
 
3538         // if (token == TokenNameEncapsedString0) {
 
3541         // token = TokenNameSTRING;
 
3544         // if (token == TokenNameEncapsedString1) {
 
3547         // token = TokenNameSTRING;
 
3550         // if (token == TokenNameEncapsedString2) {
 
3553         // token = TokenNameSTRING;
 
3562         // private void encaps_var() {
 
3564         // // | T_VARIABLE '[' encaps_var_offset ']'
 
3565         // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING
 
3566         // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}'
 
3567         // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
 
3568         // // | T_CURLY_OPEN variable '}'
 
3570         // case TokenNameVariable:
 
3572         // if (token == TokenNameLBRACKET) {
 
3574         // expr(); //encaps_var_offset();
 
3575         // if (token != TokenNameRBRACKET) {
 
3576         // throwSyntaxError("']' expected after variable.");
 
3578         // // scanner.encapsedStringStack.pop();
 
3581         // } else if (token == TokenNameMINUS_GREATER) {
 
3583         // if (token != TokenNameIdentifier) {
 
3584         // throwSyntaxError("Identifier expected after '->'.");
 
3586         // // scanner.encapsedStringStack.pop();
 
3590         // // // scanner.encapsedStringStack.pop();
 
3591         // // int tempToken = TokenNameSTRING;
 
3592         // // if (!scanner.encapsedStringStack.isEmpty()
 
3593         // // && (token == TokenNameEncapsedString0
 
3594         // // || token == TokenNameEncapsedString1
 
3595         // // || token == TokenNameEncapsedString2 || token ==
 
3596         // // TokenNameERROR)) {
 
3597         // // char encapsedChar = ((Character)
 
3598         // // scanner.encapsedStringStack.peek())
 
3600         // // switch (token) {
 
3601         // // case TokenNameEncapsedString0 :
 
3602         // // if (encapsedChar == '`') {
 
3603         // // tempToken = TokenNameEncapsedString0;
 
3606         // // case TokenNameEncapsedString1 :
 
3607         // // if (encapsedChar == '\'') {
 
3608         // // tempToken = TokenNameEncapsedString1;
 
3611         // // case TokenNameEncapsedString2 :
 
3612         // // if (encapsedChar == '"') {
 
3613         // // tempToken = TokenNameEncapsedString2;
 
3616         // // case TokenNameERROR :
 
3617         // // if (scanner.source[scanner.currentPosition - 1] == '\\') {
 
3618         // // scanner.currentPosition--;
 
3619         // // getNextToken();
 
3624         // // token = tempToken;
 
3627         // case TokenNameDOLLAR_LBRACE:
 
3629         // if (token == TokenNameDOLLAR_LBRACE) {
 
3631         // } else if (token == TokenNameIdentifier) {
 
3633         // if (token == TokenNameLBRACKET) {
 
3635         // // if (token == TokenNameRBRACKET) {
 
3636         // // getNextToken();
 
3639         // if (token != TokenNameRBRACKET) {
 
3640         // throwSyntaxError("']' expected after '${'.");
 
3648         // if (token != TokenNameRBRACE) {
 
3649         // throwSyntaxError("'}' expected.");
 
3653         // case TokenNameLBRACE_DOLLAR:
 
3655         // if (token == TokenNameLBRACE_DOLLAR) {
 
3657         // } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) {
 
3659         // if (token == TokenNameLBRACKET) {
 
3661         // // if (token == TokenNameRBRACKET) {
 
3662         // // getNextToken();
 
3665         // if (token != TokenNameRBRACKET) {
 
3666         // throwSyntaxError("']' expected.");
 
3670         // } else if (token == TokenNameMINUS_GREATER) {
 
3672         // if (token != TokenNameIdentifier && token != TokenNameVariable) {
 
3673         // throwSyntaxError("String or Variable token expected.");
 
3676         // if (token == TokenNameLBRACKET) {
 
3678         // // if (token == TokenNameRBRACKET) {
 
3679         // // getNextToken();
 
3682         // if (token != TokenNameRBRACKET) {
 
3683         // throwSyntaxError("']' expected after '${'.");
 
3689         // // if (token != TokenNameRBRACE) {
 
3690         // // throwSyntaxError("'}' expected after '{$'.");
 
3692         // // // scanner.encapsedStringStack.pop();
 
3693         // // getNextToken();
 
3696         // if (token != TokenNameRBRACE) {
 
3697         // throwSyntaxError("'}' expected.");
 
3699         // // scanner.encapsedStringStack.pop();
 
3706         // private void encaps_var_offset() {
 
3708         // // | T_NUM_STRING
 
3711         // case TokenNameSTRING:
 
3714         // case TokenNameIntegerLiteral:
 
3717         // case TokenNameVariable:
 
3720         // case TokenNameIdentifier:
 
3724         // throwSyntaxError("Variable or String token expected.");
 
3729         private void internal_functions_in_yacc() {
 
3732                 // case TokenNameisset:
 
3733                 // // T_ISSET '(' isset_variables ')'
 
3735                 // if (token != TokenNameLPAREN) {
 
3736                 // throwSyntaxError("'(' expected after keyword 'isset'");
 
3739                 // isset_variables();
 
3740                 // if (token != TokenNameRPAREN) {
 
3741                 // throwSyntaxError("')' expected after keyword 'isset'");
 
3745                 // case TokenNameempty:
 
3746                 // // T_EMPTY '(' variable ')'
 
3748                 // if (token != TokenNameLPAREN) {
 
3749                 // throwSyntaxError("'(' expected after keyword 'empty'");
 
3753                 // if (token != TokenNameRPAREN) {
 
3754                 // throwSyntaxError("')' expected after keyword 'empty'");
 
3758                 case TokenNameinclude:
 
3760                         checkFileName(token);
 
3762                 case TokenNameinclude_once:
 
3763                         // T_INCLUDE_ONCE expr
 
3764                         checkFileName(token);
 
3767                         // T_EVAL '(' expr ')'
 
3769                         if (token != TokenNameLPAREN) {
 
3770                                 throwSyntaxError("'(' expected after keyword 'eval'");
 
3774                         if (token != TokenNameRPAREN) {
 
3775                                 throwSyntaxError("')' expected after keyword 'eval'");
 
3779                 case TokenNamerequire:
 
3781                         checkFileName(token);
 
3783                 case TokenNamerequire_once:
 
3784                         // T_REQUIRE_ONCE expr
 
3785                         checkFileName(token);
 
3791          * Parse and check the include file name
 
3793          * @param includeToken
 
3795         private void checkFileName(int includeToken) {
 
3796                 // <include-token> expr
 
3797                 int start = scanner.getCurrentTokenStartPosition();
 
3798                 boolean hasLPAREN = false;
 
3800                 if (token == TokenNameLPAREN) {
 
3804                 Expression expression = expr();
 
3806                         if (token == TokenNameRPAREN) {
 
3809                                 throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'");
 
3812                 char[] currTokenSource = scanner.getCurrentTokenSource(start);
 
3814                 if (scanner.compilationUnit != null) {
 
3815                         IResource resource = scanner.compilationUnit.getResource();
 
3816                         if (resource != null && resource instanceof IFile) {
 
3817                                 file = (IFile) resource;
 
3821                 tokens = new char[1][];
 
3822                 tokens[0] = currTokenSource;
 
3824                 ImportReference impt = new ImportReference(tokens, currTokenSource, start, scanner.getCurrentTokenEndPosition(), false);
 
3825                 impt.declarationSourceEnd = impt.sourceEnd;
 
3826                 impt.declarationEnd = impt.declarationSourceEnd;
 
3827                 // endPosition is just before the ;
 
3828                 impt.declarationSourceStart = start;
 
3829                 includesList.add(impt);
 
3831                 if (expression instanceof StringLiteral) {
 
3832                         StringLiteral literal = (StringLiteral) expression;
 
3833                         char[] includeName = literal.source();
 
3834                         if (includeName.length == 0) {
 
3835                                 reportSyntaxError("Empty filename after keyword '" + scanner.toStringAction(includeToken) + "'", literal.sourceStart,
 
3836                                                 literal.sourceStart + 1);
 
3838                         String includeNameString = new String(includeName);
 
3839                         if (literal instanceof StringLiteralDQ) {
 
3840                                 if (includeNameString.indexOf('$') >= 0) {
 
3841                                         // assuming that the filename contains a variable => no filename check
 
3845                         if (includeNameString.startsWith("http://")) {
 
3846                                 // assuming external include location
 
3850                                 // check the filename:
 
3851                                 // System.out.println(new String(compilationUnit.getFileName())+" - "+
 
3852                                 // expression.toStringExpression());
 
3853                                 IProject project = file.getProject();
 
3854                                 if (project != null) {
 
3855                                         IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project);
 
3858                                                 // SyntaxError: "File: << >> doesn't exist in project."
 
3859                                                 String[] args = { expression.toStringExpression(), project.getLocation().toString() };
 
3860                                                 problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext,
 
3861                                                                 compilationUnit.compilationResult);
 
3864                                                         String filePath = path.toString();
 
3865                                                         String ext = file.getRawLocation().getFileExtension();
 
3866                                                         int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
 
3868                                                         impt.tokens = CharOperation.splitOn('/', filePath.toCharArray(), 0, filePath.length() - fileExtensionLength);
 
3869                                                         impt.setFile(PHPFileUtil.createFile(path, project));
 
3870                                                 } catch (Exception e) {
 
3871                                                         // the file is outside of the workspace
 
3879         private void isset_variables() {
 
3881                 // | isset_variables ','
 
3882                 if (token == TokenNameRPAREN) {
 
3883                         throwSyntaxError("Variable expected after keyword 'isset'");
 
3886                         variable(true, false);
 
3887                         if (token == TokenNameCOMMA) {
 
3895         private boolean common_scalar() {
 
3899                 // | T_CONSTANT_ENCAPSED_STRING
 
3906                 case TokenNameIntegerLiteral:
 
3909                 case TokenNameDoubleLiteral:
 
3912                 case TokenNameStringDoubleQuote:
 
3915                 case TokenNameStringSingleQuote:
 
3918                 case TokenNameStringInterpolated:
 
3927                 case TokenNameCLASS_C:
 
3930                 case TokenNameMETHOD_C:
 
3933                 case TokenNameFUNC_C:
 
3940         private void scalar() {
 
3943                 // | T_STRING_VARNAME
 
3946                 // | '"' encaps_list '"'
 
3947                 // | '\'' encaps_list '\''
 
3948                 // | T_START_HEREDOC encaps_list T_END_HEREDOC
 
3949                 throwSyntaxError("Not yet implemented (scalar).");
 
3952         private void static_scalar() {
 
3953                 // static_scalar: /* compile-time evaluated scalars */
 
3956                 // | '+' static_scalar
 
3957                 // | '-' static_scalar
 
3958                 // | T_ARRAY '(' static_array_pair_list ')'
 
3959                 // | static_class_constant
 
3960                 if (common_scalar()) {
 
3964                 case TokenNameIdentifier:
 
3966                         // static_class_constant:
 
3967                         // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING
 
3968                         if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) {
 
3970                                 if (token == TokenNameIdentifier) {
 
3973                                         throwSyntaxError("Identifier expected after '::' operator.");
 
3977                 case TokenNameEncapsedString0:
 
3979                                 scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3980                                 while (scanner.currentCharacter != '`') {
 
3981                                         if (scanner.currentCharacter == '\\') {
 
3982                                                 scanner.currentPosition++;
 
3984                                         scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3987                         } catch (IndexOutOfBoundsException e) {
 
3988                                 throwSyntaxError("'`' expected at end of static string.");
 
3991                 // case TokenNameEncapsedString1:
 
3993                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
3994                 // while (scanner.currentCharacter != '\'') {
 
3995                 // if (scanner.currentCharacter == '\\') {
 
3996                 // scanner.currentPosition++;
 
3998                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4001                 // } catch (IndexOutOfBoundsException e) {
 
4002                 // throwSyntaxError("'\'' expected at end of static string.");
 
4005                 // case TokenNameEncapsedString2:
 
4007                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4008                 // while (scanner.currentCharacter != '"') {
 
4009                 // if (scanner.currentCharacter == '\\') {
 
4010                 // scanner.currentPosition++;
 
4012                 // scanner.currentCharacter = scanner.source[scanner.currentPosition++];
 
4015                 // } catch (IndexOutOfBoundsException e) {
 
4016                 // throwSyntaxError("'\"' expected at end of static string.");
 
4019                 case TokenNameStringSingleQuote:
 
4022                 case TokenNameStringDoubleQuote:
 
4029                 case TokenNameMINUS:
 
4033                 case TokenNamearray:
 
4035                         if (token != TokenNameLPAREN) {
 
4036                                 throwSyntaxError("'(' expected after keyword 'array'");
 
4039                         if (token == TokenNameRPAREN) {
 
4043                         non_empty_static_array_pair_list();
 
4044                         if (token != TokenNameRPAREN) {
 
4045                                 throwSyntaxError("')' or ',' expected after keyword 'array'");
 
4049                 // case TokenNamenull :
 
4052                 // case TokenNamefalse :
 
4055                 // case TokenNametrue :
 
4059                         throwSyntaxError("Static scalar/constant expected.");
 
4063         private void non_empty_static_array_pair_list() {
 
4064                 // non_empty_static_array_pair_list:
 
4065                 // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW
 
4067                 // | non_empty_static_array_pair_list ',' static_scalar
 
4068                 // | static_scalar T_DOUBLE_ARROW static_scalar
 
4072                         if (token == TokenNameEQUAL_GREATER) {
 
4076                         if (token != TokenNameCOMMA) {
 
4080                         if (token == TokenNameRPAREN) {
 
4086         // public void reportSyntaxError() { //int act, int currentKind, int
 
4087         // // stateStackTop) {
 
4088         // /* remember current scanner position */
 
4089         // int startPos = scanner.startPosition;
 
4090         // int currentPos = scanner.currentPosition;
 
4092         // this.checkAndReportBracketAnomalies(problemReporter());
 
4093         // /* reset scanner where it was */
 
4094         // scanner.startPosition = startPos;
 
4095         // scanner.currentPosition = currentPos;
 
4098         public static final int RoundBracket = 0;
 
4100         public static final int SquareBracket = 1;
 
4102         public static final int CurlyBracket = 2;
 
4104         public static final int BracketKinds = 3;
 
4106         protected int[] nestedMethod; // the ptr is nestedType
 
4108         protected int nestedType, dimensions;
 
4110         // variable set stack
 
4111         final static int VariableStackIncrement = 10;
 
4113         HashMap fTypeVariables = null;
 
4115         HashMap fMethodVariables = null;
 
4117         ArrayList fStackUnassigned = new ArrayList();
 
4120         final static int AstStackIncrement = 100;
 
4122         protected int astPtr;
 
4124         protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
 
4126         protected int astLengthPtr;
 
4128         protected int[] astLengthStack;
 
4130         ASTNode[] noAstNodes = new ASTNode[AstStackIncrement];
 
4132         public CompilationUnitDeclaration compilationUnit; /*
 
4133                                                                                                                                                                                                                          * the result from parse()
 
4136         protected ReferenceContext referenceContext;
 
4138         protected ProblemReporter problemReporter;
 
4140         protected CompilerOptions options;
 
4142         private ArrayList includesList;
 
4144         // protected CompilationResult compilationResult;
 
4146          * Returns this parser's problem reporter initialized with its reference
 
4147          * context. Also it is assumed that a problem is going to be reported, so
 
4148          * initializes the compilation result's line positions.
 
4150         public ProblemReporter problemReporter() {
 
4151                 if (scanner.recordLineSeparator) {
 
4152                         compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
 
4154                 problemReporter.referenceContext = referenceContext;
 
4155                 return problemReporter;
 
4159          * Reconsider the entire source looking for inconsistencies in {} () []
 
4161         // public boolean checkAndReportBracketAnomalies(ProblemReporter
 
4162         // problemReporter) {
 
4163         // scanner.wasAcr = false;
 
4164         // boolean anomaliesDetected = false;
 
4166         // char[] source = scanner.source;
 
4167         // int[] leftCount = { 0, 0, 0 };
 
4168         // int[] rightCount = { 0, 0, 0 };
 
4169         // int[] depths = { 0, 0, 0 };
 
4170         // int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10]
 
4172         // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
 
4173         // int[][] rightPositions = new int[][] { new int[10], new int[10], new
 
4175         // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10]
 
4177         // scanner.currentPosition = scanner.initialPosition; //starting
 
4179         // // (first-zero-based
 
4181         // while (scanner.currentPosition < scanner.eofPosition) { //loop for
 
4186         // // ---------Consume white space and handles
 
4187         // // startPosition---------
 
4188         // boolean isWhiteSpace;
 
4190         // scanner.startPosition = scanner.currentPosition;
 
4191         // // if (((scanner.currentCharacter =
 
4192         // // source[scanner.currentPosition++]) == '\\') &&
 
4193         // // (source[scanner.currentPosition] == 'u')) {
 
4194         // // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
 
4196         // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
 
4197         // (scanner.currentCharacter == '\n'))) {
 
4198         // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
4199         // // only record line positions we have not
 
4201         // scanner.pushLineSeparator();
 
4204         // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
 
4206         // } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
 
4207         // // -------consume token until } is found---------
 
4208         // switch (scanner.currentCharacter) {
 
4210         // int index = leftCount[CurlyBracket]++;
 
4211         // if (index == leftPositions[CurlyBracket].length) {
 
4212         // System.arraycopy(leftPositions[CurlyBracket], 0,
 
4213         // (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
4214         // System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] =
 
4215         // new int[index * 2]), 0, index);
 
4217         // leftPositions[CurlyBracket][index] = scanner.startPosition;
 
4218         // leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
 
4222         // int index = rightCount[CurlyBracket]++;
 
4223         // if (index == rightPositions[CurlyBracket].length) {
 
4224         // System.arraycopy(rightPositions[CurlyBracket], 0,
 
4225         // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
 
4226         // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] =
 
4227         // new int[index * 2]), 0, index);
 
4229         // rightPositions[CurlyBracket][index] = scanner.startPosition;
 
4230         // rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
 
4234         // int index = leftCount[RoundBracket]++;
 
4235         // if (index == leftPositions[RoundBracket].length) {
 
4236         // System.arraycopy(leftPositions[RoundBracket], 0,
 
4237         // (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
 
4238         // System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] =
 
4239         // new int[index * 2]), 0, index);
 
4241         // leftPositions[RoundBracket][index] = scanner.startPosition;
 
4242         // leftDepths[RoundBracket][index] = depths[RoundBracket]++;
 
4246         // int index = rightCount[RoundBracket]++;
 
4247         // if (index == rightPositions[RoundBracket].length) {
 
4248         // System.arraycopy(rightPositions[RoundBracket], 0,
 
4249         // (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
 
4250         // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] =
 
4251         // new int[index * 2]), 0, index);
 
4253         // rightPositions[RoundBracket][index] = scanner.startPosition;
 
4254         // rightDepths[RoundBracket][index] = --depths[RoundBracket];
 
4258         // int index = leftCount[SquareBracket]++;
 
4259         // if (index == leftPositions[SquareBracket].length) {
 
4260         // System.arraycopy(leftPositions[SquareBracket], 0,
 
4261         // (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
 
4262         // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] =
 
4263         // new int[index * 2]), 0, index);
 
4265         // leftPositions[SquareBracket][index] = scanner.startPosition;
 
4266         // leftDepths[SquareBracket][index] = depths[SquareBracket]++;
 
4270         // int index = rightCount[SquareBracket]++;
 
4271         // if (index == rightPositions[SquareBracket].length) {
 
4272         // System.arraycopy(rightPositions[SquareBracket], 0,
 
4273         // (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
 
4274         // System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket]
 
4275         // = new int[index * 2]), 0, index);
 
4277         // rightPositions[SquareBracket][index] = scanner.startPosition;
 
4278         // rightDepths[SquareBracket][index] = --depths[SquareBracket];
 
4282         // if (scanner.getNextChar('\\')) {
 
4283         // scanner.scanEscapeCharacter();
 
4284         // } else { // consume next character
 
4285         // scanner.unicodeAsBackSlash = false;
 
4286         // // if (((scanner.currentCharacter =
 
4287         // // source[scanner.currentPosition++]) ==
 
4289         // // (source[scanner.currentPosition] ==
 
4291         // // scanner.getNextUnicodeChar();
 
4293         // if (scanner.withoutUnicodePtr != 0) {
 
4294         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
4295         // scanner.currentCharacter;
 
4299         // scanner.getNextChar('\'');
 
4303         // // consume next character
 
4304         // scanner.unicodeAsBackSlash = false;
 
4305         // // if (((scanner.currentCharacter =
 
4306         // // source[scanner.currentPosition++]) == '\\') &&
 
4307         // // (source[scanner.currentPosition] == 'u')) {
 
4308         // // scanner.getNextUnicodeChar();
 
4310         // if (scanner.withoutUnicodePtr != 0) {
 
4311         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
4312         // scanner.currentCharacter;
 
4315         // while (scanner.currentCharacter != '"') {
 
4316         // if (scanner.currentCharacter == '\r') {
 
4317         // if (source[scanner.currentPosition] == '\n')
 
4318         // scanner.currentPosition++;
 
4319         // break; // the string cannot go further that
 
4322         // if (scanner.currentCharacter == '\n') {
 
4323         // break; // the string cannot go further that
 
4326         // if (scanner.currentCharacter == '\\') {
 
4327         // scanner.scanEscapeCharacter();
 
4329         // // consume next character
 
4330         // scanner.unicodeAsBackSlash = false;
 
4331         // // if (((scanner.currentCharacter =
 
4332         // // source[scanner.currentPosition++]) == '\\')
 
4333         // // && (source[scanner.currentPosition] == 'u'))
 
4335         // // scanner.getNextUnicodeChar();
 
4337         // if (scanner.withoutUnicodePtr != 0) {
 
4338         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
4339         // scanner.currentCharacter;
 
4346         // if ((test = scanner.getNextChar('/', '*')) == 0) { //line
 
4348         // //get the next char
 
4349         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
4351         // && (source[scanner.currentPosition] == 'u')) {
 
4352         // //-------------unicode traitement
 
4354         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
4355         // scanner.currentPosition++;
 
4356         // while (source[scanner.currentPosition] == 'u') {
 
4357         // scanner.currentPosition++;
 
4359         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
4361         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4363         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4365         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4366         // || c4 < 0) { //error
 
4370         // scanner.currentCharacter = 'A';
 
4371         // } //something different from \n and \r
 
4373         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
4376         // while (scanner.currentCharacter != '\r' && scanner.currentCharacter !=
 
4378         // //get the next char
 
4379         // scanner.startPosition = scanner.currentPosition;
 
4380         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
4382         // && (source[scanner.currentPosition] == 'u')) {
 
4383         // //-------------unicode traitement
 
4385         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
4386         // scanner.currentPosition++;
 
4387         // while (source[scanner.currentPosition] == 'u') {
 
4388         // scanner.currentPosition++;
 
4390         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
4392         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4394         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4396         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4397         // || c4 < 0) { //error
 
4401         // scanner.currentCharacter = 'A';
 
4402         // } //something different from \n
 
4405         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
4409         // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') ||
 
4410         // (scanner.currentCharacter == '\n'))) {
 
4411         // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
 
4412         // // only record line positions we
 
4413         // // have not recorded yet
 
4414         // scanner.pushLineSeparator();
 
4415         // if (this.scanner.taskTags != null) {
 
4416         // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
 
4418         // .getCurrentTokenEndPosition());
 
4424         // if (test > 0) { //traditional and annotation
 
4426         // boolean star = false;
 
4427         // // consume next character
 
4428         // scanner.unicodeAsBackSlash = false;
 
4429         // // if (((scanner.currentCharacter =
 
4430         // // source[scanner.currentPosition++]) ==
 
4432         // // (source[scanner.currentPosition] ==
 
4434         // // scanner.getNextUnicodeChar();
 
4436         // if (scanner.withoutUnicodePtr != 0) {
 
4437         // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] =
 
4438         // scanner.currentCharacter;
 
4441         // if (scanner.currentCharacter == '*') {
 
4444         // //get the next char
 
4445         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
4447         // && (source[scanner.currentPosition] == 'u')) {
 
4448         // //-------------unicode traitement
 
4450         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
4451         // scanner.currentPosition++;
 
4452         // while (source[scanner.currentPosition] == 'u') {
 
4453         // scanner.currentPosition++;
 
4455         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
4457         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4459         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4461         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4462         // || c4 < 0) { //error
 
4466         // scanner.currentCharacter = 'A';
 
4467         // } //something different from * and /
 
4469         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
4472         // //loop until end of comment */
 
4473         // while ((scanner.currentCharacter != '/') || (!star)) {
 
4474         // star = scanner.currentCharacter == '*';
 
4476         // if (((scanner.currentCharacter = source[scanner.currentPosition++]) ==
 
4478         // && (source[scanner.currentPosition] == 'u')) {
 
4479         // //-------------unicode traitement
 
4481         // int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
 
4482         // scanner.currentPosition++;
 
4483         // while (source[scanner.currentPosition] == 'u') {
 
4484         // scanner.currentPosition++;
 
4486         // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) >
 
4488         // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4490         // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4492         // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
 
4493         // || c4 < 0) { //error
 
4497         // scanner.currentCharacter = 'A';
 
4498         // } //something different from * and
 
4501         // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
 
4505         // if (this.scanner.taskTags != null) {
 
4506         // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(),
 
4507         // this.scanner.getCurrentTokenEndPosition());
 
4514         // if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
 
4515         // scanner.scanIdentifierOrKeyword(false);
 
4518         // if (Character.isDigit(scanner.currentCharacter)) {
 
4519         // scanner.scanNumber(false);
 
4523         // //-----------------end switch while
 
4524         // // try--------------------
 
4525         // } catch (IndexOutOfBoundsException e) {
 
4526         // break; // read until EOF
 
4527         // } catch (InvalidInputException e) {
 
4528         // return false; // no clue
 
4531         // if (scanner.recordLineSeparator) {
 
4532         // compilationUnit.compilationResult.lineSeparatorPositions =
 
4533         // scanner.getLineEnds();
 
4535         // // check placement anomalies against other kinds of brackets
 
4536         // for (int kind = 0; kind < BracketKinds; kind++) {
 
4537         // for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
 
4538         // int start = leftPositions[kind][leftIndex]; // deepest
 
4540         // // find matching closing bracket
 
4541         // int depth = leftDepths[kind][leftIndex];
 
4543         // for (int i = 0; i < rightCount[kind]; i++) {
 
4544         // int pos = rightPositions[kind][i];
 
4545         // // want matching bracket further in source with same
 
4547         // if ((pos > start) && (depth == rightDepths[kind][i])) {
 
4552         // if (end < 0) { // did not find a good closing match
 
4553         // problemReporter.unmatchedBracket(start, referenceContext,
 
4554         // compilationUnit.compilationResult);
 
4557         // // check if even number of opening/closing other brackets
 
4558         // // in between this pair of brackets
 
4560         // for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds);
 
4562         // for (int i = 0; i < leftCount[otherKind]; i++) {
 
4563         // int pos = leftPositions[otherKind][i];
 
4564         // if ((pos > start) && (pos < end))
 
4567         // for (int i = 0; i < rightCount[otherKind]; i++) {
 
4568         // int pos = rightPositions[otherKind][i];
 
4569         // if ((pos > start) && (pos < end))
 
4572         // if (balance != 0) {
 
4573         // problemReporter.unmatchedBracket(start, referenceContext,
 
4574         // compilationUnit.compilationResult); //bracket
 
4580         // // too many opening brackets ?
 
4581         // for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
 
4582         // anomaliesDetected = true;
 
4583         // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i -
 
4584         // 1], referenceContext,
 
4585         // compilationUnit.compilationResult);
 
4587         // // too many closing brackets ?
 
4588         // for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
 
4589         // anomaliesDetected = true;
 
4590         // problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext,
 
4591         // compilationUnit.compilationResult);
 
4593         // if (anomaliesDetected)
 
4596         // return anomaliesDetected;
 
4597         // } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
 
4598         // return anomaliesDetected;
 
4599         // } catch (NullPointerException e) { // jdk1.2.2 jit bug
 
4600         // return anomaliesDetected;
 
4603         protected void pushOnAstLengthStack(int pos) {
 
4605                         astLengthStack[++astLengthPtr] = pos;
 
4606                 } catch (IndexOutOfBoundsException e) {
 
4607                         int oldStackLength = astLengthStack.length;
 
4608                         int[] oldPos = astLengthStack;
 
4609                         astLengthStack = new int[oldStackLength + StackIncrement];
 
4610                         System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
4611                         astLengthStack[astLengthPtr] = pos;
 
4615         protected void pushOnAstStack(ASTNode node) {
 
4617                  * add a new obj on top of the ast stack
 
4620                         astStack[++astPtr] = node;
 
4621                 } catch (IndexOutOfBoundsException e) {
 
4622                         int oldStackLength = astStack.length;
 
4623                         ASTNode[] oldStack = astStack;
 
4624                         astStack = new ASTNode[oldStackLength + AstStackIncrement];
 
4625                         System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
 
4626                         astPtr = oldStackLength;
 
4627                         astStack[astPtr] = node;
 
4630                         astLengthStack[++astLengthPtr] = 1;
 
4631                 } catch (IndexOutOfBoundsException e) {
 
4632                         int oldStackLength = astLengthStack.length;
 
4633                         int[] oldPos = astLengthStack;
 
4634                         astLengthStack = new int[oldStackLength + AstStackIncrement];
 
4635                         System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
 
4636                         astLengthStack[astLengthPtr] = 1;
 
4640         protected void resetModifiers() {
 
4641                 this.modifiers = AccDefault;
 
4642                 this.modifiersSourceStart = -1; // <-- see comment into
 
4643                 // modifiersFlag(int)
 
4644                 this.scanner.commentPtr = -1;
 
4647         protected void consumePackageDeclarationName(IFile file) {
 
4648                 // create a package name similar to java package names
 
4649                 String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString();
 
4650                 String filePath = file.getRawLocation().toString();
 
4651                 String ext = file.getRawLocation().getFileExtension();
 
4652                 int fileExtensionLength = ext == null ? 0 : ext.length() + 1;
 
4653                 ImportReference impt;
 
4655                 if (filePath.startsWith(projectPath)) {
 
4656                         tokens = CharOperation
 
4657                                         .splitOn('/', filePath.toCharArray(), projectPath.length() + 1, filePath.length() - fileExtensionLength);
 
4659                         String name = file.getName();
 
4660                         tokens = new char[1][];
 
4661                         tokens[0] = name.substring(0, name.length() - fileExtensionLength).toCharArray();
 
4664                 this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true);
 
4666                 impt.declarationSourceStart = 0;
 
4667                 impt.declarationSourceEnd = 0;
 
4668                 impt.declarationEnd = 0;
 
4669                 // endPosition is just before the ;
 
4673         public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV", "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST",
 
4674                         "$_SESSION", "$_SERVER" };
 
4679         private void pushFunctionVariableSet() {
 
4680                 HashSet set = new HashSet();
 
4681                 if (fStackUnassigned.isEmpty()) {
 
4682                         for (int i = 0; i < GLOBALS.length; i++) {
 
4683                                 set.add(GLOBALS[i]);
 
4686                 fStackUnassigned.add(set);
 
4689         private void pushIfVariableSet() {
 
4690                 if (!fStackUnassigned.isEmpty()) {
 
4691                         HashSet set = new HashSet();
 
4692                         fStackUnassigned.add(set);
 
4696         private HashSet removeIfVariableSet() {
 
4697                 if (!fStackUnassigned.isEmpty()) {
 
4698                         return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1);
 
4704          * Returns the <i>set of assigned variables </i> returns null if no Set is
 
4705          * defined at the current scanner position
 
4707         private HashSet peekVariableSet() {
 
4708                 if (!fStackUnassigned.isEmpty()) {
 
4709                         return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1);
 
4715          * add the current identifier source to the <i>set of assigned variables </i>
 
4719         private void addVariableSet(HashSet set) {
 
4721                         set.add(new String(scanner.getCurrentTokenSource()));
 
4726          * add the current identifier source to the <i>set of assigned variables </i>
 
4729         private void addVariableSet() {
 
4730                 HashSet set = peekVariableSet();
 
4732                         set.add(new String(scanner.getCurrentTokenSource()));
 
4737          * add the current identifier source to the <i>set of assigned variables </i>
 
4740         private void addVariableSet(char[] token) {
 
4741                 HashSet set = peekVariableSet();
 
4743                         set.add(new String(token));
 
4748          * check if the current identifier source is in the <i>set of assigned
 
4749          * variables </i> Returns true, if no set is defined for the current scanner
 
4753         private boolean containsVariableSet() {
 
4754                 return containsVariableSet(scanner.getCurrentTokenSource());
 
4757         private boolean containsVariableSet(char[] token) {
 
4759                 if (!fStackUnassigned.isEmpty()) {
 
4761                         String str = new String(token);
 
4762                         for (int i = 0; i < fStackUnassigned.size(); i++) {
 
4763                                 set = (HashSet) fStackUnassigned.get(i);
 
4764                                 if (set.contains(str)) {