X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index d46b0a2..4dcd0f8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -1,7453 +1,4784 @@ -/******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM Corporation - initial API and implementation - ******************************************************************************/ +/*********************************************************************************************************************************** + * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the + * terms of the Common Public License v1.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: www.phpeclipse.de + **********************************************************************************************************************************/ package net.sourceforge.phpdt.internal.compiler.parser; -import net.sourceforge.phpdt.core.compiler.*; -import net.sourceforge.phpdt.core.compiler.InvalidInputException; -import net.sourceforge.phpdt.internal.compiler.*; -import net.sourceforge.phpdt.internal.compiler.env.*; -import net.sourceforge.phpdt.internal.compiler.impl.*; -import net.sourceforge.phpdt.internal.compiler.ast.*; -import net.sourceforge.phpdt.internal.compiler.lookup.*; -import net.sourceforge.phpdt.internal.compiler.problem.*; -import net.sourceforge.phpdt.internal.compiler.util.*; - -import java.io.*; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; -public class Parser implements BindingIds, ParserBasicInformation, ITerminalSymbols, CompilerModifiers, OperatorIds, TypeIds { - protected ProblemReporter problemReporter; - public int firstToken ; // handle for multiple parsing goals - public int lastAct ; //handle for multiple parsing goals - protected ReferenceContext referenceContext; - public int currentToken; - private int synchronizedBlockSourceStart; - - //error recovery management - protected int lastCheckPoint; - protected RecoveredElement currentElement; - public static boolean VERBOSE_RECOVERY = false; - protected boolean restartRecovery; - protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters) - protected boolean hasReportedError; - protected int recoveredStaticInitializerStart; - protected int lastIgnoredToken, nextIgnoredToken; - protected int lastErrorEndPosition; - - // 1.4 feature - protected boolean assertMode = false; - - //internal data for the automat +import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; +import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.ASTNode; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Block; +import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement; +import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement; +import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Expression; +import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.FieldReference; +import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ImportReference; +import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds; +import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpdt.internal.compiler.ast.Statement; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ; +import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.TypeReference; +import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions; +import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; +import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; +import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; +import net.sourceforge.phpdt.internal.compiler.util.Util; +import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; +import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; + +public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicInformation { protected final static int StackIncrement = 255; + protected int stateStackTop; - protected int[] stack = new int[StackIncrement]; - //scanner token + + // protected int[] stack = new int[StackIncrement]; + + public int firstToken; // handle for multiple parsing goals + + public int lastAct; // handle for multiple parsing goals + + // protected RecoveredElement currentElement; + + public static boolean VERBOSE_RECOVERY = false; + + protected boolean diet = false; // tells the scanner to jump over some + + /** + * the PHP token scanner + */ public Scanner scanner; - //ast stack - final static int AstStackIncrement = 100; - protected int astPtr; - protected AstNode[] astStack = new AstNode[AstStackIncrement]; - protected int astLengthPtr; - protected int[] astLengthStack; - public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/ - AstNode [] noAstNodes = new AstNode[AstStackIncrement]; - //expression stack - final static int ExpressionStackIncrement = 100; - protected int expressionPtr; - protected Expression[] expressionStack = new Expression[ExpressionStackIncrement]; - protected int expressionLengthPtr; - protected int[] expressionLengthStack; - Expression [] noExpressions = new Expression[ExpressionStackIncrement]; - //identifiers stacks - protected int identifierPtr; - protected char[][] identifierStack; - protected int identifierLengthPtr; - protected int[] identifierLengthStack; - protected long[] identifierPositionStack; - //positions , dimensions , .... (what ever is int) ..... stack - protected int intPtr; - protected int[] intStack; - protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one) - protected int endStatementPosition; - protected int lParenPos,rParenPos; //accurate only when used ! - //modifiers dimensions nestedType etc....... - protected boolean optimizeStringLiterals =true; + + int token; + protected int modifiers; + protected int modifiersSourceStart; - protected int nestedType, dimensions; - protected int[] nestedMethod; //the ptr is nestedType - protected int[] realBlockStack; - protected int realBlockPtr; - protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies - protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...] - protected int[] variablesCounter; - //===DATA===DATA===DATA===DATA===DATA===DATA===// - public final static byte rhs[] = {0, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,1,1,1,1,3,4,0,1,2,1,1,1,1, - 1,1,1,1,1,5,1,2,1,2,2,2,1,1,2, - 2,2,4,1,1,1,1,2,1,1,1,1,1,1,1, - 1,1,1,1,2,3,3,2,2,1,3,1,3,1,2, - 1,1,1,3,0,3,1,1,1,1,1,1,1,4,1, - 3,3,7,0,0,0,0,0,2,1,1,1,2,2,4, - 4,5,4,4,2,1,2,3,3,1,3,3,1,3,1, - 4,0,2,1,2,2,4,1,1,2,5,5,7,7,7, - 7,2,2,3,2,2,3,1,2,1,2,1,1,2,2, - 1,1,1,1,1,3,3,4,1,3,4,0,1,2,1, - 1,1,1,2,3,4,0,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,3,3,2,1,1,1,1,1,1,1,5,7,7,6, - 2,3,3,4,1,2,2,1,2,3,2,5,5,7,9, - 9,1,1,1,1,3,3,5,2,3,2,3,3,3,5, - 1,3,4,1,2,5,2,1,1,1,1,1,1,3,1, - 1,3,3,3,3,3,1,1,5,6,8,7,2,0,2, - 0,1,3,4,4,1,2,3,2,1,1,2,2,3,3, - 4,6,6,4,4,1,1,1,1,2,2,0,1,1,3, - 3,1,3,3,1,3,3,1,5,5,4,1,3,3,3, - 1,3,3,1,3,3,3,1,3,3,3,3,3,1,3, - 3,1,3,1,3,1,3,1,3,1,3,1,5,1,1, - 3,3,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,0,1,0,1,0,1,0,1,0,1, - 0,1,0,2,0,1,0,1,0,1,0,1,0,1,0, - 1,0,1,0,2,0,0,1,0,1,0,1,0,1,0, - 1 - }; - - - public static char asb[] = null; - public static char asr[] = null; - public static char symbol_index[] = null; - private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$ - - public final static String name[] = { null, - "++",//$NON-NLS-1$ - "--",//$NON-NLS-1$ - "==",//$NON-NLS-1$ - "<=",//$NON-NLS-1$ - ">=",//$NON-NLS-1$ - "!=",//$NON-NLS-1$ - "<<",//$NON-NLS-1$ - ">>",//$NON-NLS-1$ - ">>>",//$NON-NLS-1$ - "+=",//$NON-NLS-1$ - "-=",//$NON-NLS-1$ - "*=",//$NON-NLS-1$ - "/=",//$NON-NLS-1$ - "&=",//$NON-NLS-1$ - "|=",//$NON-NLS-1$ - "^=",//$NON-NLS-1$ - "%=",//$NON-NLS-1$ - "<<=",//$NON-NLS-1$ - ">>=",//$NON-NLS-1$ - ">>>=",//$NON-NLS-1$ - "||",//$NON-NLS-1$ - "&&",//$NON-NLS-1$ - "+",//$NON-NLS-1$ - "-",//$NON-NLS-1$ - "!",//$NON-NLS-1$ - "%",//$NON-NLS-1$ - "^",//$NON-NLS-1$ - "&",//$NON-NLS-1$ - "*",//$NON-NLS-1$ - "|",//$NON-NLS-1$ - "~",//$NON-NLS-1$ - "/",//$NON-NLS-1$ - ">",//$NON-NLS-1$ - "<",//$NON-NLS-1$ - "(",//$NON-NLS-1$ - ")",//$NON-NLS-1$ - "{",//$NON-NLS-1$ - "}",//$NON-NLS-1$ - "[",//$NON-NLS-1$ - "]",//$NON-NLS-1$ - ";",//$NON-NLS-1$ - "?",//$NON-NLS-1$ - ":",//$NON-NLS-1$ - ",",//$NON-NLS-1$ - ".",//$NON-NLS-1$ - "=",//$NON-NLS-1$ - "",//$NON-NLS-1$ - "$empty",//$NON-NLS-1$ - "Identifier",//$NON-NLS-1$ - "abstract",//$NON-NLS-1$ - "assert",//$NON-NLS-1$ - "boolean",//$NON-NLS-1$ - "break",//$NON-NLS-1$ - "byte",//$NON-NLS-1$ - "case",//$NON-NLS-1$ - "catch",//$NON-NLS-1$ - "char",//$NON-NLS-1$ - "class",//$NON-NLS-1$ - "continue",//$NON-NLS-1$ - "default",//$NON-NLS-1$ - "do",//$NON-NLS-1$ - "double",//$NON-NLS-1$ - "else",//$NON-NLS-1$ - "extends",//$NON-NLS-1$ - "false",//$NON-NLS-1$ - "final",//$NON-NLS-1$ - "finally",//$NON-NLS-1$ - "float",//$NON-NLS-1$ - "for",//$NON-NLS-1$ - "if",//$NON-NLS-1$ - "implements",//$NON-NLS-1$ - "import",//$NON-NLS-1$ - "instanceof",//$NON-NLS-1$ - "int",//$NON-NLS-1$ - "interface",//$NON-NLS-1$ - "long",//$NON-NLS-1$ - "native",//$NON-NLS-1$ - "new",//$NON-NLS-1$ - "null",//$NON-NLS-1$ - "package",//$NON-NLS-1$ - "private",//$NON-NLS-1$ - "protected",//$NON-NLS-1$ - "public",//$NON-NLS-1$ - "return",//$NON-NLS-1$ - "short",//$NON-NLS-1$ - "static",//$NON-NLS-1$ - "strictfp",//$NON-NLS-1$ - "super",//$NON-NLS-1$ - "switch",//$NON-NLS-1$ - "synchronized",//$NON-NLS-1$ - "this",//$NON-NLS-1$ - "throw",//$NON-NLS-1$ - "throws",//$NON-NLS-1$ - "transient",//$NON-NLS-1$ - "true",//$NON-NLS-1$ - "try",//$NON-NLS-1$ - "void",//$NON-NLS-1$ - "volatile",//$NON-NLS-1$ - "while",//$NON-NLS-1$ - "IntegerLiteral",//$NON-NLS-1$ - "LongLiteral",//$NON-NLS-1$ - "FloatingPointLiteral",//$NON-NLS-1$ - "DoubleLiteral",//$NON-NLS-1$ - "CharacterLiteral",//$NON-NLS-1$ - "StringLiteral",//$NON-NLS-1$ - UNEXPECTED_EOF, - "Invalid Character",//$NON-NLS-1$ - "Goal",//$NON-NLS-1$ - "MethodBody",//$NON-NLS-1$ - "ConstructorBody",//$NON-NLS-1$ - "StaticInitializer",//$NON-NLS-1$ - "Initializer",//$NON-NLS-1$ - "Headers",//$NON-NLS-1$ - "BlockStatements",//$NON-NLS-1$ - "MethodPushModifiersHeader",//$NON-NLS-1$ - "CatchHeader",//$NON-NLS-1$ - "FieldDeclaration",//$NON-NLS-1$ - "ImportDeclaration",//$NON-NLS-1$ - "PackageDeclaration",//$NON-NLS-1$ - "TypeDeclaration",//$NON-NLS-1$ - "GenericMethodDeclaration",//$NON-NLS-1$ - "ClassBodyDeclaration",//$NON-NLS-1$ - "Expression",//$NON-NLS-1$ - "Type",//$NON-NLS-1$ - "PrimitiveType",//$NON-NLS-1$ - "ReferenceType",//$NON-NLS-1$ - "ClassOrInterfaceType",//$NON-NLS-1$ - "ArrayType",//$NON-NLS-1$ - "Name",//$NON-NLS-1$ - "Dims",//$NON-NLS-1$ - "ClassType",//$NON-NLS-1$ - "SimpleName",//$NON-NLS-1$ - "Header",//$NON-NLS-1$ - "ClassHeader",//$NON-NLS-1$ - "InterfaceHeader",//$NON-NLS-1$ - "MethodHeader",//$NON-NLS-1$ - "ConstructorHeader",//$NON-NLS-1$ - "FormalParameter",//$NON-NLS-1$ - "ImportDeclarations",//$NON-NLS-1$ - "TypeDeclarations",//$NON-NLS-1$ - "PackageDeclarationName",//$NON-NLS-1$ - "SingleTypeImportDeclarationName",//$NON-NLS-1$ - "TypeImportOnDemandDeclarationName",//$NON-NLS-1$ - "Modifiers",//$NON-NLS-1$ - "Modifier",//$NON-NLS-1$ - "ClassBody",//$NON-NLS-1$ - "ClassHeaderName",//$NON-NLS-1$ - "InterfaceTypeList",//$NON-NLS-1$ - "InterfaceType",//$NON-NLS-1$ - "ClassBodyDeclarations",//$NON-NLS-1$ - "Block",//$NON-NLS-1$ - "VariableDeclarators",//$NON-NLS-1$ - "VariableDeclarator",//$NON-NLS-1$ - "VariableDeclaratorId",//$NON-NLS-1$ - "VariableInitializer",//$NON-NLS-1$ - "ArrayInitializer",//$NON-NLS-1$ - "MethodHeaderName",//$NON-NLS-1$ - "MethodHeaderParameters",//$NON-NLS-1$ - "MethodPushModifiersHeaderName",//$NON-NLS-1$ - "ClassTypeList",//$NON-NLS-1$ - "ConstructorHeaderName",//$NON-NLS-1$ - "FormalParameterList",//$NON-NLS-1$ - "ClassTypeElt",//$NON-NLS-1$ - "StaticOnly",//$NON-NLS-1$ - "ExplicitConstructorInvocation",//$NON-NLS-1$ - "Primary",//$NON-NLS-1$ - "InterfaceBody",//$NON-NLS-1$ - "InterfaceHeaderName",//$NON-NLS-1$ - "InterfaceMemberDeclarations",//$NON-NLS-1$ - "InterfaceMemberDeclaration",//$NON-NLS-1$ - "VariableInitializers",//$NON-NLS-1$ - "BlockStatement",//$NON-NLS-1$ - "Statement",//$NON-NLS-1$ - "LocalVariableDeclaration",//$NON-NLS-1$ - "StatementWithoutTrailingSubstatement",//$NON-NLS-1$ - "StatementNoShortIf",//$NON-NLS-1$ - "StatementExpression",//$NON-NLS-1$ - "PostIncrementExpression",//$NON-NLS-1$ - "PostDecrementExpression",//$NON-NLS-1$ - "MethodInvocation",//$NON-NLS-1$ - "ClassInstanceCreationExpression",//$NON-NLS-1$ - "SwitchBlock",//$NON-NLS-1$ - "SwitchBlockStatements",//$NON-NLS-1$ - "SwitchLabels",//$NON-NLS-1$ - "SwitchBlockStatement",//$NON-NLS-1$ - "SwitchLabel",//$NON-NLS-1$ - "ConstantExpression",//$NON-NLS-1$ - "StatementExpressionList",//$NON-NLS-1$ - "OnlySynchronized",//$NON-NLS-1$ - "Catches",//$NON-NLS-1$ - "Finally",//$NON-NLS-1$ - "CatchClause",//$NON-NLS-1$ - "PushLPAREN",//$NON-NLS-1$ - "PushRPAREN",//$NON-NLS-1$ - "PrimaryNoNewArray",//$NON-NLS-1$ - "FieldAccess",//$NON-NLS-1$ - "ArrayAccess",//$NON-NLS-1$ - "ClassInstanceCreationExpressionName",//$NON-NLS-1$ - "ArgumentList",//$NON-NLS-1$ - "DimWithOrWithOutExprs",//$NON-NLS-1$ - "DimWithOrWithOutExpr",//$NON-NLS-1$ - "DimsLoop",//$NON-NLS-1$ - "OneDimLoop",//$NON-NLS-1$ - "PostfixExpression",//$NON-NLS-1$ - "UnaryExpression",//$NON-NLS-1$ - "UnaryExpressionNotPlusMinus",//$NON-NLS-1$ - "MultiplicativeExpression",//$NON-NLS-1$ - "AdditiveExpression",//$NON-NLS-1$ - "ShiftExpression",//$NON-NLS-1$ - "RelationalExpression",//$NON-NLS-1$ - "EqualityExpression",//$NON-NLS-1$ - "AndExpression",//$NON-NLS-1$ - "ExclusiveOrExpression",//$NON-NLS-1$ - "InclusiveOrExpression",//$NON-NLS-1$ - "ConditionalAndExpression",//$NON-NLS-1$ - "ConditionalOrExpression",//$NON-NLS-1$ - "ConditionalExpression",//$NON-NLS-1$ - "AssignmentExpression",//$NON-NLS-1$ - "LeftHandSide",//$NON-NLS-1$ - "AssignmentOperator"//$NON-NLS-1$ - }; - - public static short check_table[] = null; - public static char lhs[] = null; - public static char action[] = lhs; - private final static String FILEPREFIX = "parser"; //$NON-NLS-1$ - - static { - try{ - initTables(); - } catch(java.io.IOException ex){ - throw new ExceptionInInitializerError(ex.getMessage()); - } + + protected Parser(ProblemReporter problemReporter) { + this.problemReporter = problemReporter; + this.options = problemReporter.options; + this.token = TokenNameEOF; + this.initializeScanner(); } - public static final int RoundBracket = 0; - public static final int SquareBracket = 1; - public static final int CurlyBracket = 2; - public static final int BracketKinds = 3; + public void setFileToParse(IFile fileToParse) { + this.token = TokenNameEOF; + this.initializeScanner(); + } -public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) { - - this.problemReporter = problemReporter; - this.optimizeStringLiterals = optimizeStringLiterals; - this.assertMode = assertMode; - this.initializeScanner(); - astLengthStack = new int[50]; - expressionLengthStack = new int[30]; - intStack = new int[50]; - identifierStack = new char[30][]; - identifierLengthStack = new int[30]; - nestedMethod = new int[30]; - realBlockStack = new int[30]; - identifierPositionStack = new long[30]; - variablesCounter = new int[30]; -} -/** - * - * INTERNAL USE-ONLY - */ -protected void adjustInterfaceModifiers() { - intStack[intPtr - 1] |= AccInterface; -} -public final void arrayInitializer(int length) { - //length is the size of the array Initializer - //expressionPtr points on the last elt of the arrayInitializer - //i.e. it has not been decremented yet. - - ArrayInitializer ai = new ArrayInitializer(); - if (length != 0) { - expressionPtr -= length; - System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length); + /** + * ClassDeclaration Constructor. + * + * @param s + * @param sess + * Description of Parameter + * @see + */ + public Parser(IFile fileToParse) { + // if (keywordMap == null) { + // keywordMap = new HashMap(); + // for (int i = 0; i < PHP_KEYWORS.length; i++) { + // keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i])); + // } + // } + // this.currentPHPString = 0; + // PHPParserSuperclass.fileToParse = fileToParse; + // this.phpList = null; + this.includesList = null; + // this.str = ""; + this.token = TokenNameEOF; + // this.chIndx = 0; + // this.rowCount = 1; + // this.columnCount = 0; + // this.phpEnd = false; + // getNextToken(); + this.initializeScanner(); + } + + public void initializeScanner() { + this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options + .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false, + this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */, true/* isTaskCaseSensitive */); + } + + /** + * Create marker for the parse error + */ + // private void setMarker(String message, int charStart, int charEnd, int + // errorLevel) { + // setMarker(fileToParse, message, charStart, charEnd, errorLevel); + // } + /** + * This method will throw the SyntaxError. It will add the good lines and + * columns to the Error + * + * @param error + * the error message + * @throws SyntaxError + * the error raised + */ + private void throwSyntaxError(String error) { + int problemStartPosition = scanner.getCurrentTokenStartPosition(); + int problemEndPosition = scanner.getCurrentTokenEndPosition() + 1; + if (scanner.source.length <= problemEndPosition && problemEndPosition > 0) { + problemEndPosition = scanner.source.length - 1; + if (problemStartPosition > 0 && problemStartPosition >= problemEndPosition && problemEndPosition > 0) { + problemStartPosition = problemEndPosition - 1; + } + } + throwSyntaxError(error, problemStartPosition, problemEndPosition); } - pushOnExpressionStack(ai); - //positionning - ai.sourceEnd = endStatementPosition; - int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart; - try { - //does not work with comments(that contain '{') nor '{' describes as a unicode.... - while (scanner.source[--searchPosition] != '{') { - } - } catch (IndexOutOfBoundsException ex) { - //should never occur (except for strange cases like whose describe above) - searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1; + + /** + * This method will throw the SyntaxError. It will add the good lines and + * columns to the Error + * + * @param error + * the error message + * @throws SyntaxError + * the error raised + */ + // private void throwSyntaxError(String error, int startRow) { + // throw new SyntaxError(startRow, 0, " ", error); + // } + private void throwSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + if (referenceContext != null) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } + throw new SyntaxError(1, 0, " ", error); } - ai.sourceStart = searchPosition; -} -protected static int asi(int state) { - - return asb[original_state(state)]; -} -protected void blockReal() { - // See consumeLocalVariableDeclarationStatement in case of change: duplicated code - // increment the amount of declared variables for this block - realBlockStack[realBlockPtr]++; -} -private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort) throws java.io.IOException { - - //transform the String tokens into chars before dumping then into file - - int i = 0; - //read upto the tag - while (!tokens[i++].equals(tag)) {} - //read upto the } - char[] chars = new char[tokens.length]; //can't be bigger - int ic = 0; - String token; - while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$ - int c = Integer.parseInt(token); - if (isShort) - c += 32768; - chars[ic++] = (char) c; + + private void reportSyntaxError(String error) { + int problemStartPosition = scanner.getCurrentTokenStartPosition(); + int problemEndPosition = scanner.getCurrentTokenEndPosition(); + reportSyntaxError(error, problemStartPosition, problemEndPosition + 1); } - //resize - System.arraycopy(chars, 0, chars = new char[ic], 0, ic); + private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + if (referenceContext != null) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } + } - buildFileForTable(filename, chars); -} -private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException { + // private void reportSyntaxWarning(String error, int problemStartPosition, + // int problemEndPosition) { + // if (referenceContext != null) { + // problemReporter.phpParsingWarning(new String[] { error }, + // problemStartPosition, problemEndPosition, referenceContext, + // compilationUnit.compilationResult); + // } + // } - byte[] bytes = new byte[chars.length * 2]; - for (int i = 0; i < chars.length; i++) { - bytes[2 * i] = (byte) (chars[i] >>> 8); - bytes[2 * i + 1] = (byte) (chars[i] & 0xFF); + /** + * gets the next token from input + */ + private void getNextToken() { + try { + token = scanner.getNextToken(); + if (Scanner.DEBUG) { + int currentEndPosition = scanner.getCurrentTokenEndPosition(); + int currentStartPosition = scanner.getCurrentTokenStartPosition(); + System.out.print(currentStartPosition + "," + currentEndPosition + ": "); + System.out.println(scanner.toStringAction(token)); + } + } catch (InvalidInputException e) { + token = TokenNameERROR; + String detailedMessage = e.getMessage(); + + if (detailedMessage == Scanner.UNTERMINATED_STRING) { + throwSyntaxError("Unterminated string."); + } else if (detailedMessage == Scanner.UNTERMINATED_COMMENT) { + throwSyntaxError("Unterminated commment."); + } + } + return; } - java.io.FileOutputStream stream = new java.io.FileOutputStream(filename); - stream.write(bytes); - stream.close(); - System.out.println(filename + " creation complete"); //$NON-NLS-1$ -} -public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException { - - //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES + public void init(String s) { + // this.str = s; + this.token = TokenNameEOF; + this.includesList = new ArrayList(); + // this.chIndx = 0; + // this.rowCount = 1; + // this.columnCount = 0; + // this.phpEnd = false; + // this.phpMode = false; + /* scanner initialization */ + scanner.setSource(s.toCharArray()); + scanner.setPHPMode(false); + astPtr = 0; + } + + protected void initialize(boolean phpMode) { + initialize(phpMode, null); + } + + protected void initialize(boolean phpMode, IdentifierIndexManager indexManager) { + compilationUnit = null; + referenceContext = null; + this.includesList = new ArrayList(); + // this.indexManager = indexManager; + // this.str = ""; + this.token = TokenNameEOF; + // this.chIndx = 0; + // this.rowCount = 1; + // this.columnCount = 0; + // this.phpEnd = false; + // this.phpMode = phpMode; + scanner.setPHPMode(phpMode); + astPtr = 0; + } + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' + */ + public void parse(String s) { + parse(s, null); + } - //build from the lpg javadcl.java files that represents the parser tables - //lhs check_table asb asr symbol_index + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' + */ + public void parse(String s, HashMap variables) { + fMethodVariables = variables; + fStackUnassigned = new ArrayList(); + init(s); + parse(); + } - //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")] + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' + */ + protected void parse() { + if (scanner.compilationUnit != null) { + IResource resource = scanner.compilationUnit.getResource(); + if (resource != null && resource instanceof IFile) { + // set the package name + consumePackageDeclarationName((IFile) resource); + } + } + getNextToken(); + do { + try { + if (token != TokenNameEOF && token != TokenNameERROR) { + statementList(); + } + if (token != TokenNameEOF) { + if (token == TokenNameERROR) { + throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")"); + } + if (token == TokenNameRPAREN) { + throwSyntaxError("Too many closing ')'; end-of-file not reached."); + } + if (token == TokenNameRBRACE) { + throwSyntaxError("Too many closing '}'; end-of-file not reached."); + } + if (token == TokenNameRBRACKET) { + throwSyntaxError("Too many closing ']'; end-of-file not reached."); + } + if (token == TokenNameLPAREN) { + throwSyntaxError("Read character '('; end-of-file not reached."); + } + if (token == TokenNameLBRACE) { + throwSyntaxError("Read character '{'; end-of-file not reached."); + } + if (token == TokenNameLBRACKET) { + throwSyntaxError("Read character '['; end-of-file not reached."); + } + throwSyntaxError("End-of-file not reached."); + } + break; + } catch (SyntaxError syntaxError) { + // syntaxError.printStackTrace(); + break; + } + } while (true); - char[] contents = new char[] {}; - try { - contents = Util.getFileCharContent(new File(dataFilename), null); - } catch (IOException ex) { - System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$ - return; + endParse(0); } - java.util.StringTokenizer st = - new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$ - String[] tokens = new String[st.countTokens()]; - int i = 0; - while (st.hasMoreTokens()) { - tokens[i++] = st.nextToken(); + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' + */ + public void parseFunction(String s, HashMap variables) { + init(s); + scanner.phpMode = true; + parseFunction(variables); } - final String prefix = FILEPREFIX; - i = 0; - buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$ - buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$ - buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$ - buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$ - buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$ - System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$ -} -/* - * Build initial recovery state. - * Recovery state is inferred from the current state of the parser (reduced node stack). - */ -public RecoveredElement buildInitialRecoveryState(){ - - /* initialize recovery by retrieving available reduced nodes - * also rebuild bracket balance + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' */ - lastCheckPoint = 0; - - RecoveredElement element = null; - if (referenceContext instanceof CompilationUnitDeclaration){ - element = new RecoveredUnit(compilationUnit, 0, this); - - /* ignore current stack state, since restarting from the beginnning - since could not trust simple brace count */ - if (true){ // experimenting restart recovery from scratch - compilationUnit.currentPackage = null; - compilationUnit.imports = null; - compilationUnit.types = null; - currentToken = 0; - listLength = 0; - return element; - } - if (compilationUnit.currentPackage != null){ - lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd+1; - } - if (compilationUnit.imports != null){ - lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length -1].declarationSourceEnd+1; - } - } else { - if (referenceContext instanceof AbstractMethodDeclaration){ - element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this); - lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart; - } else { - /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */ - if (referenceContext instanceof TypeDeclaration){ - TypeDeclaration type = (TypeDeclaration) referenceContext; - for (int i = 0; i < type.fields.length; i++){ - FieldDeclaration field = type.fields[i]; - if (!field.isField() - && field.declarationSourceStart <= scanner.initialPosition - && scanner.initialPosition <= field.declarationSourceEnd - && scanner.eofPosition <= field.declarationSourceEnd+1){ - element = new RecoveredInitializer((Initializer) field, null, 1, this); - lastCheckPoint = field.declarationSourceStart; - break; - } + protected void parseFunction(HashMap variables) { + getNextToken(); + boolean hasModifiers = member_modifiers(); + if (token == TokenNamefunction) { + if (!hasModifiers) { + checkAndSetModifiers(AccPublic); + } + this.fMethodVariables = variables; + + MethodDeclaration methodDecl = new MethodDeclaration(null); + methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.modifiers = this.modifiers; + methodDecl.type = MethodDeclaration.METHOD_DEFINITION; + try { + getNextToken(); + functionDefinition(methodDecl); + } catch (SyntaxError sytaxErr1) { + return; + } finally { + int sourceEnd = methodDecl.sourceEnd; + if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; } - } + methodDecl.sourceEnd = sourceEnd; + methodDecl.declarationSourceEnd = sourceEnd; + } } } - if (element == null) return element; - - for(int i = 0; i <= astPtr; i++){ - AstNode node = astStack[i]; - if (node instanceof AbstractMethodDeclaration){ - AbstractMethodDeclaration method = (AbstractMethodDeclaration) node; - if (method.declarationSourceEnd == 0){ - element = element.add(method, 0); - lastCheckPoint = method.bodyStart; - } else { - element = element.add(method, 0); - lastCheckPoint = method.declarationSourceEnd + 1; - } - continue; + protected CompilationUnitDeclaration endParse(int act) { + + this.lastAct = act; + + // if (currentElement != null) { + // currentElement.topElement().updateParseTree(); + // if (VERBOSE_RECOVERY) { + // System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$ + // System.out.println("--------------------------"); //$NON-NLS-1$ + // System.out.println(compilationUnit); + // System.out.println("----------------------------------"); //$NON-NLS-1$ + // } + // } else { + if (diet & VERBOSE_RECOVERY) { + System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$ + System.out.println("--------------------------"); //$NON-NLS-1$ + System.out.println(compilationUnit); + System.out.println("----------------------------------"); //$NON-NLS-1$ } - if (node instanceof Initializer){ - Initializer initializer = (Initializer) node; - if (initializer.declarationSourceEnd == 0){ - element = element.add(initializer, 1); - lastCheckPoint = initializer.bodyStart; - } else { - element = element.add(initializer, 0); - lastCheckPoint = initializer.declarationSourceEnd + 1; - } - continue; - } - if (node instanceof FieldDeclaration){ - FieldDeclaration field = (FieldDeclaration) node; - if (field.declarationSourceEnd == 0){ - element = element.add(field, 0); - if (field.initialization == null){ - lastCheckPoint = field.sourceEnd + 1; - } else { - lastCheckPoint = field.initialization.sourceEnd + 1; - } - } else { - element = element.add(field, 0); - lastCheckPoint = field.declarationSourceEnd + 1; - } - continue; + // } + if (scanner.recordLineSeparator) { + compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); } - if (node instanceof TypeDeclaration){ - TypeDeclaration type = (TypeDeclaration) node; - if (type.declarationSourceEnd == 0){ - element = element.add(type, 0); - lastCheckPoint = type.bodyStart; - } else { - element = element.add(type, 0); - lastCheckPoint = type.declarationSourceEnd + 1; + if (scanner.taskTags != null) { + for (int i = 0; i < scanner.foundTaskCount; i++) { + problemReporter().task(new String(scanner.foundTaskTags[i]), new String(scanner.foundTaskMessages[i]), + scanner.foundTaskPriorities[i] == null ? null : new String(scanner.foundTaskPriorities[i]), + scanner.foundTaskPositions[i][0], scanner.foundTaskPositions[i][1]); } - continue; } - if (node instanceof ImportReference){ - ImportReference importRef = (ImportReference) node; - element = element.add(importRef, 0); - lastCheckPoint = importRef.declarationSourceEnd + 1; + compilationUnit.imports = new ImportReference[includesList.size()]; + for (int i = 0; i < includesList.size(); i++) { + compilationUnit.imports[i] = (ImportReference) includesList.get(i); } + return compilationUnit; } - return element; -} -protected static short check(int i) { - return check_table[i - (NUM_RULES + 1)]; -} -/* - * Reconsider the entire source looking for inconsistencies in {} () [] - */ -public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) { - - scanner.wasAcr = false; - boolean anomaliesDetected = false; - try { - char[] source = scanner.source; - int[] leftCount = {0, 0, 0}; - int[] rightCount = {0, 0, 0}; - int[] depths = {0, 0, 0}; - int[][] leftPositions = new int[][] {new int[10], new int[10], new int[10]}; - int[][] leftDepths = new int[][] {new int[10], new int[10], new int[10]}; - int[][] rightPositions = new int[][] {new int[10], new int[10], new int[10]}; - int[][] rightDepths = new int[][] {new int[10], new int[10], new int[10]}; - scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char) - while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments - try { - // ---------Consume white space and handles startPosition--------- - boolean isWhiteSpace; - do { - scanner.startPosition = scanner.currentPosition; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace(); - } else { - if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { - if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { - // only record line positions we have not recorded yet - scanner.pushLineSeparator(); - } - } - isWhiteSpace = Character.isWhitespace(scanner.currentCharacter); - } - } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); - - // -------consume token until } is found--------- - switch (scanner.currentCharacter) { - case '{' : - { - int index = leftCount[CurlyBracket] ++; - if (index == leftPositions[CurlyBracket].length) { - System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index); - } - leftPositions[CurlyBracket][index] = scanner.startPosition; - leftDepths[CurlyBracket][index] = depths[CurlyBracket] ++; - } - break; - case '}' : - { - int index = rightCount[CurlyBracket] ++; - if (index == rightPositions[CurlyBracket].length) { - System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index); - } - rightPositions[CurlyBracket][index] = scanner.startPosition; - rightDepths[CurlyBracket][index] = --depths[CurlyBracket]; - } - break; - case '(' : - { - int index = leftCount[RoundBracket] ++; - if (index == leftPositions[RoundBracket].length) { - System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index); - } - leftPositions[RoundBracket][index] = scanner.startPosition; - leftDepths[RoundBracket][index] = depths[RoundBracket] ++; - } - break; - case ')' : - { - int index = rightCount[RoundBracket] ++; - if (index == rightPositions[RoundBracket].length) { - System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index); - } - rightPositions[RoundBracket][index] = scanner.startPosition; - rightDepths[RoundBracket][index] = --depths[RoundBracket]; - } - break; - case '[' : - { - int index = leftCount[SquareBracket] ++; - if (index == leftPositions[SquareBracket].length) { - System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index); - System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index); - } - leftPositions[SquareBracket][index] = scanner.startPosition; - leftDepths[SquareBracket][index] = depths[SquareBracket] ++; - } - break; - case ']' : - { - int index = rightCount[SquareBracket] ++; - if (index == rightPositions[SquareBracket].length) { - System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index); - System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index); - } - rightPositions[SquareBracket][index] = scanner.startPosition; - rightDepths[SquareBracket][index] = --depths[SquareBracket]; - } - break; - case '\'' : - { - if (scanner.getNextChar('\\')) { - scanner.scanEscapeCharacter(); - } else { // consume next character - scanner.unicodeAsBackSlash = false; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - scanner.getNextUnicodeChar(); - } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - } - } - scanner.getNextChar('\''); - break; - } - case '"' : // consume next character - scanner.unicodeAsBackSlash = false; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - scanner.getNextUnicodeChar(); - } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - } - while (scanner.currentCharacter != '"') { - if (scanner.currentCharacter == '\r') { - if (source[scanner.currentPosition] == '\n') - scanner.currentPosition++; - break; // the string cannot go further that the line - } - if (scanner.currentCharacter == '\n') { - break; // the string cannot go further that the line - } - if (scanner.currentCharacter == '\\') { - scanner.scanEscapeCharacter(); - } - // consume next character - scanner.unicodeAsBackSlash = false; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - scanner.getNextUnicodeChar(); - } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - } - } - break; - case '/' : - { - int test; - if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment - //get the next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value - scanner.currentCharacter = 'A'; - } //something different from \n and \r - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') { - //get the next char - scanner.startPosition = scanner.currentPosition; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value - scanner.currentCharacter = 'A'; - } //something different from \n and \r - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - } - if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) { - if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { - // only record line positions we have not recorded yet - scanner.pushLineSeparator(); - } - } - break; - } - if (test > 0) { //traditional and annotation comment - boolean star = false; - // consume next character - scanner.unicodeAsBackSlash = false; - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - scanner.getNextUnicodeChar(); - } else { - if (scanner.withoutUnicodePtr != 0) { - scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter; - } - } - if (scanner.currentCharacter == '*') { - star = true; - } - //get the next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value - scanner.currentCharacter = 'A'; - } //something different from * and / - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - //loop until end of comment */ - while ((scanner.currentCharacter != '/') || (!star)) { - star = scanner.currentCharacter == '*'; - //get next char - if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) { - //-------------unicode traitement ------------ - int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - scanner.currentPosition++; - while (source[scanner.currentPosition] == 'u') { - scanner.currentPosition++; - } - if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value - scanner.currentCharacter = 'A'; - } //something different from * and / - else { - scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); - } - } - } - break; - } - break; - } - default : - if (Character.isJavaIdentifierStart(scanner.currentCharacter)) { - scanner.scanIdentifierOrKeyword(); - break; + private Block statementList() { + boolean branchStatement = false; + Statement statement; + int blockStart = scanner.getCurrentTokenStartPosition(); + ArrayList blockStatements = new ArrayList(); + do { + try { + statement = statement(); + blockStatements.add(statement); + if (token == TokenNameEOF) { + return null; + } + if (branchStatement && statement != null) { + // reportSyntaxError("Unreachable code", statement.sourceStart, + // statement.sourceEnd); + problemReporter.unreachableCode(new String(scanner.getCurrentIdentifierSource()), statement.sourceStart, + statement.sourceEnd, referenceContext, compilationUnit.compilationResult); + } + if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) + || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) + || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) + || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { + return createBlock(blockStart, blockStatements); + } + branchStatement = checkUnreachableStatements(statement); + } catch (SyntaxError sytaxErr1) { + // if an error occured, + // try to find keywords + // to parse the rest of the string + boolean tokenize = scanner.tokenizeStrings; + if (!tokenize) { + scanner.tokenizeStrings = true; + } + try { + while (token != TokenNameEOF) { + if ((token == TokenNameRBRACE) || (token == TokenNamecase) || (token == TokenNamedefault) || (token == TokenNameelse) + || (token == TokenNameelseif) || (token == TokenNameendif) || (token == TokenNameendfor) + || (token == TokenNameendforeach) || (token == TokenNameendwhile) || (token == TokenNameendswitch) + || (token == TokenNameenddeclare) || (token == TokenNameEOF) || (token == TokenNameERROR)) { + return createBlock(blockStart, blockStatements); } - if (Character.isDigit(scanner.currentCharacter)) { - scanner.scanNumber(false); + if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile + || token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak + || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameglobal + || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction || token == TokenNamedeclare + || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow || token == TokenNamefinal + || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { break; } + // System.out.println(scanner.toStringAction(token)); + getNextToken(); + // System.out.println(scanner.toStringAction(token)); + } + if (token == TokenNameEOF) { + throw sytaxErr1; + } + } finally { + scanner.tokenizeStrings = tokenize; } - //-----------------end switch while try-------------------- - } catch (IndexOutOfBoundsException e) { - break; // read until EOF - } catch (InvalidInputException e) { - return false; // no clue } + } while (true); + } + + /** + * @param statement + * @return + */ + private boolean checkUnreachableStatements(Statement statement) { + if (statement instanceof ReturnStatement || statement instanceof ContinueStatement || statement instanceof BreakStatement) { + return true; + } else if (statement instanceof IfStatement && ((IfStatement) statement).checkUnreachable) { + return true; } - if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + return false; + } + + /** + * @param blockStart + * @param blockStatements + * @return + */ + private Block createBlock(int blockStart, ArrayList blockStatements) { + int blockEnd = scanner.getCurrentTokenEndPosition(); + Block b = Block.EmptyWith(blockStart, blockEnd); + b.statements = new Statement[blockStatements.size()]; + blockStatements.toArray(b.statements); + return b; + } + + private void functionBody(MethodDeclaration methodDecl) { + // '{' [statement-list] '}' + if (token == TokenNameLBRACE) { + getNextToken(); + } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("'{' expected in compound-statement."); } + if (token != TokenNameRBRACE) { + statementList(); + } + if (token == TokenNameRBRACE) { + methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("'}' expected in compound-statement."); + } + } - // check placement anomalies against other kinds of brackets - for (int kind = 0; kind < BracketKinds; kind++) { - for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) { - int start = leftPositions[kind][leftIndex]; // deepest first - // find matching closing bracket - int depth = leftDepths[kind][leftIndex]; - int end = -1; - for (int i = 0; i < rightCount[kind]; i++) { - int pos = rightPositions[kind][i]; - // want matching bracket further in source with same depth - if ((pos > start) && (depth == rightDepths[kind][i])) { - end = pos; - break; - } + private Statement statement() { + Statement statement = null; + Expression expression; + int sourceStart = scanner.getCurrentTokenStartPosition(); + int sourceEnd; + if (token == TokenNameif) { + // T_IF '(' expr ')' statement elseif_list else_single + // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list + // new_else_single T_ENDIF ';' + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'if' keyword."); + } + expression = expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'if' condition."); + } + // create basic IfStatement + IfStatement ifStatement = new IfStatement(expression, null, null, sourceStart, -1); + if (token == TokenNameCOLON) { + getNextToken(); + ifStatementColon(ifStatement); + } else { + ifStatement(ifStatement); + } + return ifStatement; + } else if (token == TokenNameswitch) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'switch' keyword."); + } + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'switch' condition."); + } + switchStatement(); + return statement; + } else if (token == TokenNamefor) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'for' keyword."); + } + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + expressionList(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'for'."); } - if (end < 0) { // did not find a good closing match - problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); - return true; + } + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + expressionList(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'for'."); } - // check if even number of opening/closing other brackets in between this pair of brackets - int balance = 0; - for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) { - for (int i = 0; i < leftCount[otherKind]; i++) { - int pos = leftPositions[otherKind][i]; - if ((pos > start) && (pos < end)) - balance++; - } - for (int i = 0; i < rightCount[otherKind]; i++) { - int pos = rightPositions[otherKind][i]; - if ((pos > start) && (pos < end)) - balance--; - } - if (balance != 0) { - problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly - return true; - } + } + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + expressionList(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'for'."); } } - // too many opening brackets ? - for (int i = rightCount[kind]; i < leftCount[kind]; i++) { - anomaliesDetected = true; - problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, compilationUnit.compilationResult); + forStatement(); + return statement; + } else if (token == TokenNamewhile) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'while' keyword."); + } + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'while' condition."); + } + whileStatement(); + return statement; + } else if (token == TokenNamedo) { + getNextToken(); + if (token == TokenNameLBRACE) { + getNextToken(); + if (token != TokenNameRBRACE) { + statementList(); + } + if (token == TokenNameRBRACE) { + getNextToken(); + } else { + throwSyntaxError("'}' expected after 'do' keyword."); + } + } else { + statement(); + } + if (token == TokenNamewhile) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'while' keyword."); + } + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'while' condition."); + } + } else { + throwSyntaxError("'while' expected after 'do' keyword."); + } + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("';' expected after do-while statement."); + } + getNextToken(); + } + return statement; + } else if (token == TokenNameforeach) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'foreach' keyword."); + } + expr(); + if (token == TokenNameas) { + getNextToken(); + } else { + throwSyntaxError("'as' expected after 'foreach' exxpression."); + } + // variable(); + foreach_variable(); + foreach_optional_arg(); + if (token == TokenNameEQUAL_GREATER) { + getNextToken(); + variable(false, false); + } + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'foreach' expression."); + } + foreachStatement(); + return statement; + } else if (token == TokenNamebreak) { + expression = null; + getNextToken(); + if (token != TokenNameSEMICOLON) { + expression = expr(); + } + if (token == TokenNameSEMICOLON) { + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } else { + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("';' expected after 'break'."); + } + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } + return new BreakStatement(null, sourceStart, sourceEnd); + } else if (token == TokenNamecontinue) { + expression = null; + getNextToken(); + if (token != TokenNameSEMICOLON) { + expression = expr(); + } + if (token == TokenNameSEMICOLON) { + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } else { + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("';' expected after 'continue'."); + } + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } + return new ContinueStatement(null, sourceStart, sourceEnd); + } else if (token == TokenNamereturn) { + expression = null; + getNextToken(); + if (token != TokenNameSEMICOLON) { + expression = expr(); + } + if (token == TokenNameSEMICOLON) { + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } else { + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("';' expected after 'return'."); + } + sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } + return new ReturnStatement(expression, sourceStart, sourceEnd); + } else if (token == TokenNameecho) { + getNextToken(); + expressionList(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("';' expected after 'echo' statement."); + } + getNextToken(); + } + return statement; + } else if (token == TokenNameINLINE_HTML) { + if (scanner.phpExpressionTag) { + // start of block + getNextToken(); + expr(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } + if (token != TokenNameINLINE_HTML) { + throwSyntaxError("Missing '?>' for open PHP expression block (' sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; + } + methodDecl.declarationSourceEnd = sourceEnd; + methodDecl.sourceEnd = sourceEnd; + } + return statement; + } else if (token == TokenNamedeclare) { + // T_DECLARE '(' declare_list ')' declare_statement + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected in 'declare' statement."); + } + getNextToken(); + declare_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in 'declare' statement."); + } + getNextToken(); + declare_statement(); + return statement; + } else if (token == TokenNametry) { + getNextToken(); + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in 'try' statement."); + } + getNextToken(); + statementList(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in 'try' statement."); + } + getNextToken(); + return statement; + } else if (token == TokenNamecatch) { + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected in 'catch' statement."); + } + getNextToken(); + fully_qualified_class_name(); + if (token != TokenNameVariable) { + throwSyntaxError("Variable expected in 'catch' statement."); + } + addVariableSet(); + getNextToken(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in 'catch' statement."); + } + getNextToken(); + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in 'catch' statement."); + } + getNextToken(); + if (token != TokenNameRBRACE) { + statementList(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in 'catch' statement."); + } + } + getNextToken(); + additional_catches(); + return statement; + } else if (token == TokenNamethrow) { + getNextToken(); + expr(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'throw' exxpression."); + } + return statement; + } else if (token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) { + try { + TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + typeDecl.name = new char[] { ' ' }; + // default super class + typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0); + compilationUnit.types.add(typeDecl); + pushOnAstStack(typeDecl); + unticked_class_declaration_statement(typeDecl); + } finally { + // reduce stack: + astPtr--; + astLengthPtr--; + } + return statement; + // } else { + // throwSyntaxError("Unexpected keyword '" + keyword + "'"); + } else if (token == TokenNameLBRACE) { + getNextToken(); + if (token != TokenNameRBRACE) { + statement = statementList(); } - // too many closing brackets ? - for (int i = leftCount[kind]; i < rightCount[kind]; i++) { - anomaliesDetected = true; - problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult); + if (token == TokenNameRBRACE) { + getNextToken(); + return statement; + } else { + throwSyntaxError("'}' expected."); + } + } else { + if (token != TokenNameSEMICOLON) { + expr(); + } + if (token == TokenNameSEMICOLON) { + getNextToken(); + return statement; + } else { + if (token == TokenNameRBRACE) { + reportSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + } else { + if (token != TokenNameINLINE_HTML && token != TokenNameEOF) { + throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")"); + } + getNextToken(); + } } - if (anomaliesDetected) return true; } - - return anomaliesDetected; - } catch (ArrayStoreException e) { // jdk1.2.2 jit bug - return anomaliesDetected; - } catch (NullPointerException e) { // jdk1.2.2 jit bug - return anomaliesDetected; - } -} -public final void checkAndSetModifiers(int flag){ - /*modify the current modifiers buffer. - When the startPosition of the modifiers is 0 - it means that the modifier being parsed is the first - of a list of several modifiers. The startPosition - is zeroed when a copy of modifiers-buffer is push - onto the astStack. */ - - if ((modifiers & flag) != 0){ // duplicate modifier - modifiers |= AccAlternateModifierProblem; - } - modifiers |= flag; - - if (modifiersSourceStart < 0) modifiersSourceStart = scanner.startPosition; -} -public void checkAnnotation() { - - boolean deprecated = false; - boolean checkDeprecated = false; - int lastAnnotationIndex = -1; - - //since jdk1.2 look only in the last java doc comment... - found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){ - //look for @deprecated into the first javadoc comment preceeding the declaration - int commentSourceStart = scanner.commentStarts[lastAnnotationIndex]; - // javadoc only (non javadoc comment have negative end positions.) - if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) { - continue; - } - if (scanner.commentStops[lastAnnotationIndex] < 0) { - break found; - } - checkDeprecated = true; - int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over - char[] comment = scanner.source; - - for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) { - if ((comment[i] == '@') - && (comment[i + 1] == 'd') - && (comment[i + 2] == 'e') - && (comment[i + 3] == 'p') - && (comment[i + 4] == 'r') - && (comment[i + 5] == 'e') - && (comment[i + 6] == 'c') - && (comment[i + 7] == 'a') - && (comment[i + 8] == 't') - && (comment[i + 9] == 'e') - && (comment[i + 10] == 'd')) { - // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk. - int nextPos = i+11; - deprecated = (comment[nextPos] == ' ') || (comment[nextPos] == '\t') || (comment[nextPos] == '\n') || (comment[nextPos] == '\r') || (comment[nextPos] == '*'); - break found; - } - } - break found; - } - if (deprecated) { - checkAndSetModifiers(AccDeprecated); - } - // modify the modifier source start to point at the first comment - if (lastAnnotationIndex >= 0 && checkDeprecated) { - modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex]; - } -} -protected void classInstanceCreation(boolean alwaysQualified) { - // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt - - // ClassBodyopt produces a null item on the astStak if it produces NO class body - // An empty class body produces a 0 on the length stack..... - - AllocationExpression alloc; - int length; - if (((length = astLengthStack[astLengthPtr--]) == 1) - && (astStack[astPtr] == null)) { - //NO ClassBody - astPtr--; - if (alwaysQualified) { - alloc = new QualifiedAllocationExpression(); + // may be null + return statement; + } + + private void declare_statement() { + // statement + // | ':' inner_statement_list T_ENDDECLARE ';' + // ; + if (token == TokenNameCOLON) { + getNextToken(); + // TODO: implement inner_statement_list(); + statementList(); + if (token != TokenNameenddeclare) { + throwSyntaxError("'enddeclare' expected in 'declare' statement."); + } + getNextToken(); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after 'enddeclare' keyword."); + } + getNextToken(); } else { - alloc = new AllocationExpression(); - } - alloc.sourceEnd = endPosition; //the position has been stored explicitly - - if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) { - expressionPtr -= length; - System.arraycopy( - expressionStack, - expressionPtr + 1, - alloc.arguments = new Expression[length], - 0, - length); - } - alloc.type = getTypeReference(0); - //the default constructor with the correct number of argument - //will be created and added by the TC (see createsInternalConstructorWithBinding) - alloc.sourceStart = intStack[intPtr--]; - pushOnExpressionStack(alloc); - } else { - dispatchDeclarationInto(length); - AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr]; - anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition; - anonymousTypeDeclaration.bodyEnd = endStatementPosition; - if (anonymousTypeDeclaration.allocation != null) { - anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition; - } - astPtr--; - astLengthPtr--; - - // mark fields and initializer with local type mark if needed - markFieldsWithLocalType(anonymousTypeDeclaration); + statement(); + } } -} -protected final void concatExpressionLists() { - expressionLengthStack[--expressionLengthPtr]++; -} -private final void concatNodeLists() { - /* - * This is a case where you have two sublists into the astStack that you want - * to merge in one list. There is no action required on the astStack. The only - * thing you need to do is merge the two lengths specified on the astStackLength. - * The top two length are for example: - * ... p n - * and you want to result in a list like: - * ... n+p - * This means that the p could be equals to 0 in case there is no astNode pushed - * on the astStack. - * Look at the InterfaceMemberDeclarations for an example. - */ - - astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--]; -} -protected void consumeAllocationHeader() { - // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt - // ClassBodyopt produces a null item on the astStak if it produces NO class body - // An empty class body produces a 0 on the length stack..... - - if (currentElement == null){ - return; // should never occur, this consumeRule is only used in recovery mode - } - if (currentToken == TokenNameLBRACE){ - // beginning of an anonymous type - AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult); - anonymousType.sourceStart = intStack[intPtr--]; - anonymousType.sourceEnd = rParenPos; // closing parenthesis - lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition; - currentElement = currentElement.add(anonymousType, 0); - lastIgnoredToken = -1; - currentToken = 0; // opening brace already taken into account - return; + private void declare_list() { + // T_STRING '=' static_scalar + // | declare_list ',' T_STRING '=' static_scalar + while (true) { + if (token != TokenNameIdentifier) { + throwSyntaxError("Identifier expected in 'declare' list."); + } + getNextToken(); + if (token != TokenNameEQUAL) { + throwSyntaxError("'=' expected in 'declare' list."); + } + getNextToken(); + static_scalar(); + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } } - lastCheckPoint = scanner.startPosition; // force to restart at this exact position - restartRecovery = true; // request to restart from here on -} -protected void consumeArgumentList() { - // ArgumentList ::= ArgumentList ',' Expression - concatExpressionLists(); -} -protected void consumeArrayAccess(boolean unspecifiedReference) { - // ArrayAccess ::= Name '[' Expression ']' ==> true - // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false - - - //optimize push/pop - Expression exp; - if (unspecifiedReference) { - exp = - expressionStack[expressionPtr] = - new ArrayReference( - getUnspecifiedReferenceOptimized(), - expressionStack[expressionPtr]); - } else { - expressionPtr--; - expressionLengthPtr--; - exp = - expressionStack[expressionPtr] = - new ArrayReference( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1]); + + private void additional_catches() { + while (token == TokenNamecatch) { + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected in 'catch' statement."); + } + getNextToken(); + fully_qualified_class_name(); + if (token != TokenNameVariable) { + throwSyntaxError("Variable expected in 'catch' statement."); + } + addVariableSet(); + getNextToken(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in 'catch' statement."); + } + getNextToken(); + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in 'catch' statement."); + } + getNextToken(); + if (token != TokenNameRBRACE) { + statementList(); + } + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in 'catch' statement."); + } + getNextToken(); + } } - exp.sourceEnd = endPosition; -} -protected void consumeArrayCreationExpression() { - // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt - // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt - - int length; - ArrayAllocationExpression aae = new ArrayAllocationExpression(); - if (expressionLengthStack[expressionLengthPtr] != 0) { - expressionLengthPtr -- ; - aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--]; - } else { - expressionLengthPtr--; + + private void foreach_variable() { + // w_variable + // | '&' w_variable + if (token == TokenNameAND) { + getNextToken(); + } + w_variable(true); } - - aae.type = getTypeReference(0); - length = (expressionLengthStack[expressionLengthPtr--]); - expressionPtr -= length ; - System.arraycopy( - expressionStack, - expressionPtr+1, - aae.dimensions = new Expression[length], - 0, - length); - aae.sourceStart = intStack[intPtr--]; - if (aae.initializer == null) { - aae.sourceEnd = endPosition; - } else { - aae.sourceEnd = aae.initializer.sourceEnd ; + + private void foreach_optional_arg() { + // /* empty */ + // | T_DOUBLE_ARROW foreach_variable + if (token == TokenNameEQUAL_GREATER) { + getNextToken(); + foreach_variable(); + } } - pushOnExpressionStack(aae); -} -protected void consumeArrayInitializer() { - // ArrayInitializer ::= '{' VariableInitializers '}' - // ArrayInitializer ::= '{' VariableInitializers , '}' - - arrayInitializer(expressionLengthStack[expressionLengthPtr--]); -} - -protected void consumeAssertStatement() { - // AssertStatement ::= 'assert' Expression ':' Expression ';' - expressionLengthPtr-=2; - pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--])); -} - -protected void consumeAssignment() { - // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression - //optimize the push/pop - - int op = intStack[intPtr--] ; //<--the encoded operator - - expressionPtr -- ; expressionLengthPtr -- ; - expressionStack[expressionPtr] = - (op != EQUAL ) ? - new CompoundAssignment( - expressionStack[expressionPtr] , - expressionStack[expressionPtr+1], - op, - scanner.startPosition - 1) : - new Assignment( - expressionStack[expressionPtr] , - expressionStack[expressionPtr+1], - scanner.startPosition - 1); -} -protected void consumeAssignmentOperator(int pos) { - // AssignmentOperator ::= '=' - // AssignmentOperator ::= '*=' - // AssignmentOperator ::= '/=' - // AssignmentOperator ::= '%=' - // AssignmentOperator ::= '+=' - // AssignmentOperator ::= '-=' - // AssignmentOperator ::= '<<=' - // AssignmentOperator ::= '>>=' - // AssignmentOperator ::= '>>>=' - // AssignmentOperator ::= '&=' - // AssignmentOperator ::= '^=' - // AssignmentOperator ::= '|=' - - try { - intStack[++intPtr] = pos; - } catch (IndexOutOfBoundsException e) { - //intPtr is correct - int oldStackLength = intStack.length; - int oldStack[] = intStack; - intStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldStack, 0, intStack, 0, oldStackLength); - intStack[intPtr] = pos; + + private void global_var_list() { + // global_var_list: + // global_var_list ',' global_var + // | global_var + HashSet set = peekVariableSet(); + while (true) { + global_var(set); + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } } -} -protected void consumeBinaryExpression(int op) { - // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression - // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression - // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression - // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression - // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression - // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression - // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression - // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression - // RelationalExpression ::= RelationalExpression '<' ShiftExpression - // RelationalExpression ::= RelationalExpression '>' ShiftExpression - // RelationalExpression ::= RelationalExpression '<=' ShiftExpression - // RelationalExpression ::= RelationalExpression '>=' ShiftExpression - // AndExpression ::= AndExpression '&' EqualityExpression - // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression - // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression - // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression - // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression - - //optimize the push/pop - - expressionPtr--; - expressionLengthPtr--; - if (op == OR_OR) { - expressionStack[expressionPtr] = - new OR_OR_Expression( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1], - op); - } else { - if (op == AND_AND) { - expressionStack[expressionPtr] = - new AND_AND_Expression( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1], - op); - } else { - // look for "string1" + "string2" - if ((op == PLUS) && optimizeStringLiterals) { - Expression expr1, expr2; - expr1 = expressionStack[expressionPtr]; - expr2 = expressionStack[expressionPtr + 1]; - if (expr1 instanceof StringLiteral) { - if (expr2 instanceof CharLiteral) { // string+char - expressionStack[expressionPtr] = - ((StringLiteral) expr1).extendWith((CharLiteral) expr2); - } else if (expr2 instanceof StringLiteral) { //string+string - expressionStack[expressionPtr] = - ((StringLiteral) expr1).extendWith((StringLiteral) expr2); - } else { - expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS); - } - } else { - expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS); + + private void global_var(HashSet set) { + // global_var: + // T_VARIABLE + // | '$' r_variable + // | '$' '{' expr '}' + if (token == TokenNameVariable) { + if (fMethodVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_GLOBAL_VAR); + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } + addVariableSet(set); + getNextToken(); + } else if (token == TokenNameDOLLAR) { + getNextToken(); + if (token == TokenNameLBRACE) { + getNextToken(); + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in global variable."); } + getNextToken(); } else { - expressionStack[expressionPtr] = - new BinaryExpression( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1], - op); + r_variable(); } } } -} -protected void consumeBlock() { - // Block ::= OpenBlock '{' BlockStatementsopt '}' - // simpler action for empty blocks - - int length; - if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block - pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition)); - realBlockPtr--; // still need to pop the block variable counter - } else { - Block bk = new Block(realBlockStack[realBlockPtr--]); - astPtr -= length; - System.arraycopy( - astStack, - astPtr + 1, - bk.statements = new Statement[length], - 0, - length); - pushOnAstStack(bk); - bk.sourceStart = intStack[intPtr--]; - bk.sourceEnd = endStatementPosition; - } -} -protected void consumeBlockStatements() { - // BlockStatements ::= BlockStatements BlockStatement - concatNodeLists(); -} -protected void consumeCaseLabel() { - // SwitchLabel ::= 'case' ConstantExpression ':' - expressionLengthPtr--; - pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--])); -} -protected void consumeCastExpression() { - // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression - // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus - - //intStack : posOfLeftParen dim posOfRightParen - - //optimize the push/pop - - Expression exp, cast, castType; - int end = intStack[intPtr--]; - expressionStack[expressionPtr] = cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--])); - castType.sourceEnd = end - 1; - castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1; - cast.sourceEnd = exp.sourceEnd; -} -protected void consumeCastExpressionLL1() { - //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus - // Expression is used in order to make the grammar LL1 - - //optimize push/pop - - Expression castType,cast,exp; - expressionPtr--; - expressionStack[expressionPtr] = - cast = new CastExpression( exp=expressionStack[expressionPtr+1] , - castType = getTypeReference(expressionStack[expressionPtr])); - expressionLengthPtr -- ; - updateSourcePosition(castType); - cast.sourceStart=castType.sourceStart; - cast.sourceEnd=exp.sourceEnd; - castType.sourceStart++; - castType.sourceEnd--; - } -protected void consumeCatches() { - // Catches ::= Catches CatchClause - optimizedConcatNodeLists(); -} -protected void consumeCatchHeader() { - // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{' - - if (currentElement == null){ - return; // should never occur, this consumeRule is only used in recovery mode - } - // current element should be a block due to the presence of the opening brace - if (!(currentElement instanceof RecoveredBlock)){ - return; - } - // exception argument is already on astStack - ((RecoveredBlock)currentElement).attach( - new RecoveredLocalVariable((Argument)astStack[astPtr--], currentElement, 0)); // insert catch variable in catch block - lastCheckPoint = scanner.startPosition; // force to restart at this exact position - restartRecovery = true; // request to restart from here on - lastIgnoredToken = -1; -} -protected void consumeClassBodyDeclaration() { - // ClassBodyDeclaration ::= Diet Block - //push an Initializer - //optimize the push/pop - nestedMethod[nestedType]--; - Initializer initializer = new Initializer((Block) astStack[astPtr], 0); - intPtr--; // pop sourcestart left on the stack by consumeNestedMethod. - realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod - int javadocCommentStart = intStack[intPtr--]; - if (javadocCommentStart != -1) { - initializer.declarationSourceStart = javadocCommentStart; - } - astStack[astPtr] = initializer; - initializer.sourceEnd = endStatementPosition; - initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); -} -protected void consumeClassBodyDeclarations() { - // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration - concatNodeLists(); -} -protected void consumeClassBodyDeclarationsopt() { - // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations - nestedType-- ; -} -protected void consumeClassBodyopt() { - // ClassBodyopt ::= $empty - pushOnAstStack(null); - endPosition = scanner.startPosition - 1; -} -protected void consumeClassDeclaration() { - // ClassDeclaration ::= ClassHeader ClassBody - - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - //there are length declarations - //dispatch according to the type of the declarations - dispatchDeclarationInto(length); - } - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - - // mark fields and initializer with local type mark if needed - markFieldsWithLocalType(typeDecl); - - //convert constructor that do not have the type's name into methods - boolean hasConstructor = typeDecl.checkConstructors(this); - - //add the default constructor when needed (interface don't have it) - if (!hasConstructor) { - boolean insideFieldInitializer = false; - if (diet) { - for (int i = nestedType; i > 0; i--){ - if (variablesCounter[i] > 0) { - insideFieldInitializer = true; + private void static_var_list() { + // static_var_list: + // static_var_list ',' T_VARIABLE + // | static_var_list ',' T_VARIABLE '=' static_scalar + // | T_VARIABLE + // | T_VARIABLE '=' static_scalar, + HashSet set = peekVariableSet(); + while (true) { + if (token == TokenNameVariable) { + if (fMethodVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_STATIC_VAR); + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } + addVariableSet(set); + getNextToken(); + if (token == TokenNameEQUAL) { + getNextToken(); + static_scalar(); + } + if (token != TokenNameCOMMA) { break; } + getNextToken(); + } else { + break; } } - typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true); } - //always add (will be remove at code gen time if empty) - if (this.scanner.containsAssertKeyword) { - typeDecl.bits |= AstNode.AddAssertionMASK; - } - typeDecl.addClinit(); - typeDecl.bodyEnd = endStatementPosition; - typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); -} -protected void consumeClassHeader() { - // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt - - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - if (currentToken == TokenNameLBRACE) { - typeDecl.bodyStart = scanner.currentPosition; - } - if (currentElement != null) { - restartRecovery = true; // used to avoid branching back into the regular automaton - } - // flush the comments related to the class header - scanner.commentPtr = -1; -} -protected void consumeClassHeaderExtends() { - // ClassHeaderExtends ::= 'extends' ClassType - // There is a class declaration on the top of stack - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - //superclass - typeDecl.superclass = getTypeReference(0); - typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1; - // recovery - if (currentElement != null){ - lastCheckPoint = typeDecl.bodyStart; - } -} -protected void consumeClassHeaderImplements() { - // ClassHeaderImplements ::= 'implements' InterfaceTypeList - int length = astLengthStack[astLengthPtr--]; - //super interfaces - astPtr -= length; - // There is a class declaration on the top of stack - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - System.arraycopy( - astStack, - astPtr + 1, - typeDecl.superInterfaces = new TypeReference[length], - 0, - length); - typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1; - listLength = 0; // reset after having read super-interfaces - // recovery - if (currentElement != null) { // is recovering - lastCheckPoint = typeDecl.bodyStart; + private void unset_variables() { + // unset_variables: + // unset_variable + // | unset_variables ',' unset_variable + // unset_variable: + // variable + while (true) { + variable(false, false); + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } } -} -protected void consumeClassHeaderName() { - // ClassHeaderName ::= Modifiersopt 'class' 'Identifier' - TypeDeclaration typeDecl; - if (nestedMethod[nestedType] == 0) { - if (nestedType != 0) { - typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult); + + private final void initializeModifiers() { + this.modifiers = 0; + this.modifiersSourceStart = -1; + } + + private final void checkAndSetModifiers(int flag) { + this.modifiers |= flag; + if (this.modifiersSourceStart < 0) + this.modifiersSourceStart = this.scanner.startPosition; + } + + private void unticked_class_declaration_statement(TypeDeclaration typeDecl) { + initializeModifiers(); + if (token == TokenNameinterface) { + // interface_entry T_STRING + // interface_extends_list + // '{' class_statement_list '}' + checkAndSetModifiers(AccInterface); + getNextToken(); + typeDecl.modifiers = this.modifiers; + typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { + typeDecl.name = scanner.getCurrentIdentifierSource(); + if (token > TokenNameKEYWORD) { + problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), + scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); + // throwSyntaxError("Don't use a keyword for interface declaration [" + // + scanner.toStringAction(token) + "].", + // typeDecl.sourceStart, typeDecl.sourceEnd); + } + getNextToken(); + interface_extends_list(typeDecl); + } else { + typeDecl.name = new char[] { ' ' }; + throwSyntaxError("Interface name expected after keyword 'interface'.", typeDecl.sourceStart, typeDecl.sourceEnd); + return; + } } else { - typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + // class_entry_type T_STRING extends_from + // implements_list + // '{' class_statement_list'}' + class_entry_type(); + typeDecl.modifiers = this.modifiers; + typeDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + // identifier + // identifier 'extends' identifier + if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { + typeDecl.name = scanner.getCurrentIdentifierSource(); + if (token > TokenNameKEYWORD) { + problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), + scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); + // throwSyntaxError("Don't use a keyword for class declaration [" + + // scanner.toStringAction(token) + "].", + // typeDecl.sourceStart, typeDecl.sourceEnd); + } + getNextToken(); + // extends_from: + // /* empty */ + // | T_EXTENDS fully_qualified_class_name + if (token == TokenNameextends) { + interface_extends_list(typeDecl); + // getNextToken(); + // if (token != TokenNameIdentifier) { + // throwSyntaxError("Class name expected after keyword + // 'extends'.", + // scanner.getCurrentTokenStartPosition(), scanner + // .getCurrentTokenEndPosition()); + // } + } + implements_list(typeDecl); + } else { + typeDecl.name = new char[] { ' ' }; + throwSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd); + return; + } + } + // '{' class_statement_list '}' + if (token == TokenNameLBRACE) { + getNextToken(); + if (token != TokenNameRBRACE) { + ArrayList list = new ArrayList(); + class_statement_list(list); + typeDecl.fields = new FieldDeclaration[list.size()]; + for (int i = 0; i < list.size(); i++) { + typeDecl.fields[i] = (FieldDeclaration) list.get(i); + } + } + if (token == TokenNameRBRACE) { + typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } else { + throwSyntaxError("'}' expected at end of class body."); + } + } else { + throwSyntaxError("'{' expected at start of class body."); } - } else { - // Record that the block has a declaration for local types - typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult); - markCurrentMethodWithLocalType(); - blockReal(); } - //highlight the name of the type - long pos = identifierPositionStack[identifierPtr]; - typeDecl.sourceEnd = (int) pos; - typeDecl.sourceStart = (int) (pos >>> 32); - typeDecl.name = identifierStack[identifierPtr--]; - identifierLengthPtr--; - - //compute the declaration source too - // 'class' and 'interface' push two int positions: the beginning of the class token and its end. - // we want to keep the beginning position but get rid of the end position - // it is only used for the ClassLiteralAccess positions. - typeDecl.declarationSourceStart = intStack[intPtr--]; - intPtr--; // remove the end position of the class token - - typeDecl.modifiersSourceStart = intStack[intPtr--]; - typeDecl.modifiers = intStack[intPtr--]; - if (typeDecl.modifiersSourceStart >= 0) { - typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart; - } - typeDecl.bodyStart = typeDecl.sourceEnd + 1; - pushOnAstStack(typeDecl); - - listLength = 0; // will be updated when reading super-interfaces - // recovery - if (currentElement != null){ - lastCheckPoint = typeDecl.bodyStart; - currentElement = currentElement.add(typeDecl, 0); - lastIgnoredToken = -1; + private void class_entry_type() { + // T_CLASS + // | T_ABSTRACT T_CLASS + // | T_FINAL T_CLASS + if (token == TokenNameclass) { + getNextToken(); + } else if (token == TokenNameabstract) { + checkAndSetModifiers(AccAbstract); + getNextToken(); + if (token != TokenNameclass) { + throwSyntaxError("Keyword 'class' expected after keyword 'abstract'."); + } + getNextToken(); + } else if (token == TokenNamefinal) { + checkAndSetModifiers(AccFinal); + getNextToken(); + if (token != TokenNameclass) { + throwSyntaxError("Keyword 'class' expected after keyword 'final'."); + } + getNextToken(); + } else { + throwSyntaxError("Keyword 'class' 'final' or 'abstract' expected"); + } } -} -protected void consumeClassInstanceCreationExpression() { - // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt - classInstanceCreation(false); -} -protected void consumeClassInstanceCreationExpressionName() { - // ClassInstanceCreationExpressionName ::= Name '.' - pushOnExpressionStack(getUnspecifiedReferenceOptimized()); -} -protected void consumeClassInstanceCreationExpressionQualified() { - // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt - // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt - - classInstanceCreation(true); // <-- push the Qualifed.... - - expressionLengthPtr--; - QualifiedAllocationExpression qae = - (QualifiedAllocationExpression) expressionStack[expressionPtr--]; - qae.enclosingInstance = expressionStack[expressionPtr]; - expressionStack[expressionPtr] = qae; - qae.sourceStart = qae.enclosingInstance.sourceStart; -} -protected void consumeClassTypeElt() { - // ClassTypeElt ::= ClassType - pushOnAstStack(getTypeReference(0)); - /* if incomplete thrown exception list, listLength counter will not have been reset, - indicating that some items are available on the stack */ - listLength++; -} -protected void consumeClassTypeList() { - // ClassTypeList ::= ClassTypeList ',' ClassTypeElt - optimizedConcatNodeLists(); -} -protected void consumeCompilationUnit() { - // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt - // do nothing by default -} -protected void consumeConditionalExpression(int op) { - // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression - //optimize the push/pop - - expressionPtr -= 2; - expressionLengthPtr -= 2; - expressionStack[expressionPtr] = - new ConditionalExpression( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1], - expressionStack[expressionPtr + 2]); -} -protected void consumeConstructorBlockStatements() { - // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}' - concatNodeLists(); // explictly add the first statement into the list of statements -} -protected void consumeConstructorBody() { - // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}' - // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}' - nestedMethod[nestedType] --; -} -protected void consumeConstructorDeclaration() { - // ConstructorDeclaration ::= ConstructorHeader ConstructorBody - /* - astStack : MethodDeclaration statements - identifierStack : name - ==> - astStack : MethodDeclaration - identifierStack : - */ - - //must provide a default constructor call when needed - - int length; - - // pop the position of the { (body of the method) pushed in block decl - intPtr--; - - //statements - realBlockPtr--; - ExplicitConstructorCall constructorCall = null; - Statement[] statements = null; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) { - //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ? - System.arraycopy( - astStack, - astPtr + 2, - statements = new Statement[length - 1], - 0, - length - 1); - constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1]; - } else { //need to add explicitly the super(); - System.arraycopy( - astStack, - astPtr + 1, - statements = new Statement[length], - 0, - length); - constructorCall = SuperReference.implicitSuperConstructorCall(); - } - } else { - if (!diet){ - // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere. - constructorCall = SuperReference.implicitSuperConstructorCall(); + // private void class_extends(TypeDeclaration typeDecl) { + // // /* empty */ + // // | T_EXTENDS interface_list + // if (token == TokenNameextends) { + // getNextToken(); + // + // if (token == TokenNameIdentifier) { + // getNextToken(); + // } else { + // throwSyntaxError("Class name expected after keyword 'extends'."); + // } + // } + // } + + private void interface_extends_list(TypeDeclaration typeDecl) { + // /* empty */ + // | T_EXTENDS interface_list + if (token == TokenNameextends) { + getNextToken(); + interface_list(); } } - // now we know that the top of stack is a constructorDeclaration - ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr]; - cd.constructorCall = constructorCall; - cd.statements = statements; - - //highlight of the implicit call on the method name - if (constructorCall != null && cd.constructorCall.sourceEnd == 0) { - cd.constructorCall.sourceEnd = cd.sourceEnd; - cd.constructorCall.sourceStart = cd.sourceStart; + private void implements_list(TypeDeclaration typeDecl) { + // /* empty */ + // | T_IMPLEMENTS interface_list + if (token == TokenNameimplements) { + getNextToken(); + interface_list(); + } } - //watch for } that could be given as a unicode ! ( u007D is '}' ) - // store the endPosition (position just before the '}') in case there is - // a trailing comment behind the end of the method - cd.bodyEnd = endPosition; - cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); -} - -protected void consumeInvalidConstructorDeclaration() { - // ConstructorDeclaration ::= ConstructorHeader ';' - // now we know that the top of stack is a constructorDeclaration - ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr]; - - cd.bodyEnd = endPosition; // position just before the trailing semi-colon - cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); - // report the problem and continue the parsing - narrowing the problem onto the method -} -protected void consumeConstructorHeader() { - // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt - - AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr]; - - if (currentToken == TokenNameLBRACE){ - method.bodyStart = scanner.currentPosition; - } - // recovery - if (currentElement != null){ - restartRecovery = true; // used to avoid branching back into the regular automaton - } -} -protected void consumeConstructorHeaderName() { - - /* recovering - might be an empty message send */ - if (currentElement != null){ - if (lastIgnoredToken == TokenNamenew){ // was an allocation expression - lastCheckPoint = scanner.startPosition; // force to restart at this exact position - restartRecovery = true; - return; + private void interface_list() { + // interface_list: + // fully_qualified_class_name + // | interface_list ',' fully_qualified_class_name + do { + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + throwSyntaxError("Interface name expected after keyword 'implements'."); + } + if (token != TokenNameCOMMA) { + return; + } + getNextToken(); + } while (true); + } + + // private void classBody(TypeDeclaration typeDecl) { + // //'{' [class-element-list] '}' + // if (token == TokenNameLBRACE) { + // getNextToken(); + // if (token != TokenNameRBRACE) { + // class_statement_list(); + // } + // if (token == TokenNameRBRACE) { + // typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + // getNextToken(); + // } else { + // throwSyntaxError("'}' expected at end of class body."); + // } + // } else { + // throwSyntaxError("'{' expected at start of class body."); + // } + // } + private void class_statement_list(ArrayList list) { + do { + try { + class_statement(list); + if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic + || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar + || token == TokenNameconst) { + continue; + } + if (token == TokenNameRBRACE) { + break; + } + throwSyntaxError("'}' at end of class statement."); + } catch (SyntaxError sytaxErr1) { + boolean tokenize = scanner.tokenizeStrings; + if (!tokenize) { + scanner.tokenizeStrings = true; + } + try { + // if an error occured, + // try to find keywords + // to parse the rest of the string + while (token != TokenNameEOF) { + if (token == TokenNamepublic || token == TokenNameprotected || token == TokenNameprivate || token == TokenNamestatic + || token == TokenNameabstract || token == TokenNamefinal || token == TokenNamefunction || token == TokenNamevar + || token == TokenNameconst) { + break; + } + // System.out.println(scanner.toStringAction(token)); + getNextToken(); + } + if (token == TokenNameEOF) { + throw sytaxErr1; + } + } finally { + scanner.tokenizeStrings = tokenize; + } + } + } while (true); + } + + private void class_statement(ArrayList list) { + // class_statement: + // variable_modifiers class_variable_declaration ';' + // | class_constant_declaration ';' + // | method_modifiers T_FUNCTION is_reference T_STRING + // '(' parameter_list ')' method_body + initializeModifiers(); + int declarationSourceStart = scanner.getCurrentTokenStartPosition(); + + if (token == TokenNamevar) { + checkAndSetModifiers(AccPublic); + problemReporter.phpVarDeprecatedWarning(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), + referenceContext, compilationUnit.compilationResult); + getNextToken(); + class_variable_declaration(declarationSourceStart, list); + } else if (token == TokenNameconst) { + checkAndSetModifiers(AccFinal | AccPublic); + class_constant_declaration(declarationSourceStart, list); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after class const declaration."); + } + getNextToken(); + } else { + boolean hasModifiers = member_modifiers(); + if (token == TokenNamefunction) { + if (!hasModifiers) { + checkAndSetModifiers(AccPublic); + } + MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult); + methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.modifiers = this.modifiers; + methodDecl.type = MethodDeclaration.METHOD_DEFINITION; + try { + getNextToken(); + functionDefinition(methodDecl); + } finally { + int sourceEnd = methodDecl.sourceEnd; + if (sourceEnd <= 0 || methodDecl.declarationSourceStart > sourceEnd) { + sourceEnd = methodDecl.declarationSourceStart + 1; + } + methodDecl.declarationSourceEnd = sourceEnd; + methodDecl.sourceEnd = sourceEnd; + } + } else { + if (!hasModifiers) { + throwSyntaxError("'public' 'private' or 'protected' modifier expected for field declarations."); + } + class_variable_declaration(declarationSourceStart, list); + } } } - - // ConstructorHeaderName ::= Modifiersopt 'Identifier' '(' - ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult); - - //name -- this is not really revelant but we do ..... - cd.selector = identifierStack[identifierPtr]; - long selectorSource = identifierPositionStack[identifierPtr--]; - identifierLengthPtr--; - - //modifiers - cd.declarationSourceStart = intStack[intPtr--]; - cd.modifiers = intStack[intPtr--]; - - //highlight starts at the selector starts - cd.sourceStart = (int) (selectorSource >>> 32); - pushOnAstStack(cd); - cd.sourceEnd = lParenPos; - cd.bodyStart = lParenPos+1; - listLength = 0; // initialize listLength before reading parameters/throws - - // recovery - if (currentElement != null){ - lastCheckPoint = cd.bodyStart; - if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT) - || cd.modifiers != 0){ - currentElement = currentElement.add(cd, 0); - lastIgnoredToken = -1; - } - } -} -protected void consumeDefaultLabel() { - // SwitchLabel ::= 'default' ':' - pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--])); -} -protected void consumeDefaultModifiers() { - checkAnnotation(); // might update modifiers with AccDeprecated - pushOnIntStack(modifiers); // modifiers - pushOnIntStack( - modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition); - resetModifiers(); -} -protected void consumeDiet() { - // Diet ::= $empty - checkAnnotation(); - pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one - jumpOverMethodBody(); -} -protected void consumeDims() { - // Dims ::= DimsLoop - pushOnIntStack(dimensions); - dimensions = 0; -} -protected void consumeDimWithOrWithOutExpr() { - // DimWithOrWithOutExpr ::= '[' ']' - pushOnExpressionStack(null); -} -protected void consumeDimWithOrWithOutExprs() { - // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr - concatExpressionLists(); -} -protected void consumeEmptyArgumentListopt() { - // ArgumentListopt ::= $empty - pushOnExpressionStackLengthStack(0); -} -protected void consumeEmptyArrayInitializer() { - // ArrayInitializer ::= '{' ,opt '}' - arrayInitializer(0); -} -protected void consumeEmptyArrayInitializeropt() { - // ArrayInitializeropt ::= $empty - pushOnExpressionStackLengthStack(0); -} -protected void consumeEmptyBlockStatementsopt() { - // BlockStatementsopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyCatchesopt() { - // Catchesopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyClassBodyDeclarationsopt() { - // ClassBodyDeclarationsopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyClassMemberDeclaration() { - // ClassMemberDeclaration ::= ';' - pushOnAstLengthStack(0); -} -protected void consumeEmptyDimsopt() { - // Dimsopt ::= $empty - pushOnIntStack(0); -} -protected void consumeEmptyExpression() { - // Expressionopt ::= $empty - pushOnExpressionStackLengthStack(0); -} -protected void consumeEmptyForInitopt() { - // ForInitopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyForUpdateopt() { - // ForUpdateopt ::= $empty - pushOnExpressionStackLengthStack(0); -} -protected void consumeEmptyImportDeclarationsopt() { - // ImportDeclarationsopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyInterfaceMemberDeclaration() { - // InterfaceMemberDeclaration ::= ';' - pushOnAstLengthStack(0); -} -protected void consumeEmptyInterfaceMemberDeclarationsopt() { - // InterfaceMemberDeclarationsopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEmptyStatement() { - // EmptyStatement ::= ';' - if (this.scanner.source[endStatementPosition] == ';') { - pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition)); - } else { - // we have a Unicode for the ';' (/u003B) - pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition)); + + private void class_constant_declaration(int declarationSourceStart, ArrayList list) { + // class_constant_declaration ',' T_STRING '=' static_scalar + // | T_CONST T_STRING '=' static_scalar + if (token != TokenNameconst) { + throwSyntaxError("'const' keyword expected in class declaration."); + } else { + getNextToken(); + } + while (true) { + if (token != TokenNameIdentifier) { + throwSyntaxError("Identifier expected in class const declaration."); + } + FieldDeclaration fieldDeclaration = new FieldDeclaration(scanner.getCurrentIdentifierSource(), scanner + .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()); + fieldDeclaration.modifiers = this.modifiers; + fieldDeclaration.declarationSourceStart = declarationSourceStart; + fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + fieldDeclaration.modifiersSourceStart = declarationSourceStart; + // fieldDeclaration.type + list.add(fieldDeclaration); + getNextToken(); + if (token != TokenNameEQUAL) { + throwSyntaxError("'=' expected in class const declaration."); + } + getNextToken(); + static_scalar(); + if (token != TokenNameCOMMA) { + break; // while(true)-loop + } + getNextToken(); + } } -} -protected void consumeEmptySwitchBlock() { - // SwitchBlock ::= '{' '}' - pushOnAstLengthStack(0); -} -protected void consumeEmptyTypeDeclaration() { - // TypeDeclaration ::= ';' - pushOnAstLengthStack(0); -} -protected void consumeEmptyTypeDeclarationsopt() { - // TypeDeclarationsopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeEnterAnonymousClassBody() { - // EnterAnonymousClassBody ::= $empty - QualifiedAllocationExpression alloc; - AnonymousLocalTypeDeclaration anonymousType = - new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult); - alloc = - anonymousType.allocation = new QualifiedAllocationExpression(anonymousType); - markCurrentMethodWithLocalType(); - pushOnAstStack(anonymousType); - - alloc.sourceEnd = rParenPos; //the position has been stored explicitly - int argumentLength; - if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) { - expressionPtr -= argumentLength; - System.arraycopy( - expressionStack, - expressionPtr + 1, - alloc.arguments = new Expression[argumentLength], - 0, - argumentLength); + + // private void variable_modifiers() { + // // variable_modifiers: + // // non_empty_member_modifiers + // //| T_VAR + // initializeModifiers(); + // if (token == TokenNamevar) { + // checkAndSetModifiers(AccPublic); + // reportSyntaxError( + // "Keyword 'var' is deprecated. Please use 'public' 'private' or + // 'protected' + // modifier for field declarations.", + // scanner.getCurrentTokenStartPosition(), scanner + // .getCurrentTokenEndPosition()); + // getNextToken(); + // } else { + // if (!member_modifiers()) { + // throwSyntaxError("'public' 'private' or 'protected' modifier expected for + // field declarations."); + // } + // } + // } + // private void method_modifiers() { + // //method_modifiers: + // // /* empty */ + // //| non_empty_member_modifiers + // initializeModifiers(); + // if (!member_modifiers()) { + // checkAndSetModifiers(AccPublic); + // } + // } + private boolean member_modifiers() { + // T_PUBLIC + // | T_PROTECTED + // | T_PRIVATE + // | T_STATIC + // | T_ABSTRACT + // | T_FINAL + boolean foundToken = false; + while (true) { + if (token == TokenNamepublic) { + checkAndSetModifiers(AccPublic); + getNextToken(); + foundToken = true; + } else if (token == TokenNameprotected) { + checkAndSetModifiers(AccProtected); + getNextToken(); + foundToken = true; + } else if (token == TokenNameprivate) { + checkAndSetModifiers(AccPrivate); + getNextToken(); + foundToken = true; + } else if (token == TokenNamestatic) { + checkAndSetModifiers(AccStatic); + getNextToken(); + foundToken = true; + } else if (token == TokenNameabstract) { + checkAndSetModifiers(AccAbstract); + getNextToken(); + foundToken = true; + } else if (token == TokenNamefinal) { + checkAndSetModifiers(AccFinal); + getNextToken(); + foundToken = true; + } else { + break; + } + } + return foundToken; } - alloc.type = getTypeReference(0); - - anonymousType.sourceEnd = alloc.sourceEnd; - //position at the type while it impacts the anonymous declaration - anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart; - alloc.sourceStart = intStack[intPtr--]; - pushOnExpressionStack(alloc); - - anonymousType.bodyStart = scanner.currentPosition; - listLength = 0; // will be updated when reading super-interfaces - // recovery - if (currentElement != null){ - lastCheckPoint = anonymousType.bodyStart; - // the recoveryTokenCheck will deal with the open brace - currentElement = currentElement.add(anonymousType, 0); - currentToken = 0; // opening brace already taken into account - lastIgnoredToken = -1; - } -} -protected void consumeEnterCompilationUnit() { - // EnterCompilationUnit ::= $empty - // do nothing by default -} -protected void consumeEnterVariable() { - // EnterVariable ::= $empty - // do nothing by default - - char[] name = identifierStack[identifierPtr]; - long namePosition = identifierPositionStack[identifierPtr]; - int extendedDimension = intStack[intPtr--]; - AbstractVariableDeclaration declaration; - // create the ast node - boolean isLocalDeclaration = nestedMethod[nestedType] != 0; - if (isLocalDeclaration) { - // create the local variable declarations - declaration = - this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); - } else { - // create the field declaration - declaration = - this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); + + private void class_variable_declaration(int declarationSourceStart, ArrayList list) { + // class_variable_declaration: + // class_variable_declaration ',' T_VARIABLE + // | class_variable_declaration ',' T_VARIABLE '=' static_scalar + // | T_VARIABLE + // | T_VARIABLE '=' static_scalar + char[] classVariable; + do { + if (token == TokenNameVariable) { + classVariable = scanner.getCurrentIdentifierSource(); + // indexManager.addIdentifierInformation('v', classVariable, buf, -1, + // -1); + FieldDeclaration fieldDeclaration = new FieldDeclaration(classVariable, scanner.getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); + fieldDeclaration.modifiers = this.modifiers; + fieldDeclaration.declarationSourceStart = declarationSourceStart; + fieldDeclaration.declarationSourceEnd = scanner.getCurrentTokenEndPosition(); + fieldDeclaration.modifiersSourceStart = declarationSourceStart; + list.add(fieldDeclaration); + if (fTypeVariables != null) { + VariableInfo info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_CLASS_UNIT); + fTypeVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } + getNextToken(); + if (token == TokenNameEQUAL) { + getNextToken(); + static_scalar(); + } + } else { + // if (token == TokenNamethis) { + // throwSyntaxError("'$this' not allowed after keyword 'public' + // 'protected' 'private' 'var'."); + // } + throwSyntaxError("Variable expected after keyword 'public' 'protected' 'private' 'var'."); + } + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } while (true); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after field declaration."); + } + getNextToken(); } - - identifierPtr--; - identifierLengthPtr--; - TypeReference type; - int variableIndex = variablesCounter[nestedType]; - int typeDim = 0; - if (variableIndex == 0) { - // first variable of the declaration (FieldDeclaration or LocalDeclaration) - if (isLocalDeclaration) { - declaration.declarationSourceStart = intStack[intPtr--]; - declaration.modifiers = intStack[intPtr--]; - type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension - if (declaration.declarationSourceStart == -1) { - // this is true if there is no modifiers for the local variable declaration - declaration.declarationSourceStart = type.sourceStart; - } - pushOnAstStack(type); + + private void functionDefinition(MethodDeclaration methodDecl) { + boolean isAbstract = false; + if (astPtr == 0) { + if (compilationUnit != null) { + compilationUnit.types.add(methodDecl); + } } else { - type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension - pushOnAstStack(type); - declaration.declarationSourceStart = intStack[intPtr--]; - declaration.modifiers = intStack[intPtr--]; - } - } else { - type = (TypeReference) astStack[astPtr - variableIndex]; - typeDim = type.dimensions(); - AbstractVariableDeclaration previousVariable = - (AbstractVariableDeclaration) astStack[astPtr]; - declaration.declarationSourceStart = previousVariable.declarationSourceStart; - declaration.modifiers = previousVariable.modifiers; + ASTNode node = astStack[astPtr]; + if (node instanceof TypeDeclaration) { + TypeDeclaration typeDecl = ((TypeDeclaration) node); + if (typeDecl.methods == null) { + typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl }; + } else { + AbstractMethodDeclaration[] newMethods; + System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 0, + typeDecl.methods.length); + newMethods[typeDecl.methods.length] = methodDecl; + typeDecl.methods = newMethods; + } + if ((typeDecl.modifiers & AccAbstract) == AccAbstract) { + isAbstract = true; + } else if ((typeDecl.modifiers & AccInterface) == AccInterface) { + isAbstract = true; + } + } + } + try { + pushFunctionVariableSet(); + functionDeclarator(methodDecl); + if (token == TokenNameSEMICOLON) { + if (!isAbstract) { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("Body declaration expected for method: " + new String(methodDecl.selector)); + } + getNextToken(); + return; + } + functionBody(methodDecl); + } finally { + if (!fStackUnassigned.isEmpty()) { + fStackUnassigned.remove(fStackUnassigned.size() - 1); + } + } } - if (extendedDimension == 0) { - declaration.type = type; - } else { - int dimension = typeDim + extendedDimension; - //on the identifierLengthStack there is the information about the type.... - int baseType; - if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) { - //it was a baseType - int typeSourceStart = type.sourceStart; - int typeSourceEnd = type.sourceEnd; - type = TypeReference.baseTypeReference(-baseType, dimension); - type.sourceStart = typeSourceStart; - type.sourceEnd = typeSourceEnd; - declaration.type = type; + private void functionDeclarator(MethodDeclaration methodDecl) { + // identifier '(' [parameter-list] ')' + if (token == TokenNameAND) { + getNextToken(); + } + methodDecl.sourceStart = scanner.getCurrentTokenStartPosition(); + methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition(); + if (Scanner.isIdentifierOrKeyword(token)) { + methodDecl.selector = scanner.getCurrentIdentifierSource(); + if (token > TokenNameKEYWORD) { + problemReporter.phpKeywordWarning(new String[] { scanner.toStringAction(token) }, scanner.getCurrentTokenStartPosition(), + scanner.getCurrentTokenEndPosition(), referenceContext, compilationUnit.compilationResult); + } + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("'(' expected in function declaration."); + } + if (token != TokenNameRPAREN) { + parameter_list(methodDecl); + } + if (token != TokenNameRPAREN) { + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("')' expected in function declaration."); + } else { + methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1; + getNextToken(); + } } else { - declaration.type = this.copyDims(type, dimension); + methodDecl.selector = "".toCharArray(); + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("Function name expected after keyword 'function'."); } } - variablesCounter[nestedType]++; - pushOnAstStack(declaration); - // recovery - if (currentElement != null) { - if (!(currentElement instanceof RecoveredType) - && (currentToken == TokenNameDOT - //|| declaration.modifiers != 0 - || (scanner.getLineNumber(declaration.type.sourceStart) - != scanner.getLineNumber((int) (namePosition >>> 32))))){ - lastCheckPoint = (int) (namePosition >>> 32); - restartRecovery = true; + + // + private void parameter_list(MethodDeclaration methodDecl) { + // non_empty_parameter_list + // | /* empty */ + non_empty_parameter_list(methodDecl, true); + } + + private void non_empty_parameter_list(MethodDeclaration methodDecl, boolean empty_allowed) { + // optional_class_type T_VARIABLE + // | optional_class_type '&' T_VARIABLE + // | optional_class_type '&' T_VARIABLE '=' static_scalar + // | optional_class_type T_VARIABLE '=' static_scalar + // | non_empty_parameter_list ',' optional_class_type T_VARIABLE + // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE + // | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' + // static_scalar + // | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' + // static_scalar + char[] typeIdentifier = null; + if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) { + HashSet set = peekVariableSet(); + while (true) { + if (token == TokenNameIdentifier) { + typeIdentifier = scanner.getCurrentIdentifierSource(); + getNextToken(); + } + if (token == TokenNameAND) { + getNextToken(); + } + if (token == TokenNameVariable) { + if (fMethodVariables != null) { + VariableInfo info; + if (methodDecl.type == MethodDeclaration.FUNCTION_DEFINITION) { + info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_FUNCTION_DEFINITION); + } else { + info = new VariableInfo(scanner.getCurrentTokenStartPosition(), VariableInfo.LEVEL_METHOD_DEFINITION); + } + info.typeIdentifier = typeIdentifier; + fMethodVariables.put(new String(scanner.getCurrentIdentifierSource()), info); + } + addVariableSet(set); + getNextToken(); + if (token == TokenNameEQUAL) { + getNextToken(); + static_scalar(); + } + } else { + throwSyntaxError("Variable expected in parameter list."); + } + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } return; } - if (isLocalDeclaration){ - LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr]; - lastCheckPoint = localDecl.sourceEnd + 1; - currentElement = currentElement.add(localDecl, 0); - } else { - FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr]; - lastCheckPoint = fieldDecl.sourceEnd + 1; - currentElement = currentElement.add(fieldDecl, 0); + if (!empty_allowed) { + throwSyntaxError("Identifier expected in parameter list."); } - lastIgnoredToken = -1; - } -} -protected void consumeEqualityExpression(int op) { - // EqualityExpression ::= EqualityExpression '==' RelationalExpression - // EqualityExpression ::= EqualityExpression '!=' RelationalExpression - - //optimize the push/pop - - expressionPtr--; - expressionLengthPtr--; - expressionStack[expressionPtr] = - new EqualExpression( - expressionStack[expressionPtr], - expressionStack[expressionPtr + 1], - op); -} -protected void consumeExitVariableWithInitialization() { - // ExitVariableWithInitialization ::= $empty - // do nothing by default - expressionLengthPtr--; - AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr]; - variableDecl.initialization = expressionStack[expressionPtr--]; - // we need to update the declarationSourceEnd of the local variable declaration to the - // source end position of the initialization expression - variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd; - variableDecl.declarationEnd = variableDecl.initialization.sourceEnd; -} -protected void consumeExitVariableWithoutInitialization() { - // ExitVariableWithoutInitialization ::= $empty - // do nothing by default -} -protected void consumeExplicitConstructorInvocation(int flag, int recFlag) { - - /* flag allows to distinguish 3 cases : - (0) : - ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';' - ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';' - (1) : - ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';' - ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';' - (2) : - ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';' - ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';' - */ - int startPosition = intStack[intPtr--]; - ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag); - int length; - if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) { - expressionPtr -= length; - System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length); } - switch (flag) { - case 0 : - ecc.sourceStart = startPosition; - break; - case 1 : - expressionLengthPtr--; - ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart; - break; - case 2 : - ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart; - break; - }; - pushOnAstStack(ecc); - ecc.sourceEnd = endPosition; -} -protected void consumeExpressionStatement() { - // ExpressionStatement ::= StatementExpression ';' - expressionLengthPtr--; - pushOnAstStack(expressionStack[expressionPtr--]); -} -protected void consumeFieldAccess(boolean isSuperAccess) { - // FieldAccess ::= Primary '.' 'Identifier' - // FieldAccess ::= 'super' '.' 'Identifier' - - FieldReference fr = - new FieldReference( - identifierStack[identifierPtr], - identifierPositionStack[identifierPtr--]); - identifierLengthPtr--; - if (isSuperAccess) { - //considerates the fieldReference beginning at the 'super' .... - fr.sourceStart = intStack[intPtr--]; - fr.receiver = new SuperReference(fr.sourceStart, endPosition); - pushOnExpressionStack(fr); - } else { - //optimize push/pop - if ((fr.receiver = expressionStack[expressionPtr]).isThis()) { - //fieldreference begins at the this - fr.sourceStart = fr.receiver.sourceStart; - } - expressionStack[expressionPtr] = fr; - } -} -protected void consumeFieldDeclaration() { - // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code - // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' - /* - astStack : - expressionStack: Expression Expression ...... Expression - identifierStack : type identifier identifier ...... identifier - intStack : typeDim dim dim dim - ==> - astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration - expressionStack : - identifierStack : - intStack : - - */ - int variableDeclaratorsCounter = astLengthStack[astLengthPtr]; - - for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) { - FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i]; - fieldDeclaration.declarationSourceEnd = endStatementPosition; - fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included - } - updateSourceDeclarationParts(variableDeclaratorsCounter); - int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition); - if (endPos != endStatementPosition) { - for (int i = 0; i < variableDeclaratorsCounter; i++) { - FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i]; - fieldDeclaration.declarationSourceEnd = endPos; + private void optional_class_type() { + // /* empty */ + // | T_STRING + } + + // private void parameterDeclaration() { + // //variable + // //variable-reference + // if (token == TokenNameAND) { + // getNextToken(); + // if (isVariable()) { + // getNextToken(); + // } else { + // throwSyntaxError("Variable expected after reference operator '&'."); + // } + // } + // //variable '=' constant + // if (token == TokenNameVariable) { + // getNextToken(); + // if (token == TokenNameEQUAL) { + // getNextToken(); + // static_scalar(); + // } + // return; + // } + // // if (token == TokenNamethis) { + // // throwSyntaxError("Reserved word '$this' not allowed in parameter + // // declaration."); + // // } + // } + + private void labeledStatementList() { + if (token != TokenNamecase && token != TokenNamedefault) { + throwSyntaxError("'case' or 'default' expected."); } - } - // update the astStack, astPtr and astLengthStack - int startIndex = astPtr - variablesCounter[nestedType] + 1; - System.arraycopy( - astStack, - startIndex, - astStack, - startIndex - 1, - variableDeclaratorsCounter); - astPtr--; // remove the type reference - astLengthStack[--astLengthPtr] = variableDeclaratorsCounter; - - // recovery - if (currentElement != null) { - lastCheckPoint = endPos + 1; - if (currentElement.parent != null && currentElement instanceof RecoveredField){ - currentElement = currentElement.parent; - } - restartRecovery = true; - } - variablesCounter[nestedType] = 0; -} -protected void consumeForceNoDiet() { - // ForceNoDiet ::= $empty - dietInt++; -} -protected void consumeForInit() { - // ForInit ::= StatementExpressionList - pushOnAstLengthStack(-1); -} -protected void consumeFormalParameter() { - // FormalParameter ::= Type VariableDeclaratorId ==> false - // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true - /* - astStack : - identifierStack : type identifier - intStack : dim dim - ==> - astStack : Argument - identifierStack : - intStack : - */ - - identifierLengthPtr--; - char[] name = identifierStack[identifierPtr]; - long namePositions = identifierPositionStack[identifierPtr--]; - TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]); - int modifierPositions = intStack[intPtr--]; - intPtr--; - Argument arg = - new Argument( - name, - namePositions, - type, - intStack[intPtr + 1] & ~AccDeprecated); // modifiers - arg.declarationSourceStart = modifierPositions; - pushOnAstStack(arg); - - /* if incomplete method header, listLength counter will not have been reset, - indicating that some arguments are available on the stack */ - listLength++; -} -protected void consumeFormalParameterList() { - // FormalParameterList ::= FormalParameterList ',' FormalParameter - optimizedConcatNodeLists(); -} -protected void consumeFormalParameterListopt() { - // FormalParameterListopt ::= $empty - pushOnAstLengthStack(0); -} -protected void consumeImportDeclarations() { - // ImportDeclarations ::= ImportDeclarations ImportDeclaration - optimizedConcatNodeLists(); -} -protected void consumeImportDeclarationsopt() { - // ImportDeclarationsopt ::= ImportDeclarations - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - System.arraycopy( - astStack, - astPtr + 1, - compilationUnit.imports = new ImportReference[length], - 0, - length); - } -} -protected void consumeInstanceOfExpression(int op) { - // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType - //optimize the push/pop - - //by construction, no base type may be used in getTypeReference - Expression exp; - expressionStack[expressionPtr] = exp = - new InstanceOfExpression( - expressionStack[expressionPtr], - getTypeReference(intStack[intPtr--]), - op); - if (exp.sourceEnd == 0) { - //array on base type.... - exp.sourceEnd = scanner.startPosition - 1; - } - //the scanner is on the next token already.... -} -protected void consumeInterfaceDeclaration() { - // see consumeClassDeclaration in case of changes: duplicated code - // InterfaceDeclaration ::= InterfaceHeader InterfaceBody - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - //there are length declarations - //dispatch.....according to the type of the declarations - dispatchDeclarationInto(length); + do { + if (token == TokenNamecase) { + getNextToken(); + expr(); // constant(); + if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { + getNextToken(); + if (token == TokenNamecase || token == TokenNamedefault) { + // empty case statement ? + continue; + } + statementList(); + } + // else if (token == TokenNameSEMICOLON) { + // setMarker( + // "':' expected after 'case' keyword (Found token: " + + // scanner.toStringAction(token) + ")", + // scanner.getCurrentTokenStartPosition(), + // scanner.getCurrentTokenEndPosition(), + // INFO); + // getNextToken(); + // if (token == TokenNamecase) { // empty case statement ? + // continue; + // } + // statementList(); + // } + else { + throwSyntaxError("':' character expected after 'case' constant (Found token: " + scanner.toStringAction(token) + ")"); + } + } else { // TokenNamedefault + getNextToken(); + if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { + getNextToken(); + if (token == TokenNameRBRACE) { + // empty default case + break; + } + if (token != TokenNamecase) { + statementList(); + } + } else { + throwSyntaxError("':' character expected after 'default'."); + } + } + } while (token == TokenNamecase || token == TokenNamedefault); } - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - - // mark fields and initializer with local type mark if needed - markFieldsWithLocalType(typeDecl); - - //convert constructor that do not have the type's name into methods - typeDecl.checkConstructors(this); - - //always add (will be remove at code gen time if empty) - if (this.scanner.containsAssertKeyword) { - typeDecl.bits |= AstNode.AddAssertionMASK; - } - typeDecl.addClinit(); - typeDecl.bodyEnd = endStatementPosition; - typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); -} -protected void consumeInterfaceHeader() { - // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt - - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - if (currentToken == TokenNameLBRACE){ - typeDecl.bodyStart = scanner.currentPosition; - } - if (currentElement != null){ - restartRecovery = true; // used to avoid branching back into the regular automaton - } - // flush the comments related to the interface header - scanner.commentPtr = -1; -} -protected void consumeInterfaceHeaderExtends() { - // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList - int length = astLengthStack[astLengthPtr--]; - //super interfaces - astPtr -= length; - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - System.arraycopy( - astStack, - astPtr + 1, - typeDecl.superInterfaces = new TypeReference[length], - 0, - length); - typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1; - listLength = 0; // reset after having read super-interfaces - // recovery - if (currentElement != null) { - lastCheckPoint = typeDecl.bodyStart; - } -} -protected void consumeInterfaceHeaderName() { - // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier' - TypeDeclaration typeDecl; - if (nestedMethod[nestedType] == 0) { - if (nestedType != 0) { - typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult); + private void ifStatementColon(IfStatement iState) { + // T_IF '(' expr ')' ':' inner_statement_list new_elseif_list + // new_else_single T_ENDIF ';' + HashSet assignedVariableSet = null; + try { + Block b = inner_statement_list(); + iState.thenStatement = b; + checkUnreachable(iState, b); + } finally { + assignedVariableSet = removeIfVariableSet(); + } + if (token == TokenNameelseif) { + try { + pushIfVariableSet(); + new_elseif_list(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null && set != null) { + assignedVariableSet.addAll(set); + } + } + } + try { + pushIfVariableSet(); + new_else_single(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + HashSet topSet = peekVariableSet(); + if (topSet != null) { + if (set != null) { + topSet.addAll(set); + } + topSet.addAll(assignedVariableSet); + } + } + } + if (token != TokenNameendif) { + throwSyntaxError("'endif' expected."); + } + getNextToken(); + if (token != TokenNameSEMICOLON) { + reportSyntaxError("';' expected after if-statement."); + iState.sourceEnd = scanner.getCurrentTokenStartPosition(); } else { - typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); + iState.sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); } - } else { - // Record that the block has a declaration for local types - typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult); - markCurrentMethodWithLocalType(); - blockReal(); - } - - //highlight the name of the type - long pos = identifierPositionStack[identifierPtr]; - typeDecl.sourceEnd = (int) pos; - typeDecl.sourceStart = (int) (pos >>> 32); - typeDecl.name = identifierStack[identifierPtr--]; - identifierLengthPtr--; - - //compute the declaration source too - // 'class' and 'interface' push two int positions: the beginning of the class token and its end. - // we want to keep the beginning position but get rid of the end position - // it is only used for the ClassLiteralAccess positions. - typeDecl.declarationSourceStart = intStack[intPtr--]; - intPtr--; // remove the end position of the class token - typeDecl.modifiersSourceStart = intStack[intPtr--]; - typeDecl.modifiers = intStack[intPtr--]; - if (typeDecl.modifiersSourceStart >= 0) { - typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart; - } - typeDecl.bodyStart = typeDecl.sourceEnd + 1; - pushOnAstStack(typeDecl); - listLength = 0; // will be updated when reading super-interfaces - // recovery - if (currentElement != null){ // is recovering - lastCheckPoint = typeDecl.bodyStart; - currentElement = currentElement.add(typeDecl, 0); - lastIgnoredToken = -1; } -} -protected void consumeInterfaceMemberDeclarations() { - // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration - concatNodeLists(); -} -protected void consumeInterfaceMemberDeclarationsopt() { - // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations - nestedType--; -} -protected void consumeInterfaceType() { - // InterfaceType ::= ClassOrInterfaceType - pushOnAstStack(getTypeReference(0)); - /* if incomplete type header, listLength counter will not have been reset, - indicating that some interfaces are available on the stack */ - listLength++; -} -protected void consumeInterfaceTypeList() { - // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType - optimizedConcatNodeLists(); -} -protected void consumeLeftHandSide() { - // LeftHandSide ::= Name - - pushOnExpressionStack(getUnspecifiedReferenceOptimized()); -} -protected void consumeLeftParen() { - // PushLPAREN ::= '(' - pushOnIntStack(lParenPos); -} -protected void consumeLocalVariableDeclaration() { - // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';' - - /* - astStack : - expressionStack: Expression Expression ...... Expression - identifierStack : type identifier identifier ...... identifier - intStack : typeDim dim dim dim - ==> - astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration - expressionStack : - identifierStack : - intStack : - - */ - int variableDeclaratorsCounter = astLengthStack[astLengthPtr]; - - // update the astStack, astPtr and astLengthStack - int startIndex = astPtr - variablesCounter[nestedType] + 1; - System.arraycopy( - astStack, - startIndex, - astStack, - startIndex - 1, - variableDeclaratorsCounter); - astPtr--; // remove the type reference - astLengthStack[--astLengthPtr] = variableDeclaratorsCounter; - variablesCounter[nestedType] = 0; -} -protected void consumeLocalVariableDeclarationStatement() { - // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';' - // see blockReal in case of change: duplicated code - // increment the amount of declared variables for this block - realBlockStack[realBlockPtr]++; -} -protected void consumeMethodBody() { - // MethodBody ::= NestedMethod '{' BlockStatementsopt '}' - nestedMethod[nestedType] --; -} -protected void consumeMethodDeclaration(boolean isNotAbstract) { - // MethodDeclaration ::= MethodHeader MethodBody - // AbstractMethodDeclaration ::= MethodHeader ';' - /* - astStack : modifiers arguments throws statements - identifierStack : type name - intStack : dim dim dim - ==> - astStack : MethodDeclaration - identifierStack : - intStack : - */ - - int length; - if (isNotAbstract) { - // pop the position of the { (body of the method) pushed in block decl - intPtr--; - } + private void ifStatement(IfStatement iState) { + // T_IF '(' expr ')' statement elseif_list else_single + HashSet assignedVariableSet = null; + try { + pushIfVariableSet(); + Statement s = statement(); + iState.thenStatement = s; + checkUnreachable(iState, s); + } finally { + assignedVariableSet = removeIfVariableSet(); + } - int explicitDeclarations = 0; - Statement[] statements = null; - if (isNotAbstract) { - //statements - explicitDeclarations = realBlockStack[realBlockPtr--]; - if ((length = astLengthStack[astLengthPtr--]) != 0) - System.arraycopy( - astStack, - (astPtr -= length) + 1, - statements = new Statement[length], - 0, - length); + if (token == TokenNameelseif) { + try { + pushIfVariableSet(); + elseif_list(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null && set != null) { + assignedVariableSet.addAll(set); + } + } + } + try { + pushIfVariableSet(); + else_single(iState); + } finally { + HashSet set = removeIfVariableSet(); + if (assignedVariableSet != null) { + HashSet topSet = peekVariableSet(); + if (topSet != null) { + if (set != null) { + topSet.addAll(set); + } + topSet.addAll(assignedVariableSet); + } + } + } } - // now we know that we have a method declaration at the top of the ast stack - MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; - md.statements = statements; - md.explicitDeclarations = explicitDeclarations; - - // cannot be done in consumeMethodHeader because we have no idea whether or not there - // is a body when we reduce the method header - if (!isNotAbstract) { //remember the fact that the method has a semicolon body - md.modifiers |= AccSemicolonBody; - } - // store the endPosition (position just before the '}') in case there is - // a trailing comment behind the end of the method - md.bodyEnd = endPosition; - md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); -} -protected void consumeMethodHeader() { - // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt - // retrieve end position of method declarator - AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr]; - - if (currentToken == TokenNameLBRACE){ - method.bodyStart = scanner.currentPosition; - } - // recovery - if (currentElement != null){ - if (currentToken == TokenNameSEMICOLON){ - method.modifiers |= AccSemicolonBody; - method.declarationSourceEnd = scanner.currentPosition-1; - method.bodyEnd = scanner.currentPosition-1; - if (currentElement.parent != null){ - currentElement = currentElement.parent; - } - } - restartRecovery = true; // used to avoid branching back into the regular automaton - } -} -protected void consumeMethodHeaderExtendedDims() { - // MethodHeaderExtendedDims ::= Dimsopt - // now we update the returnType of the method - MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; - int extendedDims = intStack[intPtr--]; - if (extendedDims != 0) { - TypeReference returnType = md.returnType; - md.sourceEnd = endPosition; - int dims = returnType.dimensions() + extendedDims; - int baseType; - if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) { - //it was a baseType - int sourceStart = returnType.sourceStart; - int sourceEnd = returnType.sourceEnd; - returnType = TypeReference.baseTypeReference(-baseType, dims); - returnType.sourceStart = sourceStart; - returnType.sourceEnd = sourceEnd; - md.returnType = returnType; - } else { - md.returnType = this.copyDims(md.returnType, dims); + private void elseif_list(IfStatement iState) { + // /* empty */ + // | elseif_list T_ELSEIF '(' expr ')' statement + ArrayList conditionList = new ArrayList(); + ArrayList statementList = new ArrayList(); + Expression e; + Statement s; + while (token == TokenNameelseif) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'elseif' keyword."); + } + e = expr(); + conditionList.add(e); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'elseif' condition."); + } + s = statement(); + statementList.add(s); + checkUnreachable(iState, s); } - if (currentToken == TokenNameLBRACE){ - md.bodyStart = endPosition + 1; + iState.elseifConditions = new Expression[conditionList.size()]; + iState.elseifStatements = new Statement[statementList.size()]; + conditionList.toArray(iState.elseifConditions); + statementList.toArray(iState.elseifStatements); + } + + private void new_elseif_list(IfStatement iState) { + // /* empty */ + // | new_elseif_list T_ELSEIF '(' expr ')' ':' inner_statement_list + ArrayList conditionList = new ArrayList(); + ArrayList statementList = new ArrayList(); + Expression e; + Block b; + while (token == TokenNameelseif) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'elseif' keyword."); + } + e = expr(); + conditionList.add(e); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'elseif' condition."); + } + if (token == TokenNameCOLON) { + getNextToken(); + } else { + throwSyntaxError("':' expected after 'elseif' keyword."); + } + b = inner_statement_list(); + statementList.add(b); + checkUnreachable(iState, b); } - // recovery - if (currentElement != null){ - lastCheckPoint = md.bodyStart; - } - } -} -protected void consumeMethodHeaderName() { - // MethodHeaderName ::= Modifiersopt Type 'Identifier' '(' - MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult); - - //name - md.selector = identifierStack[identifierPtr]; - long selectorSource = identifierPositionStack[identifierPtr--]; - identifierLengthPtr--; - //type - md.returnType = getTypeReference(intStack[intPtr--]); - //modifiers - md.declarationSourceStart = intStack[intPtr--]; - md.modifiers = intStack[intPtr--]; - - //highlight starts at selector start - md.sourceStart = (int) (selectorSource >>> 32); - pushOnAstStack(md); - md.sourceEnd = lParenPos; - md.bodyStart = lParenPos+1; - listLength = 0; // initialize listLength before reading parameters/throws - - // recovery - if (currentElement != null){ - if (currentElement instanceof RecoveredType - //|| md.modifiers != 0 - || (scanner.getLineNumber(md.returnType.sourceStart) - == scanner.getLineNumber(md.sourceStart))){ - lastCheckPoint = md.bodyStart; - currentElement = currentElement.add(md, 0); - lastIgnoredToken = -1; + iState.elseifConditions = new Expression[conditionList.size()]; + iState.elseifStatements = new Statement[statementList.size()]; + conditionList.toArray(iState.elseifConditions); + statementList.toArray(iState.elseifStatements); + } + + private void else_single(IfStatement iState) { + // /* empty */ + // T_ELSE statement + if (token == TokenNameelse) { + getNextToken(); + Statement s = statement(); + iState.elseStatement = s; + checkUnreachable(iState, s); } else { - lastCheckPoint = md.sourceStart; - restartRecovery = true; - } - } -} -protected void consumeMethodHeaderParameters() { - // MethodHeaderParameters ::= FormalParameterListopt ')' - int length = astLengthStack[astLengthPtr--]; - astPtr -= length; - AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr]; - md.sourceEnd = rParenPos; - //arguments - if (length != 0) { - System.arraycopy( - astStack, - astPtr + 1, - md.arguments = new Argument[length], - 0, - length); - } - md.bodyStart = rParenPos+1; - listLength = 0; // reset listLength after having read all parameters - // recovery - if (currentElement != null){ - lastCheckPoint = md.bodyStart; - if (currentElement.parseTree() == md) return; - - // might not have been attached yet - in some constructor scenarii - if (md.isConstructor()){ - if ((length != 0) - || (currentToken == TokenNameLBRACE) - // || (currentToken == TokenNamethrows) - ){ - currentElement = currentElement.add(md, 0); - lastIgnoredToken = -1; - } - } - } -} -protected void consumeMethodHeaderThrowsClause() { - // MethodHeaderThrowsClause ::= 'throws' ClassTypeList - int length = astLengthStack[astLengthPtr--]; - astPtr -= length; - AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr]; - System.arraycopy( - astStack, - astPtr + 1, - md.thrownExceptions = new TypeReference[length], - 0, - length); - md.sourceEnd = md.thrownExceptions[length-1].sourceEnd; - md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1; - listLength = 0; // reset listLength after having read all thrown exceptions - // recovery - if (currentElement != null){ - lastCheckPoint = md.bodyStart; - } -} -protected void consumeMethodInvocationName() { - // MethodInvocation ::= Name '(' ArgumentListopt ')' - - // when the name is only an identifier...we have a message send to "this" (implicit) - - MessageSend m = newMessageSend(); - m.sourceEnd = rParenPos; - m.sourceStart = - (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32); - m.selector = identifierStack[identifierPtr--]; - if (identifierLengthStack[identifierLengthPtr] == 1) { - m.receiver = ThisReference.ThisImplicit; - identifierLengthPtr--; - } else { - identifierLengthStack[identifierLengthPtr]--; - m.receiver = getUnspecifiedReference(); - m.sourceStart = m.receiver.sourceStart; - } - pushOnExpressionStack(m); -} -protected void consumeMethodInvocationPrimary() { - //optimize the push/pop - //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')' - - MessageSend m = newMessageSend(); - m.sourceStart = - (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32); - m.selector = identifierStack[identifierPtr--]; - identifierLengthPtr--; - m.receiver = expressionStack[expressionPtr]; - m.sourceStart = m.receiver.sourceStart; - m.sourceEnd = rParenPos; - expressionStack[expressionPtr] = m; -} -protected void consumeMethodInvocationSuper() { - // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')' - - MessageSend m = newMessageSend(); - m.sourceStart = intStack[intPtr--]; - m.sourceEnd = rParenPos; - m.nameSourcePosition = identifierPositionStack[identifierPtr]; - m.selector = identifierStack[identifierPtr--]; - identifierLengthPtr--; - m.receiver = new SuperReference(m.sourceStart, endPosition); - pushOnExpressionStack(m); -} -protected void consumeMethodPushModifiersHeaderName() { - // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '(' - // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '(' - MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult); - - //name - md.selector = identifierStack[identifierPtr]; - long selectorSource = identifierPositionStack[identifierPtr--]; - identifierLengthPtr--; - - //modifiers - md.declarationSourceStart = intStack[intPtr--]; - md.modifiers = intStack[intPtr--]; - - //type - md.returnType = getTypeReference(intStack[intPtr--]); - - //highlight starts at selector start - md.sourceStart = (int) (selectorSource >>> 32); - pushOnAstStack(md); - md.sourceEnd = lParenPos; - md.bodyStart = lParenPos + 1; - listLength = 0; // initialize listLength before reading parameters/throws - - // recovery - if (currentElement != null) { - lastCheckPoint = md.bodyStart; - currentElement = currentElement.add(md, 0); - lastIgnoredToken = -1; - } -} -protected void consumeModifiers() { - int savedModifiersSourceStart = modifiersSourceStart; - checkAnnotation(); // might update modifiers with AccDeprecated - pushOnIntStack(modifiers); // modifiers - if (modifiersSourceStart >= savedModifiersSourceStart) { - modifiersSourceStart = savedModifiersSourceStart; - } - pushOnIntStack(modifiersSourceStart); - resetModifiers(); -} -protected void consumeNestedMethod() { - // NestedMethod ::= $empty - jumpOverMethodBody(); - nestedMethod[nestedType] ++; - consumeOpenBlock(); -} -protected void consumeNestedType() { - // NestedType ::= $empty - nestedType++; - try { - nestedMethod[nestedType] = 0; - } catch (IndexOutOfBoundsException e) { - //except in test's cases, it should never raise - int oldL = nestedMethod.length; - System.arraycopy(nestedMethod , 0, (nestedMethod = new int[oldL + 30]), 0, oldL); - nestedMethod[nestedType] = 0; - // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection - System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL); - } - variablesCounter[nestedType] = 0; -} -protected void consumeOneDimLoop() { - // OneDimLoop ::= '[' ']' - dimensions++; -} -protected void consumeOnlySynchronized() { - // OnlySynchronized ::= 'synchronized' - pushOnIntStack(this.synchronizedBlockSourceStart); - resetModifiers(); -} -protected void consumeOpenBlock() { - // OpenBlock ::= $empty - - pushOnIntStack(scanner.startPosition); - try { - realBlockStack[++realBlockPtr] = 0; - } catch (IndexOutOfBoundsException e) { - //realBlockPtr is correct - int oldStackLength = realBlockStack.length; - int oldStack[] = realBlockStack; - realBlockStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength); - realBlockStack[realBlockPtr] = 0; - } -} -protected void consumePackageDeclaration() { - // PackageDeclaration ::= 'package' Name ';' - /* build an ImportRef build from the last name - stored in the identifier stack. */ - - ImportReference impt = compilationUnit.currentPackage; - // flush annotations defined prior to import statements - impt.declarationEnd = endStatementPosition; - impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd); -} -protected void consumePackageDeclarationName() { - // PackageDeclarationName ::= 'package' Name - /* build an ImportRef build from the last name - stored in the identifier stack. */ - - ImportReference impt; - int length; - char[][] tokens = - new char[length = identifierLengthStack[identifierLengthPtr--]][]; - identifierPtr -= length; - long[] positions = new long[length]; - System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length); - System.arraycopy( - identifierPositionStack, - identifierPtr--, - positions, - 0, - length); - compilationUnit.currentPackage = - impt = new ImportReference(tokens, positions, true); - - if (currentToken == TokenNameSEMICOLON){ - impt.declarationSourceEnd = scanner.currentPosition - 1; - } else { - impt.declarationSourceEnd = impt.sourceEnd; - } - impt.declarationEnd = impt.declarationSourceEnd; - //endPosition is just before the ; - impt.declarationSourceStart = intStack[intPtr--]; - - // recovery - if (currentElement != null){ - lastCheckPoint = impt.declarationSourceEnd+1; - restartRecovery = true; // used to avoid branching back into the regular automaton - } -} -protected void consumePostfixExpression() { - // PostfixExpression ::= Name - pushOnExpressionStack(getUnspecifiedReferenceOptimized()); -} -protected void consumePrimaryNoNewArray() { - // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN - updateSourcePosition(expressionStack[expressionPtr]); -} -protected void consumePrimaryNoNewArrayArrayType() { - // PrimaryNoNewArray ::= ArrayType '.' 'class' - intPtr--; - pushOnExpressionStack( - new ClassLiteralAccess(intStack[intPtr--], - getTypeReference(intStack[intPtr--]))); -} -protected void consumePrimaryNoNewArrayName() { - // PrimaryNoNewArray ::= Name '.' 'class' - intPtr--; - pushOnExpressionStack( - new ClassLiteralAccess(intStack[intPtr--], - getTypeReference(0))); -} -protected void consumePrimaryNoNewArrayNameSuper() { - // PrimaryNoNewArray ::= Name '.' 'super' - pushOnExpressionStack( - new QualifiedSuperReference( - getTypeReference(0), - intStack[intPtr--], - endPosition)); -} -protected void consumePrimaryNoNewArrayNameThis() { - // PrimaryNoNewArray ::= Name '.' 'this' - pushOnExpressionStack( - new QualifiedThisReference( - getTypeReference(0), - intStack[intPtr--], - endPosition)); -} -protected void consumePrimaryNoNewArrayPrimitiveType() { - // PrimaryNoNewArray ::= PrimitiveType '.' 'class' - intPtr--; - pushOnExpressionStack( - new ClassLiteralAccess(intStack[intPtr--], - getTypeReference(0))); -} -protected void consumePrimaryNoNewArrayThis() { - // PrimaryNoNewArray ::= 'this' - pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition)); -} -protected void consumePrimitiveType() { - // Type ::= PrimitiveType - pushOnIntStack(0); -} -protected void consumePushModifiers() { - if ((modifiers & AccSynchronized) != 0) { - /* remove the starting position of the synchronized keyword - * we don't need it when synchronized is part of the modifiers - */ - intPtr--; - } - pushOnIntStack(modifiers); // modifiers - pushOnIntStack(modifiersSourceStart); - resetModifiers(); -} -protected void consumePushPosition() { - // for source managment purpose - // PushPosition ::= $empty - pushOnIntStack(endPosition); -} -protected void consumeQualifiedName() { - // QualifiedName ::= Name '.' SimpleName - /*back from the recursive loop of QualifiedName. - Updates identifier length into the length stack*/ - - identifierLengthStack[--identifierLengthPtr]++; -} -protected void consumeReferenceType() { - // ReferenceType ::= ClassOrInterfaceType - pushOnIntStack(0); -} -protected void consumeRestoreDiet() { - // RestoreDiet ::= $empty - dietInt--; -} -protected void consumeRightParen() { - // PushRPAREN ::= ')' - pushOnIntStack(rParenPos); -} - // This method is part of an automatic generation : do NOT edit-modify - // This method is part of an automatic generation : do NOT edit-modify - protected void consumeRule(int act) { - switch ( act ) { - case 29 : // System.out.println("Type ::= PrimitiveType"); - consumePrimitiveType(); - break ; - - case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType"); - consumeReferenceType(); - break ; - - case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName"); - consumeQualifiedName(); - break ; - - case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt"); - consumeCompilationUnit(); - break ; - - case 54 : // System.out.println("EnterCompilationUnit ::="); - consumeEnterCompilationUnit(); - break ; - - case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE"); - consumeCatchHeader(); - break ; - - case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration"); - consumeImportDeclarations(); - break ; - - case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); - consumeTypeDeclarations(); - break ; - - case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); - consumePackageDeclaration(); - break ; - - case 72 : // System.out.println("PackageDeclarationName ::= package Name"); - consumePackageDeclarationName(); - break ; - - case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON"); - consumeSingleTypeImportDeclaration(); - break ; - - case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name"); - consumeSingleTypeImportDeclarationName(); - break ; - - case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON"); - consumeTypeImportOnDemandDeclaration(); - break ; - - case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY"); - consumeTypeImportOnDemandDeclarationName(); - break ; - - case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON"); - consumeEmptyTypeDeclaration(); - break ; - - case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); - consumeClassDeclaration(); - break ; - - case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt"); - consumeClassHeader(); - break ; - - case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier"); - consumeClassHeaderName(); - break ; - - case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType"); - consumeClassHeaderExtends(); - break ; - - case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); - consumeClassHeaderImplements(); - break ; - - case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType"); - consumeInterfaceTypeList(); - break ; - - case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType"); - consumeInterfaceType(); - break ; - - case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration"); - consumeClassBodyDeclarations(); - break ; - - case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block"); - consumeClassBodyDeclaration(); - break ; - - case 110 : // System.out.println("Diet ::="); - consumeDiet(); - break ; - - case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block"); - consumeClassBodyDeclaration(); - break ; - - case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON"); - consumeEmptyClassMemberDeclaration(); - break ; - - case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON"); - consumeFieldDeclaration(); - break ; - - case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator"); - consumeVariableDeclarators(); - break ; - - case 124 : // System.out.println("EnterVariable ::="); - consumeEnterVariable(); - break ; - - case 125 : // System.out.println("ExitVariableWithInitialization ::="); - consumeExitVariableWithInitialization(); - break ; - - case 126 : // System.out.println("ExitVariableWithoutInitialization ::="); - consumeExitVariableWithoutInitialization(); - break ; - - case 127 : // System.out.println("ForceNoDiet ::="); - consumeForceNoDiet(); - break ; - - case 128 : // System.out.println("RestoreDiet ::="); - consumeRestoreDiet(); - break ; - - case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); - // set to true to consume a method with a body - consumeMethodDeclaration(true); - break ; - - case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); - // set to false to consume a method without body - consumeMethodDeclaration(false); - break ; - - case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims"); - consumeMethodHeader(); - break ; - - case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters"); - consumeMethodHeader(); - break ; - - case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN"); - consumeMethodPushModifiersHeaderName(); - break ; - - case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN"); - consumeMethodPushModifiersHeaderName(); - break ; - - case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); - consumeMethodHeaderName(); - break ; - - case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN"); - consumeMethodHeaderParameters(); - break ; - - case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); - consumeMethodHeaderExtendedDims(); - break ; - - case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); - consumeMethodHeaderThrowsClause(); - break ; - - case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters..."); - consumeConstructorHeader(); - break ; - - case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); - consumeConstructorHeaderName(); - break ; - - case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter"); - consumeFormalParameterList(); - break ; - - case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId"); - // the boolean is used to know if the modifiers should be reset - consumeFormalParameter(); - break ; - - case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); - consumeClassTypeList(); - break ; - - case 150 : // System.out.println("ClassTypeElt ::= ClassType"); - consumeClassTypeElt(); - break ; - - case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE"); - consumeMethodBody(); - break ; - - case 152 : // System.out.println("NestedMethod ::="); - consumeNestedMethod(); - break ; - - case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block"); - consumeStaticInitializer(); - break ; - - case 154 : // System.out.println("StaticOnly ::= static"); - consumeStaticOnly(); - break ; - - case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody"); - consumeConstructorDeclaration() ; - break ; - - case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); - consumeInvalidConstructorDeclaration() ; - break ; - - case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE"); - consumeConstructorBody(); - break ; - - case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements"); - consumeConstructorBlockStatements(); - break ; - - case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON"); - consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); - break ; - - case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON"); - consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); - break ; - - case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN"); - consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); - break ; - - case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN..."); - consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); - break ; - - case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN..."); - consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); - break ; - - case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN..."); - consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); - break ; - - case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); - consumeInterfaceDeclaration(); - break ; - - case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt"); - consumeInterfaceHeader(); - break ; - - case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier"); - consumeInterfaceHeaderName(); - break ; - - case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); - consumeInterfaceHeaderExtends(); - break ; - - case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations..."); - consumeInterfaceMemberDeclarations(); - break ; - - case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); - consumeEmptyInterfaceMemberDeclaration(); - break ; - - case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration"); - ignoreMethodBody(); - break ; - - case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody"); - ignoreInvalidConstructorDeclaration(true); - break ; - - case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON"); - ignoreInvalidConstructorDeclaration(false); - break ; - - case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE"); - consumeEmptyArrayInitializer(); - break ; - - case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE"); - consumeArrayInitializer(); - break ; - - case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE"); - consumeArrayInitializer(); - break ; - - case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer"); - consumeVariableInitializers(); - break ; - - case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); - consumeBlock(); - break ; - - case 192 : // System.out.println("OpenBlock ::="); - consumeOpenBlock() ; - break ; - - case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement"); - consumeBlockStatements() ; - break ; - - case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration"); - ignoreInterfaceDeclaration(); - break ; - - case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON"); - consumeLocalVariableDeclarationStatement(); - break ; - - case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators"); - consumeLocalVariableDeclaration(); - break ; - - case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators"); - consumeLocalVariableDeclaration(); - break ; - - case 202 : // System.out.println("PushModifiers ::="); - consumePushModifiers(); - break ; - - case 226 : // System.out.println("EmptyStatement ::= SEMICOLON"); - consumeEmptyStatement(); - break ; - - case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement"); - consumeStatementLabel() ; - break ; - - case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf"); - consumeStatementLabel() ; - break ; - - case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); - consumeExpressionStatement(); - break ; - - case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement"); - consumeStatementIfNoElse(); - break ; - - case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else..."); - consumeStatementIfWithElse(); - break ; - - case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf..."); - consumeStatementIfWithElse(); - break ; - - case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock"); - consumeStatementSwitch() ; - break ; - - case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE"); - consumeEmptySwitchBlock() ; - break ; - - case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE"); - consumeSwitchBlock() ; - break ; - - case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement"); - consumeSwitchBlockStatements() ; - break ; - - case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); - consumeSwitchBlockStatement() ; - break ; - - case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); - consumeSwitchLabels() ; - break ; - - case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON"); - consumeCaseLabel(); - break ; - - case 251 : // System.out.println("SwitchLabel ::= default COLON"); - consumeDefaultLabel(); - break ; - - case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement"); - consumeStatementWhile() ; - break ; - - case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf"); - consumeStatementWhile() ; - break ; - - case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON"); - consumeStatementDo() ; - break ; - - case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON..."); - consumeStatementFor() ; - break ; - - case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON"); - consumeStatementFor() ; - break ; - - case 257 : // System.out.println("ForInit ::= StatementExpressionList"); - consumeForInit() ; - break ; - - case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression"); - consumeStatementExpressionList() ; - break ; - - case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON"); - consumeSimpleAssertStatement() ; - break ; - - case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON"); - consumeAssertStatement() ; - break ; - - case 264 : // System.out.println("BreakStatement ::= break SEMICOLON"); - consumeStatementBreak() ; - break ; - - case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON"); - consumeStatementBreakWithLabel() ; - break ; - - case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON"); - consumeStatementContinue() ; - break ; - - case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); - consumeStatementContinueWithLabel() ; - break ; - - case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); - consumeStatementReturn() ; - break ; - - case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); - consumeStatementThrow(); - - break ; - - case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block"); - consumeStatementSynchronized(); - break ; - - case 271 : // System.out.println("OnlySynchronized ::= synchronized"); - consumeOnlySynchronized(); - break ; - - case 272 : // System.out.println("TryStatement ::= try Block Catches"); - consumeStatementTry(false); - break ; - - case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally"); - consumeStatementTry(true); - break ; - - case 275 : // System.out.println("Catches ::= Catches CatchClause"); - consumeCatches(); - break ; - - case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block"); - consumeStatementCatch() ; - break ; - - case 278 : // System.out.println("PushLPAREN ::= LPAREN"); - consumeLeftParen(); - break ; - - case 279 : // System.out.println("PushRPAREN ::= RPAREN"); - consumeRightParen(); - break ; - - case 283 : // System.out.println("PrimaryNoNewArray ::= this"); - consumePrimaryNoNewArrayThis(); - break ; - - case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN"); - consumePrimaryNoNewArray(); - break ; - - case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this"); - consumePrimaryNoNewArrayNameThis(); - break ; - - case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super"); - consumePrimaryNoNewArrayNameSuper(); - break ; - - case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class"); - consumePrimaryNoNewArrayName(); - break ; - - case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class"); - consumePrimaryNoNewArrayArrayType(); - break ; - - case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); - consumePrimaryNoNewArrayPrimitiveType(); - break ; - - case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN"); - consumeAllocationHeader(); - break ; - - case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN..."); - consumeClassInstanceCreationExpression(); - break ; - - case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN..."); - consumeClassInstanceCreationExpressionQualified() ; - break ; - - case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new..."); - consumeClassInstanceCreationExpressionQualified() ; - break ; - - case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); - consumeClassInstanceCreationExpressionName() ; - break ; - - case 299 : // System.out.println("ClassBodyopt ::="); - consumeClassBodyopt(); - break ; - - case 301 : // System.out.println("EnterAnonymousClassBody ::="); - consumeEnterAnonymousClassBody(); - break ; - - case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); - consumeArgumentList(); - break ; - - case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs..."); - consumeArrayCreationExpression(); - break ; - - case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs..."); - consumeArrayCreationExpression(); - break ; - - case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr"); - consumeDimWithOrWithOutExprs(); - break ; - - case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); - consumeDimWithOrWithOutExpr(); - break ; - - case 310 : // System.out.println("Dims ::= DimsLoop"); - consumeDims(); - break ; - - case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); - consumeOneDimLoop(); - break ; - - case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier"); - consumeFieldAccess(false); - break ; - - case 315 : // System.out.println("FieldAccess ::= super DOT Identifier"); - consumeFieldAccess(true); - break ; - - case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); - consumeMethodInvocationName(); - break ; - - case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN"); - consumeMethodInvocationPrimary(); - break ; - - case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN"); - consumeMethodInvocationSuper(); - break ; - - case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); - consumeArrayAccess(true); - break ; - - case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET"); - consumeArrayAccess(false); - break ; - - case 322 : // System.out.println("PostfixExpression ::= Name"); - consumePostfixExpression(); - break ; - - case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); - consumeUnaryExpression(OperatorExpression.PLUS,true); - break ; - - case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS"); - consumeUnaryExpression(OperatorExpression.MINUS,true); - break ; - - case 327 : // System.out.println("PushPosition ::="); - consumePushPosition(); - break ; - - case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.PLUS); - break ; - - case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.MINUS); - break ; - - case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.PLUS,false); - break ; - - case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.MINUS,false); - break ; - - case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.TWIDDLE); - break ; - - case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression"); - consumeUnaryExpression(OperatorExpression.NOT); - break ; - - case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression"); - consumeCastExpression(); - break ; - - case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus"); - consumeCastExpression(); - break ; - - case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus"); - consumeCastExpressionLL1(); - break ; - - case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression"); - consumeBinaryExpression(OperatorExpression.MULTIPLY); - break ; - - case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression"); - consumeBinaryExpression(OperatorExpression.DIVIDE); - break ; - - case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression"); - consumeBinaryExpression(OperatorExpression.REMAINDER); - break ; - - case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression"); - consumeBinaryExpression(OperatorExpression.PLUS); - break ; - - case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression"); - consumeBinaryExpression(OperatorExpression.MINUS); - break ; - - case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression"); - consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); - break ; - - case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression"); - consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); - break ; - - case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression"); - consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); - break ; - - case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression"); - consumeBinaryExpression(OperatorExpression.LESS); - break ; - - case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression"); - consumeBinaryExpression(OperatorExpression.GREATER); - break ; - - case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression"); - consumeBinaryExpression(OperatorExpression.LESS_EQUAL); - break ; - - case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression"); - consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); - break ; - - case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType"); - consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); - break ; - - case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression"); - consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); - break ; - - case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression"); - consumeEqualityExpression(OperatorExpression.NOT_EQUAL); - break ; - - case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); - consumeBinaryExpression(OperatorExpression.AND); - break ; - - case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression"); - consumeBinaryExpression(OperatorExpression.XOR); - break ; - - case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression"); - consumeBinaryExpression(OperatorExpression.OR); - break ; - - case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression"); - consumeBinaryExpression(OperatorExpression.AND_AND); - break ; - - case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression"); - consumeBinaryExpression(OperatorExpression.OR_OR); - break ; - - case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON..."); - consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; - break ; - - case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression"); - consumeAssignment(); - break ; - - case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); - ignoreExpressionAssignment(); - break ; - - case 379 : // System.out.println("LeftHandSide ::= Name"); - consumeLeftHandSide(); - break ; - - case 382 : // System.out.println("AssignmentOperator ::= EQUAL"); - consumeAssignmentOperator(EQUAL); - break ; - - case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); - consumeAssignmentOperator(MULTIPLY); - break ; - - case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); - consumeAssignmentOperator(DIVIDE); - break ; - - case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); - consumeAssignmentOperator(REMAINDER); - break ; - - case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL"); - consumeAssignmentOperator(PLUS); - break ; - - case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL"); - consumeAssignmentOperator(MINUS); - break ; - - case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); - consumeAssignmentOperator(LEFT_SHIFT); - break ; - - case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); - consumeAssignmentOperator(RIGHT_SHIFT); - break ; - - case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); - consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); - break ; - - case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL"); - consumeAssignmentOperator(AND); - break ; - - case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL"); - consumeAssignmentOperator(XOR); - break ; - - case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL"); - consumeAssignmentOperator(OR); - break ; - - case 400 : // System.out.println("Expressionopt ::="); - consumeEmptyExpression(); - break ; - - case 404 : // System.out.println("ImportDeclarationsopt ::="); - consumeEmptyImportDeclarationsopt(); - break ; - - case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations"); - consumeImportDeclarationsopt(); - break ; - - case 406 : // System.out.println("TypeDeclarationsopt ::="); - consumeEmptyTypeDeclarationsopt(); - break ; - - case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations"); - consumeTypeDeclarationsopt(); - break ; - - case 408 : // System.out.println("ClassBodyDeclarationsopt ::="); - consumeEmptyClassBodyDeclarationsopt(); - break ; - - case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations"); - consumeClassBodyDeclarationsopt(); - break ; - - case 410 : // System.out.println("Modifiersopt ::="); - consumeDefaultModifiers(); - break ; - - case 411 : // System.out.println("Modifiersopt ::= Modifiers"); - consumeModifiers(); - break ; - - case 412 : // System.out.println("BlockStatementsopt ::="); - consumeEmptyBlockStatementsopt(); - break ; - - case 414 : // System.out.println("Dimsopt ::="); - consumeEmptyDimsopt(); - break ; - - case 416 : // System.out.println("ArgumentListopt ::="); - consumeEmptyArgumentListopt(); - break ; - - case 420 : // System.out.println("FormalParameterListopt ::="); - consumeFormalParameterListopt(); - break ; - - case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::="); - consumeEmptyInterfaceMemberDeclarationsopt(); - break ; - - case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations"); - consumeInterfaceMemberDeclarationsopt(); - break ; - - case 426 : // System.out.println("NestedType ::="); - consumeNestedType(); - break ; - - case 427 : // System.out.println("ForInitopt ::="); - consumeEmptyForInitopt(); - break ; - - case 429 : // System.out.println("ForUpdateopt ::="); - consumeEmptyForUpdateopt(); - break ; - - case 433 : // System.out.println("Catchesopt ::="); - consumeEmptyCatchesopt(); - break ; - - case 435 : // System.out.println("ArrayInitializeropt ::="); - consumeEmptyArrayInitializeropt(); - break ; - - } - } - - -protected void consumeSimpleAssertStatement() { - // AssertStatement ::= 'assert' Expression ';' - expressionLengthPtr--; - pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--])); -} - -protected void consumeSingleTypeImportDeclaration() { - // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';' - - ImportReference impt = (ImportReference) astStack[astPtr]; - // flush annotations defined prior to import statements - impt.declarationEnd = endStatementPosition; - impt.declarationSourceEnd = - this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd); - - // recovery - if (currentElement != null) { - lastCheckPoint = impt.declarationSourceEnd + 1; - currentElement = currentElement.add(impt, 0); - lastIgnoredToken = -1; - restartRecovery = true; - // used to avoid branching back into the regular automaton - } -} -protected void consumeSingleTypeImportDeclarationName() { - // SingleTypeImportDeclarationName ::= 'import' Name - /* push an ImportRef build from the last name - stored in the identifier stack. */ - - ImportReference impt; - int length; - char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][]; - identifierPtr -= length; - long[] positions = new long[length]; - System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); - System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length); - pushOnAstStack(impt = new ImportReference(tokens, positions, false)); - - if (currentToken == TokenNameSEMICOLON){ - impt.declarationSourceEnd = scanner.currentPosition - 1; - } else { - impt.declarationSourceEnd = impt.sourceEnd; - } - impt.declarationEnd = impt.declarationSourceEnd; - //endPosition is just before the ; - impt.declarationSourceStart = intStack[intPtr--]; - - // recovery - if (currentElement != null){ - lastCheckPoint = impt.declarationSourceEnd+1; - currentElement = currentElement.add(impt, 0); - lastIgnoredToken = -1; - restartRecovery = true; // used to avoid branching back into the regular automaton - } -} -protected void consumeStatementBreak() { - // BreakStatement ::= 'break' ';' - // break pushs a position on intStack in case there is no label - - pushOnAstStack(new Break(null, intStack[intPtr--], endPosition)); -} -protected void consumeStatementBreakWithLabel() { - // BreakStatement ::= 'break' Identifier ';' - // break pushs a position on intStack in case there is no label - - pushOnAstStack( - new Break( - identifierStack[identifierPtr--], - intStack[intPtr--], - endPosition)); - identifierLengthPtr--; -} -protected void consumeStatementCatch() { - // CatchClause ::= 'catch' '(' FormalParameter ')' Block - - //catch are stored directly into the Try - //has they always comes two by two.... - //we remove one entry from the astlengthPtr. - //The construction of the try statement must - //then fetch the catches using 2*i and 2*i + 1 - - astLengthPtr--; - listLength = 0; // reset formalParameter counter (incremented for catch variable) -} -protected void consumeStatementContinue() { - // ContinueStatement ::= 'continue' ';' - // continue pushs a position on intStack in case there is no label - - pushOnAstStack( - new Continue( - null, - intStack[intPtr--], - endPosition)); -} -protected void consumeStatementContinueWithLabel() { - // ContinueStatement ::= 'continue' Identifier ';' - // continue pushs a position on intStack in case there is no label - - pushOnAstStack( - new Continue( - identifierStack[identifierPtr--], - intStack[intPtr--], - endPosition)); - identifierLengthPtr--; -} -protected void consumeStatementDo() { - // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';' - - //the 'while' pushes a value on intStack that we need to remove - intPtr--; - - //optimize the push/pop - Statement action = (Statement) astStack[astPtr]; - if (action instanceof EmptyStatement - && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) { - expressionLengthPtr--; - astStack[astPtr] = - new DoStatement( - expressionStack[expressionPtr--], - null, - intStack[intPtr--], - endPosition); - } else { - expressionLengthPtr--; - astStack[astPtr] = - new DoStatement( - expressionStack[expressionPtr--], - action, - intStack[intPtr--], - endPosition); - } -} -protected void consumeStatementExpressionList() { - // StatementExpressionList ::= StatementExpressionList ',' StatementExpression - concatExpressionLists(); -} -protected void consumeStatementFor() { - // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement - // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf - - int length; - Expression cond = null; - Statement[] inits, updates; - Statement action; - boolean scope = true; - - //statements - astLengthPtr--; // we need to consume it - action = (Statement) astStack[astPtr--]; - if (action instanceof EmptyStatement - && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) { - action = null; + iState.checkUnreachable = false; + } + iState.sourceEnd = scanner.getCurrentTokenStartPosition(); } - //updates are on the expresion stack - if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) { - updates = null; - } else { - expressionPtr -= length; - System.arraycopy( - expressionStack, - expressionPtr + 1, - updates = new Statement[length], - 0, - length); + private void new_else_single(IfStatement iState) { + // /* empty */ + // | T_ELSE ':' inner_statement_list + if (token == TokenNameelse) { + getNextToken(); + if (token == TokenNameCOLON) { + getNextToken(); + } else { + throwSyntaxError("':' expected after 'else' keyword."); + } + Block b = inner_statement_list(); + iState.elseStatement = b; + checkUnreachable(iState, b); + } else { + iState.checkUnreachable = false; + } } - if (expressionLengthStack[expressionLengthPtr--] != 0) - cond = expressionStack[expressionPtr--]; - - //inits may be on two different stacks - if ((length = astLengthStack[astLengthPtr--]) == 0) { - inits = null; - scope = false; - } else { - if (length == -1) { //on expressionStack - scope = false; - length = expressionLengthStack[expressionLengthPtr--]; - expressionPtr -= length; - System.arraycopy( - expressionStack, - expressionPtr + 1, - inits = new Statement[length], - 0, - length); - } else { //on astStack - astPtr -= length; - System.arraycopy( - astStack, - astPtr + 1, - inits = new Statement[length], - 0, - length); - } - }; - if (action instanceof Block) { - pushOnAstStack( - new ForStatement( - inits, - cond, - updates, - action, - scope, - intStack[intPtr--], - endStatementPosition)); - } else { - pushOnAstStack( - new ForStatement( - inits, - cond, - updates, - action, - scope, - intStack[intPtr--], - endPosition)); - } -} -protected void consumeStatementIfNoElse() { - // IfThenStatement ::= 'if' '(' Expression ')' Statement - - //optimize the push/pop - expressionLengthPtr--; - Statement thenStatement = (Statement) astStack[astPtr]; - if (thenStatement instanceof Block) { - astStack[astPtr] = - new IfStatement( - expressionStack[expressionPtr--], - thenStatement, - intStack[intPtr--], - endStatementPosition); - } else if (thenStatement instanceof EmptyStatement) { - astStack[astPtr] = - new IfStatement( - expressionStack[expressionPtr--], - Block.None, - intStack[intPtr--], - endStatementPosition); - } else { - astStack[astPtr] = - new IfStatement( - expressionStack[expressionPtr--], - thenStatement, - intStack[intPtr--], - endStatementPosition); - } -} -protected void consumeStatementIfWithElse() { - // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement - // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf - - astLengthPtr--; // optimized {..., Then, Else } ==> {..., If } - expressionLengthPtr--; - //optimize the push/pop - Statement elseStatement = (Statement) astStack[astPtr--]; - Statement thenStatement = (Statement) astStack[astPtr]; - if (elseStatement instanceof EmptyStatement) { - elseStatement = Block.None; - } - if (thenStatement instanceof EmptyStatement) { - thenStatement = Block.None; - } - if (elseStatement instanceof Block) { - astStack[astPtr] = - new IfStatement( - expressionStack[expressionPtr--], - thenStatement, - elseStatement, - intStack[intPtr--], - endStatementPosition); - } else { - astStack[astPtr] = - new IfStatement( - expressionStack[expressionPtr--], - thenStatement, - elseStatement, - intStack[intPtr--], - endStatementPosition); + private Block inner_statement_list() { + // inner_statement_list inner_statement + // /* empty */ + return statementList(); } -} -protected void consumeStatementLabel() { - // LabeledStatement ::= 'Identifier' ':' Statement - // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf - - //optimize push/pop - - Statement stmt = (Statement) astStack[astPtr]; - if (stmt instanceof EmptyStatement) { - astStack[astPtr] = - new LabeledStatement( - identifierStack[identifierPtr], - Block.None, - (int) (identifierPositionStack[identifierPtr--] >>> 32), - endStatementPosition); - } else { - astStack[astPtr] = - new LabeledStatement( - identifierStack[identifierPtr], - stmt, - (int) (identifierPositionStack[identifierPtr--] >>> 32), - endStatementPosition); - } - identifierLengthPtr--; -} -protected void consumeStatementReturn() { - // ReturnStatement ::= 'return' Expressionopt ';' - // return pushs a position on intStack in case there is no expression - - if (expressionLengthStack[expressionLengthPtr--] != 0) { - pushOnAstStack( - new ReturnStatement( - expressionStack[expressionPtr--], - intStack[intPtr--], - endPosition) - ); - } else { - pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition)); - } -} -protected void consumeStatementSwitch() { - // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock - - //OpenBlock just makes the semantic action blockStart() - //the block is inlined but a scope need to be created - //if some declaration occurs. - - int length; - SwitchStatement s = new SwitchStatement(); - expressionLengthPtr--; - s.testExpression = expressionStack[expressionPtr--]; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - System.arraycopy( - astStack, - astPtr + 1, - s.statements = new Statement[length], - 0, - length); - } - s.explicitDeclarations = realBlockStack[realBlockPtr--]; - pushOnAstStack(s); - intPtr--; // because of OpenBlock - s.sourceStart = intStack[intPtr--]; - s.sourceEnd = endStatementPosition; -} -protected void consumeStatementSynchronized() { - // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block - //optimize the push/pop - - if (astLengthStack[astLengthPtr] == 0) { - astLengthStack[astLengthPtr] = 1; - expressionLengthPtr--; - astStack[++astPtr] = - new SynchronizedStatement( - expressionStack[expressionPtr--], - Block.None, - intStack[intPtr--], - endStatementPosition); - } else { - expressionLengthPtr--; - astStack[astPtr] = - new SynchronizedStatement( - expressionStack[expressionPtr--], - (Block) astStack[astPtr], - intStack[intPtr--], - endStatementPosition); - } - resetModifiers(); -} -protected void consumeStatementThrow() { - // ThrowStatement ::= 'throw' Expression ';' - expressionLengthPtr--; - pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--])); -} -protected void consumeStatementTry(boolean withFinally) { - //TryStatement ::= 'try' Block Catches - //TryStatement ::= 'try' Block Catchesopt Finally - - int length; - TryStatement tryStmt = new TryStatement(); - //finally - if (withFinally) { - astLengthPtr--; - tryStmt.finallyBlock = (Block) astStack[astPtr--]; - } - //catches are handle by two [see statementCatch] - if ((length = astLengthStack[astLengthPtr--]) != 0) { - if (length == 1) { - tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--]}; - tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--]}; + + /** + * @param iState + * @param b + */ + private void checkUnreachable(IfStatement iState, Statement s) { + if (s instanceof Block) { + Block b = (Block) s; + if (b.statements == null || b.statements.length == 0) { + iState.checkUnreachable = false; + } else { + int off = b.statements.length - 1; + if (!(b.statements[off] instanceof ReturnStatement) && !(b.statements[off] instanceof ContinueStatement) + && !(b.statements[off] instanceof BreakStatement)) { + if (!(b.statements[off] instanceof IfStatement) || !((IfStatement) b.statements[off]).checkUnreachable) { + iState.checkUnreachable = false; + } + } + } } else { - Block[] bks = (tryStmt.catchBlocks = new Block[length]); - Argument[] args = (tryStmt.catchArguments = new Argument[length]); - while (length-- > 0) { - bks[length] = (Block) astStack[astPtr--]; - args[length] = (Argument) astStack[astPtr--]; + if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) { + if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) { + iState.checkUnreachable = false; + } } } } - //try - astLengthPtr--; - tryStmt.tryBlock = (Block) astStack[astPtr--]; - - //positions - tryStmt.sourceEnd = endStatementPosition; - tryStmt.sourceStart = intStack[intPtr--]; - pushOnAstStack(tryStmt); -} -protected void consumeStatementWhile() { - // WhileStatement ::= 'while' '(' Expression ')' Statement - // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf - - Statement action = (Statement) astStack[astPtr]; - expressionLengthPtr--; - if (action instanceof Block) { - astStack[astPtr] = - new WhileStatement( - expressionStack[expressionPtr--], - action, - intStack[intPtr--], - endStatementPosition); - } else { - if (action instanceof EmptyStatement - && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) { - astStack[astPtr] = - new WhileStatement( - expressionStack[expressionPtr--], - null, - intStack[intPtr--], - endPosition); + + // private void elseifStatementList() { + // do { + // elseifStatement(); + // switch (token) { + // case TokenNameelse: + // getNextToken(); + // if (token == TokenNameCOLON) { + // getNextToken(); + // if (token != TokenNameendif) { + // statementList(); + // } + // return; + // } else { + // if (token == TokenNameif) { //'else if' + // getNextToken(); + // } else { + // throwSyntaxError("':' expected after 'else'."); + // } + // } + // break; + // case TokenNameelseif: + // getNextToken(); + // break; + // default: + // return; + // } + // } while (true); + // } + + // private void elseifStatement() { + // if (token == TokenNameLPAREN) { + // getNextToken(); + // expr(); + // if (token != TokenNameRPAREN) { + // throwSyntaxError("')' expected in else-if-statement."); + // } + // getNextToken(); + // if (token != TokenNameCOLON) { + // throwSyntaxError("':' expected in else-if-statement."); + // } + // getNextToken(); + // if (token != TokenNameendif) { + // statementList(); + // } + // } + // } + + private void switchStatement() { + if (token == TokenNameCOLON) { + // ':' [labeled-statement-list] 'endswitch' ';' + getNextToken(); + labeledStatementList(); + if (token != TokenNameendswitch) { + throwSyntaxError("'endswitch' expected."); + } + getNextToken(); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after switch-statement."); + } + getNextToken(); } else { - astStack[astPtr] = - new WhileStatement( - expressionStack[expressionPtr--], - action, - intStack[intPtr--], - endPosition); + // '{' [labeled-statement-list] '}' + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in switch statement."); + } + getNextToken(); + if (token != TokenNameRBRACE) { + labeledStatementList(); + } + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in switch statement."); + } + getNextToken(); } } -} -protected void consumeStaticInitializer() { - // StaticInitializer ::= StaticOnly Block - //push an Initializer - //optimize the push/pop - Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic); - astStack[astPtr] = initializer; - initializer.sourceEnd = endStatementPosition; - initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); - nestedMethod[nestedType] --; - initializer.declarationSourceStart = intStack[intPtr--]; - - // recovery - if (currentElement != null){ - lastCheckPoint = initializer.declarationSourceEnd; - currentElement = currentElement.add(initializer, 0); - lastIgnoredToken = -1; - } -} -protected void consumeStaticOnly() { - // StaticOnly ::= 'static' - int savedModifiersSourceStart = modifiersSourceStart; - checkAnnotation(); // might update declaration source start - if (modifiersSourceStart >= savedModifiersSourceStart) { - modifiersSourceStart = savedModifiersSourceStart; - } - pushOnIntStack( - modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition); - jumpOverMethodBody(); - nestedMethod[nestedType]++; - resetModifiers(); - - // recovery - if (currentElement != null){ - recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers - } -} -protected void consumeSwitchBlock() { - // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' - concatNodeLists(); -} -protected void consumeSwitchBlockStatement() { - // SwitchBlockStatement ::= SwitchLabels BlockStatements - concatNodeLists(); -} -protected void consumeSwitchBlockStatements() { - // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement - concatNodeLists(); -} -protected void consumeSwitchLabels() { - // SwitchLabels ::= SwitchLabels SwitchLabel - optimizedConcatNodeLists(); -} -protected void consumeToken(int type) { - /* remember the last consumed value */ - /* try to minimize the number of build values */ - if (scanner.wasNonExternalizedStringLiteral) { - StringLiteral[] literals = this.scanner.nonNLSStrings; - // could not reproduce, but this is the only NPE - // added preventive null check see PR 9035 - if (literals != null) { - for (int i = 0, max = literals.length; i < max; i++) { - problemReporter().nonExternalizedStringLiteral(literals[i]); - } - } - scanner.currentLine = null; - scanner.wasNonExternalizedStringLiteral = false; - } - // clear the commentPtr of the scanner in case we read something different from a modifier - switch(type) { -// case TokenNameabstract : -// case TokenNamestrictfp : -// case TokenNamefinal : -// case TokenNamenative : -// case TokenNameprivate : -// case TokenNameprotected : -// case TokenNamepublic : -// case TokenNametransient : -// case TokenNamevolatile : - case TokenNamestatic : -// case TokenNamesynchronized : - break; - default: - scanner.commentPtr = -1; - } - //System.out.println(scanner.toStringAction(type)); - switch (type) { - case TokenNameIdentifier : - pushIdentifier(); - if (scanner.useAssertAsAnIndentifier) { - long positions = identifierPositionStack[identifierPtr]; - problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions); - } - scanner.commentPtr = -1; - break; -// case TokenNameinterface : -// adjustInterfaceModifiers(); -// //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too.... -// pushOnIntStack(scanner.startPosition); -// pushOnIntStack(scanner.currentPosition - 1); -// scanner.commentPtr = -1; -// break; -// case TokenNameabstract : -// checkAndSetModifiers(AccAbstract); -// break; -// case TokenNamestrictfp : -// checkAndSetModifiers(AccStrictfp); -// break; -// case TokenNamefinal : -// checkAndSetModifiers(AccFinal); -// break; -// case TokenNamenative : -// checkAndSetModifiers(AccNative); -// break; -// case TokenNameprivate : -// checkAndSetModifiers(AccPrivate); -// break; -// case TokenNameprotected : -// checkAndSetModifiers(AccProtected); -// break; -// case TokenNamepublic : -// checkAndSetModifiers(AccPublic); -// break; -// case TokenNametransient : -// checkAndSetModifiers(AccTransient); -// break; -// case TokenNamevolatile : -// checkAndSetModifiers(AccVolatile); -// break; - case TokenNamestatic : - checkAndSetModifiers(AccStatic); - break; -// case TokenNamesynchronized : -// this.synchronizedBlockSourceStart = scanner.startPosition; -// checkAndSetModifiers(AccSynchronized); -// break; -// //============================== -// case TokenNamevoid : -// pushIdentifier(-T_void); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// //push a default dimension while void is not part of the primitive -// //declaration baseType and so takes the place of a type without getting into -// //regular type parsing that generates a dimension on intStack -// case TokenNameboolean : -// pushIdentifier(-T_boolean); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNamebyte : -// pushIdentifier(-T_byte); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNamechar : -// pushIdentifier(-T_char); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNamedouble : -// pushIdentifier(-T_double); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNamefloat : -// pushIdentifier(-T_float); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNameint : -// pushIdentifier(-T_int); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNamelong : -// pushIdentifier(-T_long); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; -// case TokenNameshort : -// pushIdentifier(-T_short); -// pushOnIntStack(scanner.currentPosition - 1); -// pushOnIntStack(scanner.startPosition); -// scanner.commentPtr = -1; -// break; - //============================== - case TokenNameIntegerLiteral : - pushOnExpressionStack( - new IntLiteral( - scanner.getCurrentTokenSource(), - scanner.startPosition, - scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNameLongLiteral : - pushOnExpressionStack( - new LongLiteral( - scanner.getCurrentTokenSource(), - scanner.startPosition, - scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNameFloatingPointLiteral : - pushOnExpressionStack( - new FloatLiteral( - scanner.getCurrentTokenSource(), - scanner.startPosition, - scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNameDoubleLiteral : - pushOnExpressionStack( - new DoubleLiteral( - scanner.getCurrentTokenSource(), - scanner.startPosition, - scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNameCharacterLiteral : - pushOnExpressionStack( - new CharLiteral( - scanner.getCurrentTokenSource(), - scanner.startPosition, - scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNameStringLiteral : - StringLiteral stringLiteral = new StringLiteral( - scanner.getCurrentTokenSourceString(), - scanner.startPosition, - scanner.currentPosition - 1); - pushOnExpressionStack(stringLiteral); - scanner.commentPtr = -1; - break; - case TokenNamefalse : - pushOnExpressionStack( - new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1)); - scanner.commentPtr = -1; - break; - case TokenNametrue : - pushOnExpressionStack( - new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1)); - break; - case TokenNamenull : - pushOnExpressionStack( - new NullLiteral(scanner.startPosition, scanner.currentPosition - 1)); - break; - //============================ -// case TokenNamesuper : -// case TokenNamethis : -// endPosition = scanner.currentPosition - 1; -// pushOnIntStack(scanner.startPosition); -// break; -// case TokenNameassert : -// case TokenNameimport : -// case TokenNamepackage : -// case TokenNamethrow : - case TokenNamenew : - case TokenNamedo : - case TokenNameif : - case TokenNamefor : - case TokenNameswitch : -// case TokenNametry : - case TokenNamewhile : - case TokenNamebreak : - case TokenNamecontinue : - case TokenNamereturn : - case TokenNamecase : - pushOnIntStack(scanner.startPosition); - break; - case TokenNameclass : - pushOnIntStack(scanner.currentPosition - 1); - pushOnIntStack(scanner.startPosition); - break; - case TokenNamedefault : - pushOnIntStack(scanner.startPosition); - pushOnIntStack(scanner.currentPosition - 1); - break; - //let extra semantic action decide when to push - case TokenNameRBRACKET : - case TokenNamePLUS : - case TokenNameMINUS : - case TokenNameNOT : - case TokenNameTWIDDLE : - endPosition = scanner.startPosition; - break; - case TokenNamePLUS_PLUS : - case TokenNameMINUS_MINUS : - endPosition = scanner.startPosition; - endStatementPosition = scanner.currentPosition - 1; - break; - case TokenNameRBRACE: - case TokenNameSEMICOLON : - endStatementPosition = scanner.currentPosition - 1; - endPosition = scanner.startPosition - 1; - //the item is not part of the potential futur expression/statement - break; - // in order to handle ( expression) ////// (cast)expression///// foo(x) - case TokenNameRPAREN : - rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101 - break; - case TokenNameLPAREN : - lParenPos = scanner.startPosition; - break; - // case TokenNameQUESTION : - // case TokenNameCOMMA : - // case TokenNameCOLON : - // case TokenNameEQUAL : - // case TokenNameLBRACKET : - // case TokenNameDOT : - // case TokenNameERROR : - // case TokenNameEOF : - // case TokenNamecase : - // case TokenNamecatch : - // case TokenNameelse : - // case TokenNameextends : - // case TokenNamefinally : - // case TokenNameimplements : - // case TokenNamethrows : - // case TokenNameinstanceof : - // case TokenNameEQUAL_EQUAL : - // case TokenNameLESS_EQUAL : - // case TokenNameGREATER_EQUAL : - // case TokenNameNOT_EQUAL : - // case TokenNameLEFT_SHIFT : - // case TokenNameRIGHT_SHIFT : - // case TokenNameUNSIGNED_RIGHT_SHIFT : - // case TokenNamePLUS_EQUAL : - // case TokenNameMINUS_EQUAL : - // case TokenNameMULTIPLY_EQUAL : - // case TokenNameDIVIDE_EQUAL : - // case TokenNameAND_EQUAL : - // case TokenNameOR_EQUAL : - // case TokenNameXOR_EQUAL : - // case TokenNameREMAINDER_EQUAL : - // case TokenNameLEFT_SHIFT_EQUAL : - // case TokenNameRIGHT_SHIFT_EQUAL : - // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : - // case TokenNameOR_OR : - // case TokenNameAND_AND : - // case TokenNameREMAINDER : - // case TokenNameXOR : - // case TokenNameAND : - // case TokenNameMULTIPLY : - // case TokenNameOR : - // case TokenNameDIVIDE : - // case TokenNameGREATER : - // case TokenNameLESS : - } -} -protected void consumeTypeDeclarations() { - // TypeDeclarations ::= TypeDeclarations TypeDeclaration - concatNodeLists(); -} -protected void consumeTypeDeclarationsopt() { - // TypeDeclarationsopt ::= TypeDeclarations - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length); - } -} -protected void consumeTypeImportOnDemandDeclaration() { - // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';' - - ImportReference impt = (ImportReference) astStack[astPtr]; - // flush annotations defined prior to import statements - impt.declarationEnd = endStatementPosition; - impt.declarationSourceEnd = - this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd); - - // recovery - if (currentElement != null) { - lastCheckPoint = impt.declarationSourceEnd + 1; - currentElement = currentElement.add(impt, 0); - restartRecovery = true; - lastIgnoredToken = -1; - // used to avoid branching back into the regular automaton - } -} -protected void consumeTypeImportOnDemandDeclarationName() { - // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' - /* push an ImportRef build from the last name - stored in the identifier stack. */ - - ImportReference impt; - int length; - char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][]; - identifierPtr -= length; - long[] positions = new long[length]; - System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); - System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length); - pushOnAstStack(impt = new ImportReference(tokens, positions, true)); - - if (currentToken == TokenNameSEMICOLON){ - impt.declarationSourceEnd = scanner.currentPosition - 1; - } else { - impt.declarationSourceEnd = impt.sourceEnd; - } - impt.declarationEnd = impt.declarationSourceEnd; - //endPosition is just before the ; - impt.declarationSourceStart = intStack[intPtr--]; - - // recovery - if (currentElement != null){ - lastCheckPoint = impt.declarationSourceEnd+1; - currentElement = currentElement.add(impt, 0); - lastIgnoredToken = -1; - restartRecovery = true; // used to avoid branching back into the regular automaton - } -} -protected void consumeUnaryExpression(int op) { - // UnaryExpression ::= '+' PushPosition UnaryExpression - // UnaryExpression ::= '-' PushPosition UnaryExpression - // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression - // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression - - //optimize the push/pop - - //handle manually the -2147483648 while it is not a real - //computation of an - and 2147483648 (notice that 2147483648 - //is Integer.MAX_VALUE+1.....) - //Same for -9223372036854775808L ............ - - //intStack have the position of the operator - - Expression r, exp = expressionStack[expressionPtr]; - if (op == MINUS) { - if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) { - r = expressionStack[expressionPtr] = new IntLiteralMinValue(); - } else { - if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) { - r = expressionStack[expressionPtr] = new LongLiteralMinValue(); - } else { - r = expressionStack[expressionPtr] = new UnaryExpression(exp, op); + + private void forStatement() { + if (token == TokenNameCOLON) { + getNextToken(); + statementList(); + if (token != TokenNameendfor) { + throwSyntaxError("'endfor' expected."); } + getNextToken(); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after for-statement."); + } + getNextToken(); + } else { + statement(); } - } else { - r = expressionStack[expressionPtr] = new UnaryExpression(exp, op); } - r.sourceStart = intStack[intPtr--]; - r.sourceEnd = exp.sourceEnd; -} -protected void consumeUnaryExpression(int op, boolean post) { - // PreIncrementExpression ::= '++' PushPosition UnaryExpression - // PreDecrementExpression ::= '--' PushPosition UnaryExpression - - // ++ and -- operators - //optimize the push/pop - - //intStack has the position of the operator when prefix - - Expression leftHandSide = expressionStack[expressionPtr]; - if (leftHandSide instanceof Reference) { - // ++foo()++ is unvalid - if (post) { - expressionStack[expressionPtr] = - new PostfixExpression( - leftHandSide, - IntLiteral.One, - op, - endStatementPosition); + + private void whileStatement() { + // ':' statement-list 'endwhile' ';' + if (token == TokenNameCOLON) { + getNextToken(); + statementList(); + if (token != TokenNameendwhile) { + throwSyntaxError("'endwhile' expected."); + } + getNextToken(); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after while-statement."); + } + getNextToken(); } else { - expressionStack[expressionPtr] = - new PrefixExpression( - leftHandSide, - IntLiteral.One, - op, - intStack[intPtr--]); - } - } else { - //the ++ or the -- is NOT taken into account if code gen proceeds - if (!post) { - intPtr--; - } - problemReporter().invalidUnaryExpression(leftHandSide); - } -} -protected void consumeVariableDeclarators() { - // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator - optimizedConcatNodeLists(); -} -protected void consumeVariableInitializers() { - // VariableInitializers ::= VariableInitializers ',' VariableInitializer - concatExpressionLists(); -} -protected TypeReference copyDims(TypeReference typeRef, int dim) { - return typeRef.copyDims(dim); -} -protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) { - return new FieldDeclaration(null, name, sourceStart, sourceEnd); -} - -protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) { - return new LocalDeclaration(null, name, sourceStart, sourceEnd); -} - -public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) { - - CompilationUnitDeclaration parsedUnit; - boolean old = diet; - try { - diet = true; - parsedUnit = parse(sourceUnit, compilationResult); - } - finally { - diet = old; + statement(); + } } - return parsedUnit; -} -protected void dispatchDeclarationInto(int length) { - /* they are length on astStack that should go into - methods fields constructors lists of the typeDecl - - Return if there is a constructor declaration in the methods declaration */ - - - // Looks for the size of each array . - - if (length == 0) - return; - int[] flag = new int[length + 1]; //plus one -- see - int size1 = 0, size2 = 0, size3 = 0; - for (int i = length - 1; i >= 0; i--) { - AstNode astNode = astStack[astPtr--]; - if (astNode instanceof AbstractMethodDeclaration) { - //methods and constructors have been regrouped into one single list - flag[i] = 3; - size2++; + + private void foreachStatement() { + if (token == TokenNameCOLON) { + getNextToken(); + statementList(); + if (token != TokenNameendforeach) { + throwSyntaxError("'endforeach' expected."); + } + getNextToken(); + if (token != TokenNameSEMICOLON) { + throwSyntaxError("';' expected after foreach-statement."); + } + getNextToken(); } else { - if (astNode instanceof TypeDeclaration) { - flag[i] = 4; - size3++; + statement(); + } + } + + // private void exitStatus() { + // if (token == TokenNameLPAREN) { + // getNextToken(); + // } else { + // throwSyntaxError("'(' expected in 'exit-status'."); + // } + // if (token != TokenNameRPAREN) { + // expression(); + // } + // if (token == TokenNameRPAREN) { + // getNextToken(); + // } else { + // throwSyntaxError("')' expected after 'exit-status'."); + // } + // } + private void expressionList() { + do { + expr(); + if (token == TokenNameCOMMA) { + getNextToken(); } else { - //field - flag[i] = 1; - size1++; + break; } + } while (true); + } + + private Expression expr() { + // r_variable + // | expr_without_variable + // if (token!=TokenNameEOF) { + if (Scanner.TRACE) { + System.out.println("TRACE: expr()"); } + return expr_without_variable(true); + // } } - //arrays creation - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - if (size1 != 0) - typeDecl.fields = new FieldDeclaration[size1]; - if (size2 != 0) - typeDecl.methods = new AbstractMethodDeclaration[size2]; - if (size3 != 0) - typeDecl.memberTypes = new MemberTypeDeclaration[size3]; - - //arrays fill up - size1 = size2 = size3 = 0; - int flagI = flag[0], start = 0; - int length2; - for (int end = 0; end <= length; end++) // the plus one allows to - { - if (flagI != flag[end]) //treat the last element as a ended flag..... - { //array copy - switch (flagI) { - case 1 : - size1 += (length2 = end - start); - System.arraycopy( - astStack, - astPtr + start + 1, - typeDecl.fields, - size1 - length2, - length2); + private Expression expr_without_variable(boolean only_variable) { + int exprSourceStart = scanner.getCurrentTokenStartPosition(); + int exprSourceEnd = scanner.getCurrentTokenEndPosition(); + Expression expression = new Expression(); + expression.sourceStart = exprSourceStart; + // default, may be overwritten + expression.sourceEnd = exprSourceEnd; + try { + // internal_functions_in_yacc + // | T_CLONE expr + // | T_PRINT expr + // | '(' expr ')' + // | '@' expr + // | '+' expr + // | '-' expr + // | '!' expr + // | '~' expr + // | T_INC rw_variable + // | T_DEC rw_variable + // | T_INT_CAST expr + // | T_DOUBLE_CAST expr + // | T_STRING_CAST expr + // | T_ARRAY_CAST expr + // | T_OBJECT_CAST expr + // | T_BOOL_CAST expr + // | T_UNSET_CAST expr + // | T_EXIT exit_expr + // | scalar + // | T_ARRAY '(' array_pair_list ')' + // | '`' encaps_list '`' + // | T_LIST '(' assignment_list ')' '=' expr + // | T_NEW class_name_reference ctor_arguments + // | variable '=' expr + // | variable '=' '&' variable + // | variable '=' '&' T_NEW class_name_reference ctor_arguments + // | variable T_PLUS_EQUAL expr + // | variable T_MINUS_EQUAL expr + // | variable T_MUL_EQUAL expr + // | variable T_DIV_EQUAL expr + // | variable T_CONCAT_EQUAL expr + // | variable T_MOD_EQUAL expr + // | variable T_AND_EQUAL expr + // | variable T_OR_EQUAL expr + // | variable T_XOR_EQUAL expr + // | variable T_SL_EQUAL expr + // | variable T_SR_EQUAL expr + // | rw_variable T_INC + // | rw_variable T_DEC + // | expr T_BOOLEAN_OR expr + // | expr T_BOOLEAN_AND expr + // | expr T_LOGICAL_OR expr + // | expr T_LOGICAL_AND expr + // | expr T_LOGICAL_XOR expr + // | expr '|' expr + // | expr '&' expr + // | expr '^' expr + // | expr '.' expr + // | expr '+' expr + // | expr '-' expr + // | expr '*' expr + // | expr '/' expr + // | expr '%' expr + // | expr T_SL expr + // | expr T_SR expr + // | expr T_IS_IDENTICAL expr + // | expr T_IS_NOT_IDENTICAL expr + // | expr T_IS_EQUAL expr + // | expr T_IS_NOT_EQUAL expr + // | expr '<' expr + // | expr T_IS_SMALLER_OR_EQUAL expr + // | expr '>' expr + // | expr T_IS_GREATER_OR_EQUAL expr + // | expr T_INSTANCEOF class_name_reference + // | expr '?' expr ':' expr + if (Scanner.TRACE) { + System.out.println("TRACE: expr_without_variable() PART 1"); + } + switch (token) { + case TokenNameisset: + // T_ISSET '(' isset_variables ')' + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'isset'"); + } + getNextToken(); + isset_variables(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'isset'"); + } + getNextToken(); + break; + case TokenNameempty: + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'empty'"); + } + getNextToken(); + variable(true, false); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'empty'"); + } + getNextToken(); + break; + case TokenNameeval: + case TokenNameinclude: + case TokenNameinclude_once: + case TokenNamerequire: + case TokenNamerequire_once: + internal_functions_in_yacc(); + break; + // | '(' expr ')' + case TokenNameLPAREN: + getNextToken(); + expr(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected in expression."); + } + break; + // | T_CLONE expr + // | T_PRINT expr + // | '@' expr + // | '+' expr + // | '-' expr + // | '!' expr + // | '~' expr + // | T_INT_CAST expr + // | T_DOUBLE_CAST expr + // | T_STRING_CAST expr + // | T_ARRAY_CAST expr + // | T_OBJECT_CAST expr + // | T_BOOL_CAST expr + // | T_UNSET_CAST expr + case TokenNameclone: + case TokenNameprint: + case TokenNameAT: + case TokenNamePLUS: + case TokenNameMINUS: + case TokenNameNOT: + case TokenNameTWIDDLE: + case TokenNameintCAST: + case TokenNamedoubleCAST: + case TokenNamestringCAST: + case TokenNamearrayCAST: + case TokenNameobjectCAST: + case TokenNameboolCAST: + case TokenNameunsetCAST: + getNextToken(); + expr(); + break; + case TokenNameexit: + getNextToken(); + exit_expr(); + break; + // scalar: + // T_STRING + // | T_STRING_VARNAME + // | class_constant + // | T_START_HEREDOC encaps_list T_END_HEREDOC + // | '`' encaps_list '`' + // | common_scalar + // | '`' encaps_list '`' + // case TokenNameEncapsedString0: + // scanner.encapsedStringStack.push(new Character('`')); + // getNextToken(); + // try { + // if (token == TokenNameEncapsedString0) { + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString0) { + // throwSyntaxError("\'`\' expected at end of string" + "(Found token: " + + // scanner.toStringAction(token) + " )"); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // // | '\'' encaps_list '\'' + // case TokenNameEncapsedString1: + // scanner.encapsedStringStack.push(new Character('\'')); + // getNextToken(); + // try { + // exprSourceStart = scanner.getCurrentTokenStartPosition(); + // if (token == TokenNameEncapsedString1) { + // expression = new + // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), + // exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString1) { + // throwSyntaxError("\'\'\' expected at end of string" + "(Found token: " + // + scanner.toStringAction(token) + " )"); + // } else { + // expression = new + // StringLiteralSQ(scanner.getCurrentStringLiteralSource(exprSourceStart), + // exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // //| '"' encaps_list '"' + // case TokenNameEncapsedString2: + // scanner.encapsedStringStack.push(new Character('"')); + // getNextToken(); + // try { + // exprSourceStart = scanner.getCurrentTokenStartPosition(); + // if (token == TokenNameEncapsedString2) { + // expression = new + // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), + // exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } else { + // encaps_list(); + // if (token != TokenNameEncapsedString2) { + // throwSyntaxError("'\"' expected at end of string" + "(Found token: " + + // scanner.toStringAction(token) + " )"); + // } else { + // expression = new + // StringLiteralDQ(scanner.getCurrentStringLiteralSource(exprSourceStart), + // exprSourceStart, scanner + // .getCurrentTokenEndPosition()); + // } + // } + // } finally { + // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + case TokenNameStringDoubleQuote: + expression = new StringLiteralDQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); + common_scalar(); + break; + case TokenNameStringSingleQuote: + expression = new StringLiteralSQ(scanner.getCurrentStringLiteralSource(), scanner.getCurrentTokenStartPosition(), scanner + .getCurrentTokenEndPosition()); + common_scalar(); + break; + case TokenNameIntegerLiteral: + case TokenNameDoubleLiteral: + case TokenNameStringInterpolated: + case TokenNameFILE: + case TokenNameLINE: + case TokenNameCLASS_C: + case TokenNameMETHOD_C: + case TokenNameFUNC_C: + common_scalar(); + break; + case TokenNameHEREDOC: + getNextToken(); + break; + case TokenNamearray: + // T_ARRAY '(' array_pair_list ')' + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + break; + } + array_pair_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' or ',' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); + } + getNextToken(); + } else { + throwSyntaxError("'(' expected after keyword 'array'" + "(Found token: " + scanner.toStringAction(token) + ")"); + } + break; + case TokenNamelist: + // | T_LIST '(' assignment_list ')' '=' expr + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + assignment_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after 'list' keyword."); + } + getNextToken(); + if (token != TokenNameEQUAL) { + throwSyntaxError("'=' expected after 'list' keyword."); + } + getNextToken(); + expr(); + } else { + throwSyntaxError("'(' expected after 'list' keyword."); + } + break; + case TokenNamenew: + // | T_NEW class_name_reference ctor_arguments + getNextToken(); + Expression typeRef = class_name_reference(); + ctor_arguments(); + if (typeRef != null) { + expression = typeRef; + } + break; + // | T_INC rw_variable + // | T_DEC rw_variable + case TokenNamePLUS_PLUS: + case TokenNameMINUS_MINUS: + getNextToken(); + rw_variable(); + break; + // | variable '=' expr + // | variable '=' '&' variable + // | variable '=' '&' T_NEW class_name_reference ctor_arguments + // | variable T_PLUS_EQUAL expr + // | variable T_MINUS_EQUAL expr + // | variable T_MUL_EQUAL expr + // | variable T_DIV_EQUAL expr + // | variable T_CONCAT_EQUAL expr + // | variable T_MOD_EQUAL expr + // | variable T_AND_EQUAL expr + // | variable T_OR_EQUAL expr + // | variable T_XOR_EQUAL expr + // | variable T_SL_EQUAL expr + // | variable T_SR_EQUAL expr + // | rw_variable T_INC + // | rw_variable T_DEC + case TokenNameIdentifier: + case TokenNameVariable: + case TokenNameDOLLAR: + Expression lhs = null; + boolean rememberedVar = false; + if (token == TokenNameIdentifier) { + lhs = identifier(true, true); + if (lhs != null) { + expression = lhs; + } + } else { + lhs = variable(true, true); + if (lhs != null) { + expression = lhs; + } + if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL + && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL + && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL + && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL + && token != TokenNameLEFT_SHIFT_EQUAL) { + FieldReference ref = (FieldReference) lhs; + if (!containsVariableSet(ref.token)) { + problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(), + referenceContext, compilationUnit.compilationResult); + addVariableSet(ref.token); + } + } + } + switch (token) { + case TokenNameEQUAL: + if (lhs != null && lhs instanceof FieldReference) { + addVariableSet(((FieldReference) lhs).token); + } + getNextToken(); + if (token == TokenNameAND) { + getNextToken(); + if (token == TokenNamenew) { + // | variable '=' '&' T_NEW class_name_reference + // ctor_arguments + getNextToken(); + SingleTypeReference classRef = class_name_reference(); + ctor_arguments(); + if (classRef != null) { + if (lhs != null && lhs instanceof FieldReference) { + // example: + // $var = & new Object(); + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = classRef; + lhsInfo.typeIdentifier = classRef.token; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } else { + Expression rhs = variable(false, false); + if (rhs != null && rhs instanceof FieldReference && lhs != null && lhs instanceof FieldReference) { + // example: + // $var = &$ref; + if (fMethodVariables != null) { + VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token); + if (rhsInfo != null && rhsInfo.reference != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = rhsInfo.reference; + lhsInfo.typeIdentifier = rhsInfo.typeIdentifier; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } + } else { + Expression rhs = expr(); + if (lhs != null && lhs instanceof FieldReference) { + if (rhs != null && rhs instanceof FieldReference) { + // example: + // $var = $ref; + if (fMethodVariables != null) { + VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token); + if (rhsInfo != null && rhsInfo.reference != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = rhsInfo.reference; + lhsInfo.typeIdentifier = rhsInfo.typeIdentifier; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } else if (rhs != null && rhs instanceof SingleTypeReference) { + // example: + // $var = new Object(); + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + lhsInfo.reference = (SingleTypeReference) rhs; + lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token; + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + rememberedVar = true; + } + } + } + } + if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) { + if (fMethodVariables != null) { + VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart()); + fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo); + } + } + break; + case TokenNamePLUS_EQUAL: + case TokenNameMINUS_EQUAL: + case TokenNameMULTIPLY_EQUAL: + case TokenNameDIVIDE_EQUAL: + case TokenNameDOT_EQUAL: + case TokenNameREMAINDER_EQUAL: + case TokenNameAND_EQUAL: + case TokenNameOR_EQUAL: + case TokenNameXOR_EQUAL: + case TokenNameRIGHT_SHIFT_EQUAL: + case TokenNameLEFT_SHIFT_EQUAL: + if (lhs != null && lhs instanceof FieldReference) { + addVariableSet(((FieldReference) lhs).token); + } + getNextToken(); + expr(); + break; + case TokenNamePLUS_PLUS: + case TokenNameMINUS_MINUS: + getNextToken(); + break; + default: + if (!only_variable) { + throwSyntaxError("Variable expression not allowed (found token '" + scanner.toStringAction(token) + "')."); + } + if (lhs != null) { + expression = lhs; + } + } + break; + default: + if (token != TokenNameINLINE_HTML) { + if (token > TokenNameKEYWORD) { + getNextToken(); + break; + } else { + // System.out.println(scanner.getCurrentTokenStartPosition()); + // System.out.println(scanner.getCurrentTokenEndPosition()); + + throwSyntaxError("Error in expression (found token '" + scanner.toStringAction(token) + "')."); + } + } + return expression; + } + if (Scanner.TRACE) { + System.out.println("TRACE: expr_without_variable() PART 2"); + } + // | expr T_BOOLEAN_OR expr + // | expr T_BOOLEAN_AND expr + // | expr T_LOGICAL_OR expr + // | expr T_LOGICAL_AND expr + // | expr T_LOGICAL_XOR expr + // | expr '|' expr + // | expr '&' expr + // | expr '^' expr + // | expr '.' expr + // | expr '+' expr + // | expr '-' expr + // | expr '*' expr + // | expr '/' expr + // | expr '%' expr + // | expr T_SL expr + // | expr T_SR expr + // | expr T_IS_IDENTICAL expr + // | expr T_IS_NOT_IDENTICAL expr + // | expr T_IS_EQUAL expr + // | expr T_IS_NOT_EQUAL expr + // | expr '<' expr + // | expr T_IS_SMALLER_OR_EQUAL expr + // | expr '>' expr + // | expr T_IS_GREATER_OR_EQUAL expr + while (true) { + switch (token) { + case TokenNameOR_OR: + getNextToken(); + expression = new OR_OR_Expression(expression, expr(), token); break; - case 3 : - size2 += (length2 = end - start); - System.arraycopy( - astStack, - astPtr + start + 1, - typeDecl.methods, - size2 - length2, - length2); + case TokenNameAND_AND: + getNextToken(); + expression = new AND_AND_Expression(expression, expr(), token); break; - case 4 : - size3 += (length2 = end - start); - System.arraycopy( - astStack, - astPtr + start + 1, - typeDecl.memberTypes, - size3 - length2, - length2); + case TokenNameEQUAL_EQUAL: + getNextToken(); + expression = new EqualExpression(expression, expr(), token); break; - }; - flagI = flag[start = end]; + case TokenNameand: + case TokenNameor: + case TokenNamexor: + case TokenNameAND: + case TokenNameOR: + case TokenNameXOR: + case TokenNameDOT: + case TokenNamePLUS: + case TokenNameMINUS: + case TokenNameMULTIPLY: + case TokenNameDIVIDE: + case TokenNameREMAINDER: + case TokenNameLEFT_SHIFT: + case TokenNameRIGHT_SHIFT: + case TokenNameEQUAL_EQUAL_EQUAL: + case TokenNameNOT_EQUAL_EQUAL: + case TokenNameNOT_EQUAL: + case TokenNameLESS: + case TokenNameLESS_EQUAL: + case TokenNameGREATER: + case TokenNameGREATER_EQUAL: + getNextToken(); + expression = new BinaryExpression(expression, expr(), token); + break; + // | expr T_INSTANCEOF class_name_reference + // | expr '?' expr ':' expr + case TokenNameinstanceof: + getNextToken(); + TypeReference classRef = class_name_reference(); + if (classRef != null) { + expression = new InstanceOfExpression(expression, classRef, OperatorIds.INSTANCEOF); + expression.sourceStart = exprSourceStart; + expression.sourceEnd = scanner.getCurrentTokenEndPosition(); + } + break; + case TokenNameQUESTION: + getNextToken(); + Expression valueIfTrue = expr(); + if (token != TokenNameCOLON) { + throwSyntaxError("':' expected in conditional expression."); + } + getNextToken(); + Expression valueIfFalse = expr(); + + expression = new ConditionalExpression(expression, valueIfTrue, valueIfFalse); + break; + default: + return expression; + } + } + } catch (SyntaxError e) { + // try to find next token after expression with errors: + if (token == TokenNameSEMICOLON) { + getNextToken(); + return expression; + } + if (token == TokenNameRBRACE || token == TokenNameRPAREN || token == TokenNameRBRACKET) { + getNextToken(); + return expression; + } + throw e; } } - if (typeDecl.memberTypes != null) { - for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) { - typeDecl.memberTypes[i].enclosingType = typeDecl; + private SingleTypeReference class_name_reference() { + // class_name_reference: + // T_STRING + // | dynamic_class_name_reference + SingleTypeReference ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: class_name_reference()"); + } + if (token == TokenNameIdentifier) { + ref = new SingleTypeReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); + getNextToken(); + } else { + ref = null; + dynamic_class_name_reference(); } + return ref; } -} -protected CompilationUnitDeclaration endParse(int act) { - - this.lastAct = act; - if (currentElement != null){ - currentElement.topElement().updateParseTree(); - if (VERBOSE_RECOVERY){ - System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$ - System.out.println("--------------------------"); //$NON-NLS-1$ - System.out.println(compilationUnit); - System.out.println("----------------------------------"); //$NON-NLS-1$ - } - } else { - if (diet & VERBOSE_RECOVERY){ - System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$ - System.out.println("--------------------------"); //$NON-NLS-1$ - System.out.println(compilationUnit); - System.out.println("----------------------------------"); //$NON-NLS-1$ + private void dynamic_class_name_reference() { + // dynamic_class_name_reference: + // base_variable T_OBJECT_OPERATOR object_property + // dynamic_class_name_variable_properties + // | base_variable + if (Scanner.TRACE) { + System.out.println("TRACE: dynamic_class_name_reference()"); + } + base_variable(true); + if (token == TokenNameMINUS_GREATER) { + getNextToken(); + object_property(); + dynamic_class_name_variable_properties(); } } - if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + + private void dynamic_class_name_variable_properties() { + // dynamic_class_name_variable_properties: + // dynamic_class_name_variable_properties + // dynamic_class_name_variable_property + // | /* empty */ + if (Scanner.TRACE) { + System.out.println("TRACE: dynamic_class_name_variable_properties()"); + } + while (token == TokenNameMINUS_GREATER) { + dynamic_class_name_variable_property(); + } } - return compilationUnit; -} -/* - * Flush annotations defined prior to a given positions. - * - * Note: annotations are stacked in syntactical order - * - * Either answer given , or the end position of a comment line - * immediately following the (same line) - * - * e.g. - * void foo(){ - * } // end of method foo - */ - -public int flushAnnotationsDefinedPriorTo(int position) { - - int lastAnnotationIndex = scanner.commentPtr; - if (lastAnnotationIndex < 0) return position; // no comment - - // compute the index of the first obsolete comment - int index = lastAnnotationIndex; - int validCount = 0; - while (index >= 0){ - int commentEnd = scanner.commentStops[index]; - if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments - if (commentEnd <= position){ - break; + + private void dynamic_class_name_variable_property() { + // dynamic_class_name_variable_property: + // T_OBJECT_OPERATOR object_property + if (Scanner.TRACE) { + System.out.println("TRACE: dynamic_class_name_variable_property()"); + } + if (token == TokenNameMINUS_GREATER) { + getNextToken(); + object_property(); } - index--; - validCount++; } - // if the source at is immediately followed by a line comment, then - // flush this comment and shift to the comment end. - if (validCount > 0){ - int immediateCommentEnd = -scanner.commentStops[index+1]; //non-javadoc comment end positions are negative - if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments - // is there any line break until the end of the immediate comment ? (thus only tolerating line comment) - immediateCommentEnd--; // comment end in one char too far - if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)){ - position = immediateCommentEnd; - validCount--; // flush this comment - index++; + + private void ctor_arguments() { + // ctor_arguments: + // /* empty */ + // | '(' function_call_parameter_list ')' + if (token == TokenNameLPAREN) { + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + return; } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in ctor_arguments."); + } + getNextToken(); } } - // position can be located in the middle of a line break - // this is a bug on Windows platform only. - // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557 - char[] source = scanner.source; - - if ((position < source.length) - && (source[position] == '\r') - && ((position + 1) < source.length) - && (source[position + 1] == '\n')) { - position++; - } - if (index < 0) return position; // no obsolete comment - if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos - System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount); - System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount); + private void assignment_list() { + // assignment_list: + // assignment_list ',' assignment_list_element + // | assignment_list_element + while (true) { + assignment_list_element(); + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } } - scanner.commentPtr = validCount - 1; - return position; -} -public final int getFirstToken() { - // the first token is a virtual token that - // allows the parser to parse several goals - // even if they aren't LALR(1).... - // Goal ::= '++' CompilationUnit - // Goal ::= '--' MethodBody - // Goal ::= '==' ConstructorBody - // -- Initializer - // Goal ::= '>>' StaticInitializer - // Goal ::= '>>' Block - // -- error recovery - // Goal ::= '>>>' Headers - // Goal ::= '*' BlockStatements - // Goal ::= '*' MethodPushModifiersHeader - // -- JDOM - // Goal ::= '&&' FieldDeclaration - // Goal ::= '||' ImportDeclaration - // Goal ::= '?' PackageDeclaration - // Goal ::= '+' TypeDeclaration - // Goal ::= '/' GenericMethodDeclaration - // Goal ::= '&' ClassBodyDeclaration - // -- code snippet - // Goal ::= '%' Expression - // -- completion parser - // Goal ::= '!' ConstructorBlockStatementsopt - // Goal ::= '~' BlockStatementsopt - - return firstToken; -} -/* - * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments. - * The array is a flattened structure: 2*n entries with consecutives start and end positions. - * - * If no JavaDoc is available, then null is answered instead of an empty array. - * - * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45 - */ -public int[] getJavaDocPositions() { - int javadocCount = 0; - for (int i = 0, max = scanner.commentPtr; i <= max; i++){ - // javadoc only (non javadoc comment have negative end positions.) - if (scanner.commentStops[i] > 0){ - javadocCount++; + private void assignment_list_element() { + // assignment_list_element: + // variable + // | T_LIST '(' assignment_list ')' + // | /* empty */ + if (token == TokenNameVariable) { + variable(true, false); + } else if (token == TokenNameDOLLAR) { + variable(false, false); + } else { + if (token == TokenNamelist) { + getNextToken(); + if (token == TokenNameLPAREN) { + getNextToken(); + assignment_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after 'list' keyword."); + } + getNextToken(); + } else { + throwSyntaxError("'(' expected after 'list' keyword."); + } + } } } - if (javadocCount == 0) return null; - int[] positions = new int[2*javadocCount]; - int index = 0; - for (int i = 0, max = scanner.commentPtr; i <= max; i++){ - // javadoc only (non javadoc comment have negative end positions.) - if (scanner.commentStops[i] > 0){ - positions[index++] = scanner.commentStarts[i]; - positions[index++] = scanner.commentStops[i]-1; //stop is one over + private void array_pair_list() { + // array_pair_list: + // /* empty */ + // | non_empty_array_pair_list possible_comma + non_empty_array_pair_list(); + if (token == TokenNameCOMMA) { + getNextToken(); } } - return positions; -} - protected void getMethodBodies(CompilationUnitDeclaration unit) { - //fill the methods bodies in order for the code to be generated - - if (unit == null) return; - - if (unit.ignoreMethodBodies) { - unit.ignoreFurtherInvestigation = true; - return; - // if initial diet parse did not work, no need to dig into method bodies. - } - //real parse of the method.... - this.scanner.setSource( - unit.compilationResult.compilationUnit.getContents()); - if (unit.types != null) { - for (int i = unit.types.length; --i >= 0;) - unit.types[i].parseMethod(this, unit); + private void non_empty_array_pair_list() { + // non_empty_array_pair_list: + // non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr + // | non_empty_array_pair_list ',' expr + // | expr T_DOUBLE_ARROW expr + // | expr + // | non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable + // | non_empty_array_pair_list ',' '&' w_variable + // | expr T_DOUBLE_ARROW '&' w_variable + // | '&' w_variable + while (true) { + if (token == TokenNameAND) { + getNextToken(); + variable(true, false); + } else { + expr(); + if (token == TokenNameAND) { + getNextToken(); + variable(true, false); + } else if (token == TokenNameEQUAL_GREATER) { + getNextToken(); + if (token == TokenNameAND) { + getNextToken(); + variable(true, false); + } else { + expr(); + } + } + } + if (token != TokenNameCOMMA) { + return; + } + getNextToken(); + if (token == TokenNameRPAREN) { + return; + } } } -protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not -This variable is a type reference and dim will be its dimensions*/ - - int length; - TypeReference ref; - if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { - // single variable reference - if (dim == 0) { - ref = - new SingleTypeReference( - identifierStack[identifierPtr], - identifierPositionStack[identifierPtr--]); + + // private void variableList() { + // do { + // variable(); + // if (token == TokenNameCOMMA) { + // getNextToken(); + // } else { + // break; + // } + // } while (true); + // } + private Expression variable_without_objects(boolean lefthandside, boolean ignoreVar) { + // variable_without_objects: + // reference_variable + // | simple_indirect_reference reference_variable + if (Scanner.TRACE) { + System.out.println("TRACE: variable_without_objects()"); + } + while (token == TokenNameDOLLAR) { + getNextToken(); + } + return reference_variable(lefthandside, ignoreVar); + } + + private Expression function_call(boolean lefthandside, boolean ignoreVar) { + // function_call: + // T_STRING '(' function_call_parameter_list ')' + // | class_constant '(' function_call_parameter_list ')' + // | static_member '(' function_call_parameter_list ')' + // | variable_without_objects '(' function_call_parameter_list ')' + char[] defineName = null; + char[] ident = null; + int startPos = 0; + int endPos = 0; + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: function_call()"); + } + if (token == TokenNameIdentifier) { + ident = scanner.getCurrentIdentifierSource(); + defineName = ident; + startPos = scanner.getCurrentTokenStartPosition(); + endPos = scanner.getCurrentTokenEndPosition(); + getNextToken(); + switch (token) { + case TokenNamePAAMAYIM_NEKUDOTAYIM: + // static member: + defineName = null; + getNextToken(); + if (token == TokenNameIdentifier) { + // class _constant + getNextToken(); + } else { + // static member: + variable_without_objects(true, false); + } + break; + } } else { - ref = - new ArrayTypeReference( - identifierStack[identifierPtr], - dim, - identifierPositionStack[identifierPtr--]); - ref.sourceEnd = endPosition; - } - } else { - if (length < 0) { //flag for precompiled type reference on base types - ref = TypeReference.baseTypeReference(-length, dim); - ref.sourceStart = intStack[intPtr--]; - if (dim == 0) { - ref.sourceEnd = intStack[intPtr--]; - } else { - intPtr--; - ref.sourceEnd = endPosition; - } - } else { //Qualified variable reference - char[][] tokens = new char[length][]; - identifierPtr -= length; - long[] positions = new long[length]; - System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); - System.arraycopy( - identifierPositionStack, - identifierPtr + 1, - positions, - 0, - length); - if (dim == 0) { - ref = new QualifiedTypeReference(tokens, positions); - } else { - ref = new ArrayQualifiedTypeReference(tokens, dim, positions); - ref.sourceEnd = endPosition; - } - } - }; - return ref; -} -protected Expression getTypeReference(Expression exp) { - - exp.bits &= ~AstNode.RestrictiveFlagMASK; - exp.bits |= TYPE; - return exp; -} -protected NameReference getUnspecifiedReference() { - /* build a (unspecified) NameReference which may be qualified*/ - - int length; - NameReference ref; - if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) - // single variable reference - ref = - new SingleNameReference( - identifierStack[identifierPtr], - identifierPositionStack[identifierPtr--]); - else - //Qualified variable reference - { - char[][] tokens = new char[length][]; - identifierPtr -= length; - System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); - ref = - new QualifiedNameReference(tokens, - (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart - (int) identifierPositionStack[identifierPtr + length]); // sourceEnd - }; - return ref; -} -protected NameReference getUnspecifiedReferenceOptimized() { - /* build a (unspecified) NameReference which may be qualified - The optimization occurs for qualified reference while we are - certain in this case the last item of the qualified name is - a field access. This optimization is IMPORTANT while it results - that when a NameReference is build, the type checker should always - look for that it is not a type reference */ - - int length; - NameReference ref; - if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) { - // single variable reference - ref = - new SingleNameReference( - identifierStack[identifierPtr], - identifierPositionStack[identifierPtr--]); - ref.bits &= ~AstNode.RestrictiveFlagMASK; - ref.bits |= LOCAL | FIELD; + ref = variable_without_objects(lefthandside, ignoreVar); + } + if (token != TokenNameLPAREN) { + if (defineName != null) { + // does this identifier contain only uppercase characters? + if (defineName.length == 3) { + if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') { + defineName = null; + } + } else if (defineName.length == 4) { + if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') { + defineName = null; + } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') { + defineName = null; + } + } else if (defineName.length == 5) { + if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') { + defineName = null; + } + } + if (defineName != null) { + for (int i = 0; i < defineName.length; i++) { + if (Character.isLowerCase(defineName[i])) { + problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult); + break; + } + } + } + } + } else { + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + return ref; + } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call (" + functionName + ")."); + } + getNextToken(); + } return ref; } - //Qualified-variable-reference - //In fact it is variable-reference DOT field-ref , but it would result in a type - //conflict tha can be only reduce by making a superclass (or inetrface ) between - //nameReference and FiledReference or putting FieldReference under NameReference - //or else..........This optimisation is not really relevant so just leave as it is - - char[][] tokens = new char[length][]; - identifierPtr -= length; - System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length); - ref = new QualifiedNameReference( - tokens, - (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart - (int) identifierPositionStack[identifierPtr + length]); // sourceEnd - ref.bits &= ~AstNode.RestrictiveFlagMASK; - ref.bits |= LOCAL | FIELD; - return ref; -} -public void goForBlockStatementsOrMethodHeaders() { - //tells the scanner to go for block statements or method headers parsing - - firstToken = TokenNameMULTIPLY; - scanner.recordLineSeparator = false; -} -public void goForClassBodyDeclarations() { - //tells the scanner to go for any body declarations parsing - - firstToken = TokenNameAND; - scanner.recordLineSeparator = true; -} -public void goForCompilationUnit(){ - //tells the scanner to go for compilation unit parsing - - firstToken = TokenNamePLUS_PLUS ; - scanner.linePtr = -1; - scanner.recordLineSeparator = true; - scanner.currentLine= null; - scanner.lines= new ArrayList(); -} -public void goForConstructorBody(){ - //tells the scanner to go for compilation unit parsing - - firstToken = TokenNameEQUAL_EQUAL ; - scanner.recordLineSeparator = false; -} -public void goForExpression() { - //tells the scanner to go for an expression parsing - - firstToken = TokenNameREMAINDER; - scanner.recordLineSeparator = false; -} -public void goForFieldDeclaration(){ - //tells the scanner to go for field declaration parsing - - firstToken = TokenNameAND_AND ; - scanner.recordLineSeparator = true; -} -public void goForGenericMethodDeclaration(){ - //tells the scanner to go for generic method declarations parsing - - firstToken = TokenNameDIVIDE; - scanner.recordLineSeparator = true; -} -public void goForHeaders(){ - //tells the scanner to go for headers only parsing - - firstToken = TokenNameUNSIGNED_RIGHT_SHIFT; - scanner.recordLineSeparator = true; -} -public void goForImportDeclaration(){ - //tells the scanner to go for import declaration parsing - - firstToken = TokenNameOR_OR ; - scanner.recordLineSeparator = true; -} -public void goForInitializer(){ - //tells the scanner to go for initializer parsing - - firstToken = TokenNameRIGHT_SHIFT ; - scanner.recordLineSeparator = false; -} -public void goForMethodBody(){ - //tells the scanner to go for method body parsing - - firstToken = TokenNameMINUS_MINUS ; - scanner.recordLineSeparator = false; -} -public void goForPackageDeclaration() { - //tells the scanner to go for package declaration parsing - - firstToken = TokenNameQUESTION; - scanner.recordLineSeparator = true; -} -public void goForTypeDeclaration() { - //tells the scanner to go for type (interface or class) declaration parsing - - firstToken = TokenNamePLUS; - scanner.recordLineSeparator = true; -} -public final static void grammar(){ -/* ---main options -%options ACTION, AN=JavaAction.java, GP=java, -%options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 , -%options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME , - ---error recovering options..... -%options ERROR_MAPS - ---grammar understanding options -%options first follow -%options TRACE=FULL , -%options VERBOSE - ---Usefull macros helping reading/writing semantic actions -$Define -$putCase -/. case $rule_number : // System.out.println("$rule_text"); - ./ - -$break -/. - break ; -./ - --- here it starts really ------------------------------------------ -$Terminals - - Identifier - - abstract assert boolean break byte case catch char class - continue default do double else extends false final finally float - for if implements import instanceof int - interface long native new null package private - protected public return short static strictfp super switch - synchronized this throw throws transient true try void - volatile while - - IntegerLiteral - LongLiteral - FloatingPointLiteral - DoubleLiteral - CharacterLiteral - StringLiteral - - PLUS_PLUS - MINUS_MINUS - EQUAL_EQUAL - LESS_EQUAL - GREATER_EQUAL - NOT_EQUAL - LEFT_SHIFT - RIGHT_SHIFT - UNSIGNED_RIGHT_SHIFT - PLUS_EQUAL - MINUS_EQUAL - MULTIPLY_EQUAL - DIVIDE_EQUAL - AND_EQUAL - OR_EQUAL - XOR_EQUAL - REMAINDER_EQUAL - LEFT_SHIFT_EQUAL - RIGHT_SHIFT_EQUAL - UNSIGNED_RIGHT_SHIFT_EQUAL - OR_OR - AND_AND - PLUS - MINUS - NOT - REMAINDER - XOR - AND - MULTIPLY - OR - TWIDDLE - DIVIDE - GREATER - LESS - LPAREN - RPAREN - LBRACE - RBRACE - LBRACKET - RBRACKET - SEMICOLON - QUESTION - COLON - COMMA - DOT - EQUAL - --- BodyMarker - -$Alias - - '++' ::= PLUS_PLUS - '--' ::= MINUS_MINUS - '==' ::= EQUAL_EQUAL - '<=' ::= LESS_EQUAL - '>=' ::= GREATER_EQUAL - '!=' ::= NOT_EQUAL - '<<' ::= LEFT_SHIFT - '>>' ::= RIGHT_SHIFT - '>>>' ::= UNSIGNED_RIGHT_SHIFT - '+=' ::= PLUS_EQUAL - '-=' ::= MINUS_EQUAL - '*=' ::= MULTIPLY_EQUAL - '/=' ::= DIVIDE_EQUAL - '&=' ::= AND_EQUAL - '|=' ::= OR_EQUAL - '^=' ::= XOR_EQUAL - '%=' ::= REMAINDER_EQUAL - '<<=' ::= LEFT_SHIFT_EQUAL - '>>=' ::= RIGHT_SHIFT_EQUAL - '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL - '||' ::= OR_OR - '&&' ::= AND_AND - - '+' ::= PLUS - '-' ::= MINUS - '!' ::= NOT - '%' ::= REMAINDER - '^' ::= XOR - '&' ::= AND - '*' ::= MULTIPLY - '|' ::= OR - '~' ::= TWIDDLE - '/' ::= DIVIDE - '>' ::= GREATER - '<' ::= LESS - '(' ::= LPAREN - ')' ::= RPAREN - '{' ::= LBRACE - '}' ::= RBRACE - '[' ::= LBRACKET - ']' ::= RBRACKET - ';' ::= SEMICOLON - '?' ::= QUESTION - ':' ::= COLON - ',' ::= COMMA - '.' ::= DOT - '=' ::= EQUAL - -$Start - Goal - -$Rules - -/. // This method is part of an automatic generation : do NOT edit-modify -protected void consumeRule(int act) { - switch ( act ) { -./ - - - -Goal ::= '++' CompilationUnit -Goal ::= '--' MethodBody -Goal ::= '==' ConstructorBody --- Initializer -Goal ::= '>>' StaticInitializer -Goal ::= '>>' Initializer --- error recovery -Goal ::= '>>>' Headers -Goal ::= '*' BlockStatements -Goal ::= '*' MethodPushModifiersHeader -Goal ::= '*' CatchHeader --- JDOM -Goal ::= '&&' FieldDeclaration -Goal ::= '||' ImportDeclaration -Goal ::= '?' PackageDeclaration -Goal ::= '+' TypeDeclaration -Goal ::= '/' GenericMethodDeclaration -Goal ::= '&' ClassBodyDeclaration --- code snippet -Goal ::= '%' Expression --- completion parser -Goal ::= '!' ConstructorBlockStatementsopt -Goal ::= '~' BlockStatementsopt - -Literal -> IntegerLiteral -Literal -> LongLiteral -Literal -> FloatingPointLiteral -Literal -> DoubleLiteral -Literal -> CharacterLiteral -Literal -> StringLiteral -Literal -> null -Literal -> BooleanLiteral -BooleanLiteral -> true -BooleanLiteral -> false - -------------------------------------------------------------- -------------------------------------------------------------- ---a Type results in both a push of its dimension(s) and its name(s). - -Type ::= PrimitiveType - /.$putCase consumePrimitiveType(); $break ./ -Type -> ReferenceType - -PrimitiveType -> NumericType -NumericType -> IntegralType -NumericType -> FloatingPointType - -PrimitiveType -> 'boolean' -PrimitiveType -> 'void' -IntegralType -> 'byte' -IntegralType -> 'short' -IntegralType -> 'int' -IntegralType -> 'long' -IntegralType -> 'char' -FloatingPointType -> 'float' -FloatingPointType -> 'double' - -ReferenceType ::= ClassOrInterfaceType -/.$putCase consumeReferenceType(); $break ./ -ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0 - -ClassOrInterfaceType -> Name - --- --- These rules have been rewritten to avoid some conflicts introduced --- by adding the 1.1 features --- --- ArrayType ::= PrimitiveType '[' ']' --- ArrayType ::= Name '[' ']' --- ArrayType ::= ArrayType '[' ']' --- - -ArrayType ::= PrimitiveType Dims -ArrayType ::= Name Dims - -ClassType -> ClassOrInterfaceType - - --------------------------------------------------------------- --------------------------------------------------------------- - -Name -> SimpleName -Name -> QualifiedName - -SimpleName -> 'Identifier' - -QualifiedName ::= Name '.' SimpleName -/.$putCase consumeQualifiedName(); $break ./ - -CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt -/.$putCase consumeCompilationUnit(); $break ./ - -EnterCompilationUnit ::= $empty -/.$putCase consumeEnterCompilationUnit(); $break ./ - -Headers -> Header -Headers ::= Headers Header - -Header -> ImportDeclaration -Header -> PackageDeclaration -Header -> ClassHeader -Header -> InterfaceHeader -Header -> StaticInitializer -Header -> MethodHeader -Header -> ConstructorHeader -Header -> FieldDeclaration -Header -> AllocationHeader - -CatchHeader ::= 'catch' '(' FormalParameter ')' '{' -/.$putCase consumeCatchHeader(); $break ./ - -ImportDeclarations -> ImportDeclaration -ImportDeclarations ::= ImportDeclarations ImportDeclaration -/.$putCase consumeImportDeclarations(); $break ./ - -TypeDeclarations -> TypeDeclaration -TypeDeclarations ::= TypeDeclarations TypeDeclaration -/.$putCase consumeTypeDeclarations(); $break ./ - -PackageDeclaration ::= PackageDeclarationName ';' -/.$putCase consumePackageDeclaration(); $break ./ - -PackageDeclarationName ::= 'package' Name -/.$putCase consumePackageDeclarationName(); $break ./ - -ImportDeclaration -> SingleTypeImportDeclaration -ImportDeclaration -> TypeImportOnDemandDeclaration - -SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';' -/.$putCase consumeSingleTypeImportDeclaration(); $break ./ - -SingleTypeImportDeclarationName ::= 'import' Name -/.$putCase consumeSingleTypeImportDeclarationName(); $break ./ - -TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';' -/.$putCase consumeTypeImportOnDemandDeclaration(); $break ./ - -TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*' -/.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./ - -TypeDeclaration -> ClassDeclaration -TypeDeclaration -> InterfaceDeclaration --- this declaration in part of a list od declaration and we will --- use and optimized list length calculation process --- thus we decrement the number while it will be incremend..... -TypeDeclaration ::= ';' -/. $putCase consumeEmptyTypeDeclaration(); $break ./ - ---18.7 Only in the LALR(1) Grammar - -Modifiers ::= Modifier -Modifiers ::= Modifiers Modifier - -Modifier -> 'public' -Modifier -> 'protected' -Modifier -> 'private' -Modifier -> 'static' -Modifier -> 'abstract' -Modifier -> 'final' -Modifier -> 'native' -Modifier -> 'synchronized' -Modifier -> 'transient' -Modifier -> 'volatile' -Modifier -> 'strictfp' - ---18.8 Productions from 8: Class Declarations ---ClassModifier ::= --- 'abstract' --- | 'final' --- | 'public' ---18.8.1 Productions from 8.1: Class Declarations - -ClassDeclaration ::= ClassHeader ClassBody -/.$putCase consumeClassDeclaration(); $break ./ - -ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt -/.$putCase consumeClassHeader(); $break ./ - -ClassHeaderName ::= Modifiersopt 'class' 'Identifier' -/.$putCase consumeClassHeaderName(); $break ./ - -ClassHeaderExtends ::= 'extends' ClassType -/.$putCase consumeClassHeaderExtends(); $break ./ - -ClassHeaderImplements ::= 'implements' InterfaceTypeList -/.$putCase consumeClassHeaderImplements(); $break ./ - -InterfaceTypeList -> InterfaceType -InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType -/.$putCase consumeInterfaceTypeList(); $break ./ - -InterfaceType ::= ClassOrInterfaceType -/.$putCase consumeInterfaceType(); $break ./ - -ClassBody ::= '{' ClassBodyDeclarationsopt '}' - -ClassBodyDeclarations ::= ClassBodyDeclaration -ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration -/.$putCase consumeClassBodyDeclarations(); $break ./ - -ClassBodyDeclaration -> ClassMemberDeclaration -ClassBodyDeclaration -> StaticInitializer -ClassBodyDeclaration -> ConstructorDeclaration ---1.1 feature -ClassBodyDeclaration ::= Diet NestedMethod Block -/.$putCase consumeClassBodyDeclaration(); $break ./ -Diet ::= $empty -/.$putCase consumeDiet(); $break./ - -Initializer ::= Diet NestedMethod Block -/.$putCase consumeClassBodyDeclaration(); $break ./ - -ClassMemberDeclaration -> FieldDeclaration -ClassMemberDeclaration -> MethodDeclaration ---1.1 feature -ClassMemberDeclaration -> ClassDeclaration ---1.1 feature -ClassMemberDeclaration -> InterfaceDeclaration - --- Empty declarations are not valid Java ClassMemberDeclarations. --- However, since the current (2/14/97) Java compiler accepts them --- (in fact, some of the official tests contain this erroneous --- syntax) - -GenericMethodDeclaration -> MethodDeclaration -GenericMethodDeclaration -> ConstructorDeclaration - -ClassMemberDeclaration ::= ';' -/.$putCase consumeEmptyClassMemberDeclaration(); $break./ - ---18.8.2 Productions from 8.3: Field Declarations ---VariableModifier ::= --- 'public' --- | 'protected' --- | 'private' --- | 'static' --- | 'final' --- | 'transient' --- | 'volatile' - -FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' -/.$putCase consumeFieldDeclaration(); $break ./ - -VariableDeclarators -> VariableDeclarator -VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator -/.$putCase consumeVariableDeclarators(); $break ./ - -VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization - -VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization - -EnterVariable ::= $empty -/.$putCase consumeEnterVariable(); $break ./ - -ExitVariableWithInitialization ::= $empty -/.$putCase consumeExitVariableWithInitialization(); $break ./ - -ExitVariableWithoutInitialization ::= $empty -/.$putCase consumeExitVariableWithoutInitialization(); $break ./ - -ForceNoDiet ::= $empty -/.$putCase consumeForceNoDiet(); $break ./ -RestoreDiet ::= $empty -/.$putCase consumeRestoreDiet(); $break ./ - -VariableDeclaratorId ::= 'Identifier' Dimsopt - -VariableInitializer -> Expression -VariableInitializer -> ArrayInitializer - ---18.8.3 Productions from 8.4: Method Declarations ---MethodModifier ::= --- 'public' --- | 'protected' --- | 'private' --- | 'static' --- | 'abstract' --- | 'final' --- | 'native' --- | 'synchronized' --- - -MethodDeclaration -> AbstractMethodDeclaration -MethodDeclaration ::= MethodHeader MethodBody -/.$putCase // set to true to consume a method with a body - consumeMethodDeclaration(true); $break ./ - -AbstractMethodDeclaration ::= MethodHeader ';' -/.$putCase // set to false to consume a method without body - consumeMethodDeclaration(false); $break ./ - -MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt -/.$putCase consumeMethodHeader(); $break ./ - -MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt -/.$putCase consumeMethodHeader(); $break ./ - -MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '(' -/.$putCase consumeMethodPushModifiersHeaderName(); $break ./ - -MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '(' -/.$putCase consumeMethodPushModifiersHeaderName(); $break ./ - -MethodHeaderName ::= Modifiersopt Type 'Identifier' '(' -/.$putCase consumeMethodHeaderName(); $break ./ - -MethodHeaderParameters ::= FormalParameterListopt ')' -/.$putCase consumeMethodHeaderParameters(); $break ./ - -MethodHeaderExtendedDims ::= Dimsopt -/.$putCase consumeMethodHeaderExtendedDims(); $break ./ - -MethodHeaderThrowsClause ::= 'throws' ClassTypeList -/.$putCase consumeMethodHeaderThrowsClause(); $break ./ - -ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt -/.$putCase consumeConstructorHeader(); $break ./ - -ConstructorHeaderName ::= Modifiersopt 'Identifier' '(' -/.$putCase consumeConstructorHeaderName(); $break ./ - -FormalParameterList -> FormalParameter -FormalParameterList ::= FormalParameterList ',' FormalParameter -/.$putCase consumeFormalParameterList(); $break ./ - ---1.1 feature -FormalParameter ::= Modifiersopt Type VariableDeclaratorId -/.$putCase // the boolean is used to know if the modifiers should be reset - consumeFormalParameter(); $break ./ - -ClassTypeList -> ClassTypeElt -ClassTypeList ::= ClassTypeList ',' ClassTypeElt -/.$putCase consumeClassTypeList(); $break ./ - -ClassTypeElt ::= ClassType -/.$putCase consumeClassTypeElt(); $break ./ - - -MethodBody ::= NestedMethod '{' BlockStatementsopt '}' -/.$putCase consumeMethodBody(); $break ./ - -NestedMethod ::= $empty -/.$putCase consumeNestedMethod(); $break ./ - ---18.8.4 Productions from 8.5: Static Initializers - -StaticInitializer ::= StaticOnly Block -/.$putCase consumeStaticInitializer(); $break./ - -StaticOnly ::= 'static' -/.$putCase consumeStaticOnly(); $break ./ - ---18.8.5 Productions from 8.6: Constructor Declarations ---ConstructorModifier ::= --- 'public' --- | 'protected' --- | 'private' --- --- -ConstructorDeclaration ::= ConstructorHeader ConstructorBody -/.$putCase consumeConstructorDeclaration() ; $break ./ - --- These rules are added to be able to parse constructors with no body -ConstructorDeclaration ::= ConstructorHeader ';' -/.$putCase consumeInvalidConstructorDeclaration() ; $break ./ - --- the rules ExplicitConstructorInvocationopt has been expanded --- in the rule below in order to make the grammar lalr(1). --- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}' --- Other inlining has occured into the next rule too.... - -ConstructorBody ::= NestedMethod '{' ConstructorBlockStatementsopt '}' -/.$putCase consumeConstructorBody(); $break ./ - -ConstructorBlockStatementsopt -> BlockStatementsopt - -ConstructorBlockStatementsopt -> ExplicitConstructorInvocation - -ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements -/.$putCase consumeConstructorBlockStatements(); $break ./ - -ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./ - -ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./ - ---1.1 feature -ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./ - ---1.1 feature -ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./ - ---1.1 feature -ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./ - ---1.1 feature -ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';' -/.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./ - ---18.9 Productions from 9: Interface Declarations - ---18.9.1 Productions from 9.1: Interface Declarations ---InterfaceModifier ::= --- 'public' --- | 'abstract' --- -InterfaceDeclaration ::= InterfaceHeader InterfaceBody -/.$putCase consumeInterfaceDeclaration(); $break ./ - -InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt -/.$putCase consumeInterfaceHeader(); $break ./ - -InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier' -/.$putCase consumeInterfaceHeaderName(); $break ./ - --- This rule will be used to accept inner local interface and then report a relevant error message -InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody - -InterfaceHeaderExtends ::= 'extends' InterfaceTypeList -/.$putCase consumeInterfaceHeaderExtends(); $break ./ - -InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}' - -InterfaceMemberDeclarations -> InterfaceMemberDeclaration -InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration -/.$putCase consumeInterfaceMemberDeclarations(); $break ./ - ---same as for class members -InterfaceMemberDeclaration ::= ';' -/.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./ - --- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message -InvalidMethodDeclaration -> MethodHeader MethodBody - -InterfaceMemberDeclaration -> ConstantDeclaration -InterfaceMemberDeclaration ::= InvalidMethodDeclaration -/.$putCase ignoreMethodBody(); $break ./ - --- These rules are added to be able to parse constructors inside interface and then report a relevent error message -InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody -/.$putCase ignoreInvalidConstructorDeclaration(true); $break ./ - -InvalidConstructorDeclaration ::= ConstructorHeader ';' -/.$putCase ignoreInvalidConstructorDeclaration(false); $break ./ - -InterfaceMemberDeclaration -> AbstractMethodDeclaration -InterfaceMemberDeclaration -> InvalidConstructorDeclaration - ---1.1 feature -InterfaceMemberDeclaration -> ClassDeclaration ---1.1 feature -InterfaceMemberDeclaration -> InterfaceDeclaration - -ConstantDeclaration -> FieldDeclaration - -ArrayInitializer ::= '{' ,opt '}' -/.$putCase consumeEmptyArrayInitializer(); $break ./ -ArrayInitializer ::= '{' VariableInitializers '}' -/.$putCase consumeArrayInitializer(); $break ./ -ArrayInitializer ::= '{' VariableInitializers , '}' -/.$putCase consumeArrayInitializer(); $break ./ - -VariableInitializers ::= VariableInitializer -VariableInitializers ::= VariableInitializers ',' VariableInitializer -/.$putCase consumeVariableInitializers(); $break ./ - -Block ::= OpenBlock '{' BlockStatementsopt '}' -/.$putCase consumeBlock(); $break ./ -OpenBlock ::= $empty -/.$putCase consumeOpenBlock() ; $break ./ - -BlockStatements -> BlockStatement -BlockStatements ::= BlockStatements BlockStatement -/.$putCase consumeBlockStatements() ; $break ./ - -BlockStatement -> LocalVariableDeclarationStatement -BlockStatement -> Statement ---1.1 feature -BlockStatement -> ClassDeclaration -BlockStatement ::= InvalidInterfaceDeclaration -/.$putCase ignoreInterfaceDeclaration(); $break ./ - -LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';' -/.$putCase consumeLocalVariableDeclarationStatement(); $break ./ - -LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators -/.$putCase consumeLocalVariableDeclaration(); $break ./ - --- 1.1 feature --- The modifiers part of this rule makes the grammar more permissive. --- The only modifier here is final. We put Modifiers to allow multiple modifiers --- This will require to check the validity of the modifier - -LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators -/.$putCase consumeLocalVariableDeclaration(); $break ./ - -PushModifiers ::= $empty -/.$putCase consumePushModifiers(); $break ./ - -Statement -> StatementWithoutTrailingSubstatement -Statement -> LabeledStatement -Statement -> IfThenStatement -Statement -> IfThenElseStatement -Statement -> WhileStatement -Statement -> ForStatement - -StatementNoShortIf -> StatementWithoutTrailingSubstatement -StatementNoShortIf -> LabeledStatementNoShortIf -StatementNoShortIf -> IfThenElseStatementNoShortIf -StatementNoShortIf -> WhileStatementNoShortIf -StatementNoShortIf -> ForStatementNoShortIf - -StatementWithoutTrailingSubstatement -> AssertStatement -StatementWithoutTrailingSubstatement -> Block -StatementWithoutTrailingSubstatement -> EmptyStatement -StatementWithoutTrailingSubstatement -> ExpressionStatement -StatementWithoutTrailingSubstatement -> SwitchStatement -StatementWithoutTrailingSubstatement -> DoStatement -StatementWithoutTrailingSubstatement -> BreakStatement -StatementWithoutTrailingSubstatement -> ContinueStatement -StatementWithoutTrailingSubstatement -> ReturnStatement -StatementWithoutTrailingSubstatement -> SynchronizedStatement -StatementWithoutTrailingSubstatement -> ThrowStatement -StatementWithoutTrailingSubstatement -> TryStatement - -EmptyStatement ::= ';' -/.$putCase consumeEmptyStatement(); $break ./ - -LabeledStatement ::= 'Identifier' ':' Statement -/.$putCase consumeStatementLabel() ; $break ./ - -LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf -/.$putCase consumeStatementLabel() ; $break ./ - -ExpressionStatement ::= StatementExpression ';' -/. $putCase consumeExpressionStatement(); $break ./ - -StatementExpression ::= Assignment -StatementExpression ::= PreIncrementExpression -StatementExpression ::= PreDecrementExpression -StatementExpression ::= PostIncrementExpression -StatementExpression ::= PostDecrementExpression -StatementExpression ::= MethodInvocation -StatementExpression ::= ClassInstanceCreationExpression - -IfThenStatement ::= 'if' '(' Expression ')' Statement -/.$putCase consumeStatementIfNoElse(); $break ./ - -IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement -/.$putCase consumeStatementIfWithElse(); $break ./ - -IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf -/.$putCase consumeStatementIfWithElse(); $break ./ - -SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock -/.$putCase consumeStatementSwitch() ; $break ./ - -SwitchBlock ::= '{' '}' -/.$putCase consumeEmptySwitchBlock() ; $break ./ - -SwitchBlock ::= '{' SwitchBlockStatements '}' -SwitchBlock ::= '{' SwitchLabels '}' -SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' -/.$putCase consumeSwitchBlock() ; $break ./ + // private void function_call_parameter_list() { + // function_call_parameter_list: + // non_empty_function_call_parameter_list { $$ = $1; } + // | /* empty */ + // } + private void non_empty_function_call_parameter_list() { + // non_empty_function_call_parameter_list: + // expr_without_variable + // | variable + // | '&' w_variable + // | non_empty_function_call_parameter_list ',' expr_without_variable + // | non_empty_function_call_parameter_list ',' variable + // | non_empty_function_call_parameter_list ',' '&' w_variable + if (Scanner.TRACE) { + System.out.println("TRACE: non_empty_function_call_parameter_list()"); + } + while (true) { + if (token == TokenNameAND) { + getNextToken(); + w_variable(true); + } else { + // if (token == TokenNameIdentifier || token == + // TokenNameVariable + // || token == TokenNameDOLLAR) { + // variable(); + // } else { + expr_without_variable(true); + // } + } + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } + } -SwitchBlockStatements -> SwitchBlockStatement -SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement -/.$putCase consumeSwitchBlockStatements() ; $break ./ + private void fully_qualified_class_name() { + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + throwSyntaxError("Class name expected."); + } + } -SwitchBlockStatement ::= SwitchLabels BlockStatements -/.$putCase consumeSwitchBlockStatement() ; $break ./ + private void static_member() { + // static_member: + // fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM + // variable_without_objects + if (Scanner.TRACE) { + System.out.println("TRACE: static_member()"); + } + fully_qualified_class_name(); + if (token != TokenNamePAAMAYIM_NEKUDOTAYIM) { + throwSyntaxError("'::' expected after class name (static_member)."); + } + getNextToken(); + variable_without_objects(false, false); + } -SwitchLabels -> SwitchLabel -SwitchLabels ::= SwitchLabels SwitchLabel -/.$putCase consumeSwitchLabels() ; $break ./ + private Expression base_variable_with_function_calls(boolean lefthandside, boolean ignoreVar) { + // base_variable_with_function_calls: + // base_variable + // | function_call + if (Scanner.TRACE) { + System.out.println("TRACE: base_variable_with_function_calls()"); + } + return function_call(lefthandside, ignoreVar); + } -SwitchLabel ::= 'case' ConstantExpression ':' -/. $putCase consumeCaseLabel(); $break ./ + private Expression base_variable(boolean lefthandside) { + // base_variable: + // reference_variable + // | simple_indirect_reference reference_variable + // | static_member + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: base_variable()"); + } + if (token == TokenNameIdentifier) { + static_member(); + } else { + while (token == TokenNameDOLLAR) { + getNextToken(); + } + reference_variable(lefthandside, false); + } + return ref; + } -SwitchLabel ::= 'default' ':' -/. $putCase consumeDefaultLabel(); $break ./ + // private void simple_indirect_reference() { + // // simple_indirect_reference: + // // '$' + // //| simple_indirect_reference '$' + // } + private Expression reference_variable(boolean lefthandside, boolean ignoreVar) { + // reference_variable: + // reference_variable '[' dim_offset ']' + // | reference_variable '{' expr '}' + // | compound_variable + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: reference_variable()"); + } + ref = compound_variable(lefthandside, ignoreVar); + while (true) { + if (token == TokenNameLBRACE) { + ref = null; + getNextToken(); + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in reference variable."); + } + getNextToken(); + } else if (token == TokenNameLBRACKET) { + if (ref != null && ref instanceof FieldReference) { + FieldReference fref = (FieldReference) ref; + addVariableSet(fref.token); + } + ref = null; + getNextToken(); + if (token != TokenNameRBRACKET) { + expr(); + // dim_offset(); + if (token != TokenNameRBRACKET) { + throwSyntaxError("']' expected in reference variable."); + } + } + getNextToken(); + } else { + break; + } + } + return ref; + } -WhileStatement ::= 'while' '(' Expression ')' Statement -/.$putCase consumeStatementWhile() ; $break ./ + private Expression compound_variable(boolean lefthandside, boolean ignoreVar) { + // compound_variable: + // T_VARIABLE + // | '$' '{' expr '}' + if (Scanner.TRACE) { + System.out.println("TRACE: compound_variable()"); + } + if (token == TokenNameVariable) { + if (!lefthandside) { + if (!containsVariableSet()) { + // reportSyntaxError("The local variable " + new + // String(scanner.getCurrentIdentifierSource()) + // + " may not have been initialized"); + problemReporter.uninitializedLocalVariable(new String(scanner.getCurrentIdentifierSource()), scanner + .getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), referenceContext, + compilationUnit.compilationResult); + } + } else { + if (!ignoreVar) { + addVariableSet(); + } + } + FieldReference ref = new FieldReference(scanner.getCurrentIdentifierSource(), scanner.getCurrentTokenStartPosition()); + getNextToken(); + return ref; + } else { + // because of simple_indirect_reference + while (token == TokenNameDOLLAR) { + getNextToken(); + } + if (token != TokenNameLBRACE) { + reportSyntaxError("'{' expected after compound variable token '$'."); + return null; + } + getNextToken(); + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected after compound variable token '$'."); + } + getNextToken(); + } + return null; + } // private void dim_offset() { // // dim_offset: // // /* empty */ + + // // | expr + // expr(); + // } + private void object_property() { + // object_property: + // object_dim_list + // | variable_without_objects + if (Scanner.TRACE) { + System.out.println("TRACE: object_property()"); + } + if (token == TokenNameVariable || token == TokenNameDOLLAR) { + variable_without_objects(false, false); + } else { + object_dim_list(); + } + } -WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf -/.$putCase consumeStatementWhile() ; $break ./ + private void object_dim_list() { + // object_dim_list: + // object_dim_list '[' dim_offset ']' + // | object_dim_list '{' expr '}' + // | variable_name + if (Scanner.TRACE) { + System.out.println("TRACE: object_dim_list()"); + } + variable_name(); + while (true) { + if (token == TokenNameLBRACE) { + getNextToken(); + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in object_dim_list."); + } + getNextToken(); + } else if (token == TokenNameLBRACKET) { + getNextToken(); + if (token == TokenNameRBRACKET) { + getNextToken(); + continue; + } + expr(); + if (token != TokenNameRBRACKET) { + throwSyntaxError("']' expected in object_dim_list."); + } + getNextToken(); + } else { + break; + } + } + } -DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';' -/.$putCase consumeStatementDo() ; $break ./ + private void variable_name() { + // variable_name: + // T_STRING + // | '{' expr '}' + if (Scanner.TRACE) { + System.out.println("TRACE: variable_name()"); + } + if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { + if (token > TokenNameKEYWORD) { + // TODO show a warning "Keyword used as variable" ? + } + getNextToken(); + } else { + if (token != TokenNameLBRACE) { + throwSyntaxError("'{' expected in variable name."); + } + getNextToken(); + expr(); + if (token != TokenNameRBRACE) { + throwSyntaxError("'}' expected in variable name."); + } + getNextToken(); + } + } -ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement -/.$putCase consumeStatementFor() ; $break ./ -ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf -/.$putCase consumeStatementFor() ; $break ./ + private void r_variable() { + variable(false, false); + } ---the minus one allows to avoid a stack-to-stack transfer -ForInit ::= StatementExpressionList -/.$putCase consumeForInit() ; $break ./ -ForInit -> LocalVariableDeclaration + private void w_variable(boolean lefthandside) { + variable(lefthandside, false); + } -ForUpdate -> StatementExpressionList + private void rw_variable() { + variable(false, false); + } -StatementExpressionList -> StatementExpression -StatementExpressionList ::= StatementExpressionList ',' StatementExpression -/.$putCase consumeStatementExpressionList() ; $break ./ + private Expression variable(boolean lefthandside, boolean ignoreVar) { + // variable: + // base_variable_with_function_calls T_OBJECT_OPERATOR + // object_property method_or_not variable_properties + // | base_variable_with_function_calls + Expression ref = base_variable_with_function_calls(lefthandside, ignoreVar); + if (token == TokenNameMINUS_GREATER) { + ref = null; + getNextToken(); + object_property(); + method_or_not(); + variable_properties(); + } + return ref; + } --- 1.4 feature -AssertStatement ::= 'assert' Expression ';' -/.$putCase consumeSimpleAssertStatement() ; $break ./ + private void variable_properties() { + // variable_properties: + // variable_properties variable_property + // | /* empty */ + while (token == TokenNameMINUS_GREATER) { + variable_property(); + } + } -AssertStatement ::= 'assert' Expression ':' Expression ';' -/.$putCase consumeAssertStatement() ; $break ./ - -BreakStatement ::= 'break' ';' -/.$putCase consumeStatementBreak() ; $break ./ + private void variable_property() { + // variable_property: + // T_OBJECT_OPERATOR object_property method_or_not + if (Scanner.TRACE) { + System.out.println("TRACE: variable_property()"); + } + if (token == TokenNameMINUS_GREATER) { + getNextToken(); + object_property(); + method_or_not(); + } else { + throwSyntaxError("'->' expected in variable_property."); + } + } -BreakStatement ::= 'break' Identifier ';' -/.$putCase consumeStatementBreakWithLabel() ; $break ./ + private Expression identifier(boolean lefthandside, boolean ignoreVar) { + // variable: + // base_variable_with_function_calls T_OBJECT_OPERATOR + // object_property method_or_not variable_properties + // | base_variable_with_function_calls + + // Expression ref = function_call(lefthandside, ignoreVar); + + // function_call: + // T_STRING '(' function_call_parameter_list ')' + // | class_constant '(' function_call_parameter_list ')' + // | static_member '(' function_call_parameter_list ')' + // | variable_without_objects '(' function_call_parameter_list ')' + char[] defineName = null; + char[] ident = null; + int startPos = 0; + int endPos = 0; + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: function_call()"); + } + if (token == TokenNameIdentifier) { + ident = scanner.getCurrentIdentifierSource(); + defineName = ident; + startPos = scanner.getCurrentTokenStartPosition(); + endPos = scanner.getCurrentTokenEndPosition(); + getNextToken(); + + if (token == TokenNameEQUAL || token == TokenNamePLUS_EQUAL || token == TokenNameMINUS_EQUAL + || token == TokenNameMULTIPLY_EQUAL || token == TokenNameDIVIDE_EQUAL || token == TokenNameDOT_EQUAL + || token == TokenNameREMAINDER_EQUAL || token == TokenNameAND_EQUAL || token == TokenNameOR_EQUAL + || token == TokenNameXOR_EQUAL || token == TokenNameRIGHT_SHIFT_EQUAL || token == TokenNameLEFT_SHIFT_EQUAL) { + String error = "Assignment operator '" + scanner.toStringAction(token) + "' not allowed after identifier '" + + new String(ident) + "' (use 'define(...)' to define constants)."; + reportSyntaxError(error); + } -ContinueStatement ::= 'continue' ';' -/.$putCase consumeStatementContinue() ; $break ./ + switch (token) { + case TokenNamePAAMAYIM_NEKUDOTAYIM: + // static member: + defineName = null; + getNextToken(); + if (token == TokenNameIdentifier) { + // class _constant + getNextToken(); + } else { + // static member: + variable_without_objects(true, false); + } + break; + } + } else { + ref = variable_without_objects(lefthandside, ignoreVar); + } + if (token != TokenNameLPAREN) { + if (defineName != null) { + // does this identifier contain only uppercase characters? + if (defineName.length == 3) { + if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') { + defineName = null; + } + } else if (defineName.length == 4) { + if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') { + defineName = null; + } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') { + defineName = null; + } + } else if (defineName.length == 5) { + if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') { + defineName = null; + } + } + if (defineName != null) { + for (int i = 0; i < defineName.length; i++) { + if (Character.isLowerCase(defineName[i])) { + problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult); + break; + } + } + } + } + // TODO is this ok ? + // return ref; + // throwSyntaxError("'(' expected in function call."); + } else { + getNextToken(); -ContinueStatement ::= 'continue' Identifier ';' -/.$putCase consumeStatementContinueWithLabel() ; $break ./ + if (token == TokenNameRPAREN) { + getNextToken(); + ref = null; + } else { + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call (" + functionName + ")."); + } + getNextToken(); + } + } + if (token == TokenNameMINUS_GREATER) { + ref = null; + getNextToken(); + object_property(); + method_or_not(); + variable_properties(); + } + return ref; + } -ReturnStatement ::= 'return' Expressionopt ';' -/.$putCase consumeStatementReturn() ; $break ./ + private void method_or_not() { + // method_or_not: + // '(' function_call_parameter_list ')' + // | /* empty */ + if (Scanner.TRACE) { + System.out.println("TRACE: method_or_not()"); + } + if (token == TokenNameLPAREN) { + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + return; + } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected in method_or_not."); + } + getNextToken(); + } + } -ThrowStatement ::= 'throw' Expression ';' -/.$putCase consumeStatementThrow(); -$break ./ + private void exit_expr() { + // /* empty */ + // | '(' ')' + // | '(' expr ')' + if (token != TokenNameLPAREN) { + return; + } + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + return; + } + expr(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'exit'"); + } + getNextToken(); + } + + // private void encaps_list() { + // // encaps_list encaps_var + // // | encaps_list T_STRING + // // | encaps_list T_NUM_STRING + // // | encaps_list T_ENCAPSED_AND_WHITESPACE + // // | encaps_list T_CHARACTER + // // | encaps_list T_BAD_CHARACTER + // // | encaps_list '[' + // // | encaps_list ']' + // // | encaps_list '{' + // // | encaps_list '}' + // // | encaps_list T_OBJECT_OPERATOR + // // | /* empty */ + // while (true) { + // switch (token) { + // case TokenNameSTRING: + // getNextToken(); + // break; + // case TokenNameLBRACE: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameRBRACE: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameLBRACKET: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameRBRACKET: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameMINUS_GREATER: + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // break; + // case TokenNameVariable: + // case TokenNameDOLLAR_LBRACE: + // case TokenNameLBRACE_DOLLAR: + // encaps_var(); + // break; + // default: + // char encapsedChar = ((Character) + // scanner.encapsedStringStack.peek()).charValue(); + // if (encapsedChar == '$') { + // scanner.encapsedStringStack.pop(); + // encapsedChar = ((Character) + // scanner.encapsedStringStack.peek()).charValue(); + // switch (encapsedChar) { + // case '`': + // if (token == TokenNameEncapsedString0) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // case '\'': + // if (token == TokenNameEncapsedString1) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // case '"': + // if (token == TokenNameEncapsedString2) { + // return; + // } + // token = TokenNameSTRING; + // continue; + // } + // } + // return; + // } + // } + // } + + // private void encaps_var() { + // // T_VARIABLE + // // | T_VARIABLE '[' encaps_var_offset ']' + // // | T_VARIABLE T_OBJECT_OPERATOR T_STRING + // // | T_DOLLAR_OPEN_CURLY_BRACES expr '}' + // // | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' + // // | T_CURLY_OPEN variable '}' + // switch (token) { + // case TokenNameVariable: + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // expr(); //encaps_var_offset(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after variable."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // // } + // } else if (token == TokenNameMINUS_GREATER) { + // getNextToken(); + // if (token != TokenNameIdentifier) { + // throwSyntaxError("Identifier expected after '->'."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // // else { + // // // scanner.encapsedStringStack.pop(); + // // int tempToken = TokenNameSTRING; + // // if (!scanner.encapsedStringStack.isEmpty() + // // && (token == TokenNameEncapsedString0 + // // || token == TokenNameEncapsedString1 + // // || token == TokenNameEncapsedString2 || token == + // // TokenNameERROR)) { + // // char encapsedChar = ((Character) + // // scanner.encapsedStringStack.peek()) + // // .charValue(); + // // switch (token) { + // // case TokenNameEncapsedString0 : + // // if (encapsedChar == '`') { + // // tempToken = TokenNameEncapsedString0; + // // } + // // break; + // // case TokenNameEncapsedString1 : + // // if (encapsedChar == '\'') { + // // tempToken = TokenNameEncapsedString1; + // // } + // // break; + // // case TokenNameEncapsedString2 : + // // if (encapsedChar == '"') { + // // tempToken = TokenNameEncapsedString2; + // // } + // // break; + // // case TokenNameERROR : + // // if (scanner.source[scanner.currentPosition - 1] == '\\') { + // // scanner.currentPosition--; + // // getNextToken(); + // // } + // // break; + // // } + // // } + // // token = tempToken; + // // } + // break; + // case TokenNameDOLLAR_LBRACE: + // getNextToken(); + // if (token == TokenNameDOLLAR_LBRACE) { + // encaps_var(); + // } else if (token == TokenNameIdentifier) { + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after '${'."); + // } + // getNextToken(); + // // } + // } + // } else { + // expr(); + // } + // if (token != TokenNameRBRACE) { + // throwSyntaxError("'}' expected."); + // } + // getNextToken(); + // break; + // case TokenNameLBRACE_DOLLAR: + // getNextToken(); + // if (token == TokenNameLBRACE_DOLLAR) { + // encaps_var(); + // } else if (token == TokenNameIdentifier || token > TokenNameKEYWORD) { + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected."); + // } + // getNextToken(); + // // } + // } else if (token == TokenNameMINUS_GREATER) { + // getNextToken(); + // if (token != TokenNameIdentifier && token != TokenNameVariable) { + // throwSyntaxError("String or Variable token expected."); + // } + // getNextToken(); + // if (token == TokenNameLBRACKET) { + // getNextToken(); + // // if (token == TokenNameRBRACKET) { + // // getNextToken(); + // // } else { + // expr(); + // if (token != TokenNameRBRACKET) { + // throwSyntaxError("']' expected after '${'."); + // } + // getNextToken(); + // // } + // } + // } + // // if (token != TokenNameRBRACE) { + // // throwSyntaxError("'}' expected after '{$'."); + // // } + // // // scanner.encapsedStringStack.pop(); + // // getNextToken(); + // } else { + // expr(); + // if (token != TokenNameRBRACE) { + // throwSyntaxError("'}' expected."); + // } + // // scanner.encapsedStringStack.pop(); + // getNextToken(); + // } + // break; + // } + // } + + // private void encaps_var_offset() { + // // T_STRING + // // | T_NUM_STRING + // // | T_VARIABLE + // switch (token) { + // case TokenNameSTRING: + // getNextToken(); + // break; + // case TokenNameIntegerLiteral: + // getNextToken(); + // break; + // case TokenNameVariable: + // getNextToken(); + // break; + // case TokenNameIdentifier: + // getNextToken(); + // break; + // default: + // throwSyntaxError("Variable or String token expected."); + // break; + // } + // } + + private void internal_functions_in_yacc() { + // int start = 0; + switch (token) { + // case TokenNameisset: + // // T_ISSET '(' isset_variables ')' + // getNextToken(); + // if (token != TokenNameLPAREN) { + // throwSyntaxError("'(' expected after keyword 'isset'"); + // } + // getNextToken(); + // isset_variables(); + // if (token != TokenNameRPAREN) { + // throwSyntaxError("')' expected after keyword 'isset'"); + // } + // getNextToken(); + // break; + // case TokenNameempty: + // // T_EMPTY '(' variable ')' + // getNextToken(); + // if (token != TokenNameLPAREN) { + // throwSyntaxError("'(' expected after keyword 'empty'"); + // } + // getNextToken(); + // variable(false); + // if (token != TokenNameRPAREN) { + // throwSyntaxError("')' expected after keyword 'empty'"); + // } + // getNextToken(); + // break; + case TokenNameinclude: + // T_INCLUDE expr + checkFileName(token); + break; + case TokenNameinclude_once: + // T_INCLUDE_ONCE expr + checkFileName(token); + break; + case TokenNameeval: + // T_EVAL '(' expr ')' + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'eval'"); + } + getNextToken(); + expr(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' expected after keyword 'eval'"); + } + getNextToken(); + break; + case TokenNamerequire: + // T_REQUIRE expr + checkFileName(token); + break; + case TokenNamerequire_once: + // T_REQUIRE_ONCE expr + checkFileName(token); + break; + } + } -SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block -/.$putCase consumeStatementSynchronized(); $break ./ -OnlySynchronized ::= 'synchronized' -/.$putCase consumeOnlySynchronized(); $break ./ + /** + * Parse and check the include file name + * + * @param includeToken + */ + private void checkFileName(int includeToken) { + // expr + int start = scanner.getCurrentTokenStartPosition(); + boolean hasLPAREN = false; + getNextToken(); + if (token == TokenNameLPAREN) { + hasLPAREN = true; + getNextToken(); + } + Expression expression = expr(); + if (hasLPAREN) { + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected for keyword '" + scanner.toStringAction(includeToken) + "'"); + } + } + char[] currTokenSource = scanner.getCurrentTokenSource(start); + IFile file = null; + if (scanner.compilationUnit != null) { + IResource resource = scanner.compilationUnit.getResource(); + if (resource != null && resource instanceof IFile) { + file = (IFile) resource; + } + } + char[][] tokens; + tokens = new char[1][]; + tokens[0] = currTokenSource; + ImportReference impt = new ImportReference(tokens, currTokenSource, start, scanner.getCurrentTokenEndPosition(), false); + impt.declarationSourceEnd = impt.sourceEnd; + impt.declarationEnd = impt.declarationSourceEnd; + // endPosition is just before the ; + impt.declarationSourceStart = start; + includesList.add(impt); + + if (expression instanceof StringLiteral) { + StringLiteral literal = (StringLiteral) expression; + char[] includeName = literal.source(); + if (includeName.length == 0) { + reportSyntaxError("Empty filename after keyword '" + scanner.toStringAction(includeToken) + "'", literal.sourceStart, + literal.sourceStart + 1); + } + String includeNameString = new String(includeName); + if (literal instanceof StringLiteralDQ) { + if (includeNameString.indexOf('$') >= 0) { + // assuming that the filename contains a variable => no filename check + return; + } + } + if (includeNameString.startsWith("http://")) { + // assuming external include location + return; + } + if (file != null) { + // check the filename: + // System.out.println(new String(compilationUnit.getFileName())+" - "+ + // expression.toStringExpression()); + IProject project = file.getProject(); + if (project != null) { + IPath path = PHPFileUtil.determineFilePath(includeNameString, file, project); + + if (path == null) { + // SyntaxError: "File: << >> doesn't exist in project." + String[] args = { expression.toStringExpression(), project.getLocation().toString() }; + problemReporter.phpIncludeNotExistWarning(args, literal.sourceStart, literal.sourceEnd, referenceContext, + compilationUnit.compilationResult); + } else { + try { + String filePath = path.toString(); + String ext = file.getRawLocation().getFileExtension(); + int fileExtensionLength = ext == null ? 0 : ext.length() + 1; + + impt.tokens = CharOperation.splitOn('/', filePath.toCharArray(), 0, filePath.length() - fileExtensionLength); + impt.setFile(PHPFileUtil.createFile(path, project)); + } catch (Exception e) { + // the file is outside of the workspace + } + } + } + } + } + } -TryStatement ::= 'try' Block Catches -/.$putCase consumeStatementTry(false); $break ./ -TryStatement ::= 'try' Block Catchesopt Finally -/.$putCase consumeStatementTry(true); $break ./ + private void isset_variables() { + // variable + // | isset_variables ',' + if (token == TokenNameRPAREN) { + throwSyntaxError("Variable expected after keyword 'isset'"); + } + while (true) { + variable(true, false); + if (token == TokenNameCOMMA) { + getNextToken(); + } else { + break; + } + } + } -Catches -> CatchClause -Catches ::= Catches CatchClause -/.$putCase consumeCatches(); $break ./ + private boolean common_scalar() { + // common_scalar: + // T_LNUMBER + // | T_DNUMBER + // | T_CONSTANT_ENCAPSED_STRING + // | T_LINE + // | T_FILE + // | T_CLASS_C + // | T_METHOD_C + // | T_FUNC_C + switch (token) { + case TokenNameIntegerLiteral: + getNextToken(); + return true; + case TokenNameDoubleLiteral: + getNextToken(); + return true; + case TokenNameStringDoubleQuote: + getNextToken(); + return true; + case TokenNameStringSingleQuote: + getNextToken(); + return true; + case TokenNameStringInterpolated: + getNextToken(); + return true; + case TokenNameFILE: + getNextToken(); + return true; + case TokenNameLINE: + getNextToken(); + return true; + case TokenNameCLASS_C: + getNextToken(); + return true; + case TokenNameMETHOD_C: + getNextToken(); + return true; + case TokenNameFUNC_C: + getNextToken(); + return true; + } + return false; + } + + private void scalar() { + // scalar: + // T_STRING + // | T_STRING_VARNAME + // | class_constant + // | common_scalar + // | '"' encaps_list '"' + // | '\'' encaps_list '\'' + // | T_START_HEREDOC encaps_list T_END_HEREDOC + throwSyntaxError("Not yet implemented (scalar)."); + } + + private void static_scalar() { + // static_scalar: /* compile-time evaluated scalars */ + // common_scalar + // | T_STRING + // | '+' static_scalar + // | '-' static_scalar + // | T_ARRAY '(' static_array_pair_list ')' + // | static_class_constant + if (common_scalar()) { + return; + } + switch (token) { + case TokenNameIdentifier: + getNextToken(); + // static_class_constant: + // T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING + if (token == TokenNamePAAMAYIM_NEKUDOTAYIM) { + getNextToken(); + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + throwSyntaxError("Identifier expected after '::' operator."); + } + } + break; + case TokenNameEncapsedString0: + try { + scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + while (scanner.currentCharacter != '`') { + if (scanner.currentCharacter == '\\') { + scanner.currentPosition++; + } + scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + } + getNextToken(); + } catch (IndexOutOfBoundsException e) { + throwSyntaxError("'`' expected at end of static string."); + } + break; + // case TokenNameEncapsedString1: + // try { + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // while (scanner.currentCharacter != '\'') { + // if (scanner.currentCharacter == '\\') { + // scanner.currentPosition++; + // } + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // } + // getNextToken(); + // } catch (IndexOutOfBoundsException e) { + // throwSyntaxError("'\'' expected at end of static string."); + // } + // break; + // case TokenNameEncapsedString2: + // try { + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // while (scanner.currentCharacter != '"') { + // if (scanner.currentCharacter == '\\') { + // scanner.currentPosition++; + // } + // scanner.currentCharacter = scanner.source[scanner.currentPosition++]; + // } + // getNextToken(); + // } catch (IndexOutOfBoundsException e) { + // throwSyntaxError("'\"' expected at end of static string."); + // } + // break; + case TokenNameStringSingleQuote: + getNextToken(); + break; + case TokenNameStringDoubleQuote: + getNextToken(); + break; + case TokenNamePLUS: + getNextToken(); + static_scalar(); + break; + case TokenNameMINUS: + getNextToken(); + static_scalar(); + break; + case TokenNamearray: + getNextToken(); + if (token != TokenNameLPAREN) { + throwSyntaxError("'(' expected after keyword 'array'"); + } + getNextToken(); + if (token == TokenNameRPAREN) { + getNextToken(); + break; + } + non_empty_static_array_pair_list(); + if (token != TokenNameRPAREN) { + throwSyntaxError("')' or ',' expected after keyword 'array'"); + } + getNextToken(); + break; + // case TokenNamenull : + // getNextToken(); + // break; + // case TokenNamefalse : + // getNextToken(); + // break; + // case TokenNametrue : + // getNextToken(); + // break; + default: + throwSyntaxError("Static scalar/constant expected."); + } + } -CatchClause ::= 'catch' '(' FormalParameter ')' Block -/.$putCase consumeStatementCatch() ; $break ./ + private void non_empty_static_array_pair_list() { + // non_empty_static_array_pair_list: + // non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW + // static_scalar + // | non_empty_static_array_pair_list ',' static_scalar + // | static_scalar T_DOUBLE_ARROW static_scalar + // | static_scalar + while (true) { + static_scalar(); + if (token == TokenNameEQUAL_GREATER) { + getNextToken(); + static_scalar(); + } + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + if (token == TokenNameRPAREN) { + break; + } + } + } -Finally ::= 'finally' Block + // public void reportSyntaxError() { //int act, int currentKind, int + // // stateStackTop) { + // /* remember current scanner position */ + // int startPos = scanner.startPosition; + // int currentPos = scanner.currentPosition; + // + // this.checkAndReportBracketAnomalies(problemReporter()); + // /* reset scanner where it was */ + // scanner.startPosition = startPos; + // scanner.currentPosition = currentPos; + // } ---18.12 Productions from 14: Expressions + public static final int RoundBracket = 0; ---for source positionning purpose -PushLPAREN ::= '(' -/.$putCase consumeLeftParen(); $break ./ -PushRPAREN ::= ')' -/.$putCase consumeRightParen(); $break ./ + public static final int SquareBracket = 1; -Primary -> PrimaryNoNewArray -Primary -> ArrayCreationExpression + public static final int CurlyBracket = 2; -PrimaryNoNewArray -> Literal -PrimaryNoNewArray ::= 'this' -/.$putCase consumePrimaryNoNewArrayThis(); $break ./ + public static final int BracketKinds = 3; -PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN -/.$putCase consumePrimaryNoNewArray(); $break ./ + protected int[] nestedMethod; // the ptr is nestedType -PrimaryNoNewArray -> ClassInstanceCreationExpression -PrimaryNoNewArray -> FieldAccess ---1.1 feature -PrimaryNoNewArray ::= Name '.' 'this' -/.$putCase consumePrimaryNoNewArrayNameThis(); $break ./ -PrimaryNoNewArray ::= Name '.' 'super' -/.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./ + protected int nestedType, dimensions; ---1.1 feature ---PrimaryNoNewArray ::= Type '.' 'class' ---inline Type in the previous rule in order to make the grammar LL1 instead --- of LL2. The result is the 3 next rules. -PrimaryNoNewArray ::= Name '.' 'class' -/.$putCase consumePrimaryNoNewArrayName(); $break ./ + // variable set stack + final static int VariableStackIncrement = 10; -PrimaryNoNewArray ::= ArrayType '.' 'class' -/.$putCase consumePrimaryNoNewArrayArrayType(); $break ./ + HashMap fTypeVariables = null; -PrimaryNoNewArray ::= PrimitiveType '.' 'class' -/.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./ + HashMap fMethodVariables = null; -PrimaryNoNewArray -> MethodInvocation -PrimaryNoNewArray -> ArrayAccess + ArrayList fStackUnassigned = new ArrayList(); ---1.1 feature --- --- In Java 1.0 a ClassBody could not appear at all in a --- ClassInstanceCreationExpression. --- + // ast stack + final static int AstStackIncrement = 100; -AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')' -/.$putCase consumeAllocationHeader(); $break ./ + protected int astPtr; -ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt -/.$putCase consumeClassInstanceCreationExpression(); $break ./ ---1.1 feature + protected ASTNode[] astStack = new ASTNode[AstStackIncrement]; -ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt -/.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ + protected int astLengthPtr; ---1.1 feature -ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt -/.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ + protected int[] astLengthStack; -ClassInstanceCreationExpressionName ::= Name '.' -/.$putCase consumeClassInstanceCreationExpressionName() ; $break ./ - -ClassBodyopt ::= $empty --test made using null as contents -/.$putCase consumeClassBodyopt(); $break ./ -ClassBodyopt ::= EnterAnonymousClassBody ClassBody - -EnterAnonymousClassBody ::= $empty -/.$putCase consumeEnterAnonymousClassBody(); $break ./ - -ArgumentList ::= Expression -ArgumentList ::= ArgumentList ',' Expression -/.$putCase consumeArgumentList(); $break ./ - ---Thess rules are re-written in order to be ll1 ---ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer ---ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt ---ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt ---DimExprs ::= DimExpr ---DimExprs ::= DimExprs DimExpr - -ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt -/.$putCase consumeArrayCreationExpression(); $break ./ -ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt -/.$putCase consumeArrayCreationExpression(); $break ./ - -DimWithOrWithOutExprs ::= DimWithOrWithOutExpr -DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr -/.$putCase consumeDimWithOrWithOutExprs(); $break ./ - -DimWithOrWithOutExpr ::= '[' Expression ']' -DimWithOrWithOutExpr ::= '[' ']' -/. $putCase consumeDimWithOrWithOutExpr(); $break ./ --- ----------------------------------------------- - -Dims ::= DimsLoop -/. $putCase consumeDims(); $break ./ -DimsLoop -> OneDimLoop -DimsLoop ::= DimsLoop OneDimLoop -OneDimLoop ::= '[' ']' -/. $putCase consumeOneDimLoop(); $break ./ - -FieldAccess ::= Primary '.' 'Identifier' -/.$putCase consumeFieldAccess(false); $break ./ - -FieldAccess ::= 'super' '.' 'Identifier' -/.$putCase consumeFieldAccess(true); $break ./ - -MethodInvocation ::= Name '(' ArgumentListopt ')' -/.$putCase consumeMethodInvocationName(); $break ./ - -MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')' -/.$putCase consumeMethodInvocationPrimary(); $break ./ - -MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')' -/.$putCase consumeMethodInvocationSuper(); $break ./ - -ArrayAccess ::= Name '[' Expression ']' -/.$putCase consumeArrayAccess(true); $break ./ -ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' -/.$putCase consumeArrayAccess(false); $break ./ - -PostfixExpression -> Primary -PostfixExpression ::= Name -/.$putCase consumePostfixExpression(); $break ./ -PostfixExpression -> PostIncrementExpression -PostfixExpression -> PostDecrementExpression - -PostIncrementExpression ::= PostfixExpression '++' -/.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./ - -PostDecrementExpression ::= PostfixExpression '--' -/.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./ - ---for source managment purpose -PushPosition ::= $empty - /.$putCase consumePushPosition(); $break ./ - -UnaryExpression -> PreIncrementExpression -UnaryExpression -> PreDecrementExpression -UnaryExpression ::= '+' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./ -UnaryExpression ::= '-' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./ -UnaryExpression -> UnaryExpressionNotPlusMinus - -PreIncrementExpression ::= '++' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./ - -PreDecrementExpression ::= '--' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./ - -UnaryExpressionNotPlusMinus -> PostfixExpression -UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./ -UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression -/.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./ -UnaryExpressionNotPlusMinus -> CastExpression - -CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression -/.$putCase consumeCastExpression(); $break ./ - CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus -/.$putCase consumeCastExpression(); $break ./ --- Expression is here only in order to make the grammar LL1 -CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus -/.$putCase consumeCastExpressionLL1(); $break ./ - -MultiplicativeExpression -> UnaryExpression -MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression -/.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./ -MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression -/.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./ -MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression -/.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./ - -AdditiveExpression -> MultiplicativeExpression -AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression -/.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./ -AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression -/.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./ - -ShiftExpression -> AdditiveExpression -ShiftExpression ::= ShiftExpression '<<' AdditiveExpression -/.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./ -ShiftExpression ::= ShiftExpression '>>' AdditiveExpression -/.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./ -ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression -/.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./ - -RelationalExpression -> ShiftExpression -RelationalExpression ::= RelationalExpression '<' ShiftExpression -/.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./ -RelationalExpression ::= RelationalExpression '>' ShiftExpression -/.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./ -RelationalExpression ::= RelationalExpression '<=' ShiftExpression -/.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./ -RelationalExpression ::= RelationalExpression '>=' ShiftExpression -/.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./ -RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType -/.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./ - -EqualityExpression -> RelationalExpression -EqualityExpression ::= EqualityExpression '==' RelationalExpression -/.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./ -EqualityExpression ::= EqualityExpression '!=' RelationalExpression -/.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./ - -AndExpression -> EqualityExpression -AndExpression ::= AndExpression '&' EqualityExpression -/.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./ - -ExclusiveOrExpression -> AndExpression -ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression -/.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./ - -InclusiveOrExpression -> ExclusiveOrExpression -InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression -/.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./ - -ConditionalAndExpression -> InclusiveOrExpression -ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression -/.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./ - -ConditionalOrExpression -> ConditionalAndExpression -ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression -/.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./ - -ConditionalExpression -> ConditionalOrExpression -ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression -/.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./ - -AssignmentExpression -> ConditionalExpression -AssignmentExpression -> Assignment - -Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression -/.$putCase consumeAssignment(); $break ./ - --- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario -InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer -Assignment ::= InvalidArrayInitializerAssignement -/.$putcase ignoreExpressionAssignment();$break ./ - -LeftHandSide ::= Name -/.$putCase consumeLeftHandSide(); $break ./ -LeftHandSide -> FieldAccess -LeftHandSide -> ArrayAccess - -AssignmentOperator ::= '=' -/.$putCase consumeAssignmentOperator(EQUAL); $break ./ -AssignmentOperator ::= '*=' -/.$putCase consumeAssignmentOperator(MULTIPLY); $break ./ -AssignmentOperator ::= '/=' -/.$putCase consumeAssignmentOperator(DIVIDE); $break ./ -AssignmentOperator ::= '%=' -/.$putCase consumeAssignmentOperator(REMAINDER); $break ./ -AssignmentOperator ::= '+=' -/.$putCase consumeAssignmentOperator(PLUS); $break ./ -AssignmentOperator ::= '-=' -/.$putCase consumeAssignmentOperator(MINUS); $break ./ -AssignmentOperator ::= '<<=' -/.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./ -AssignmentOperator ::= '>>=' -/.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./ -AssignmentOperator ::= '>>>=' -/.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./ -AssignmentOperator ::= '&=' -/.$putCase consumeAssignmentOperator(AND); $break ./ -AssignmentOperator ::= '^=' -/.$putCase consumeAssignmentOperator(XOR); $break ./ -AssignmentOperator ::= '|=' -/.$putCase consumeAssignmentOperator(OR); $break ./ - -Expression -> AssignmentExpression - -ConstantExpression -> Expression - --- The following rules are for optional nonterminals. --- - -PackageDeclarationopt -> $empty -PackageDeclarationopt -> PackageDeclaration - -ClassHeaderExtendsopt ::= $empty -ClassHeaderExtendsopt -> ClassHeaderExtends - -Expressionopt ::= $empty -/.$putCase consumeEmptyExpression(); $break ./ -Expressionopt -> Expression - - ---------------------------------------------------------------------------------------- --- --- The rules below are for optional terminal symbols. An optional comma, --- is only used in the context of an array initializer - It is a --- "syntactic sugar" that otherwise serves no other purpose. By contrast, --- an optional identifier is used in the definition of a break and --- continue statement. When the identifier does not appear, a NULL --- is produced. When the identifier is present, the user should use the --- corresponding TOKEN(i) method. See break statement as an example. --- ---------------------------------------------------------------------------------------- - -,opt -> $empty -,opt -> , - -ImportDeclarationsopt ::= $empty -/.$putCase consumeEmptyImportDeclarationsopt(); $break ./ -ImportDeclarationsopt ::= ImportDeclarations -/.$putCase consumeImportDeclarationsopt(); $break ./ - - -TypeDeclarationsopt ::= $empty -/.$putCase consumeEmptyTypeDeclarationsopt(); $break ./ -TypeDeclarationsopt ::= TypeDeclarations -/.$putCase consumeTypeDeclarationsopt(); $break ./ - -ClassBodyDeclarationsopt ::= $empty -/.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./ -ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations -/.$putCase consumeClassBodyDeclarationsopt(); $break ./ - -Modifiersopt ::= $empty -/. $putCase consumeDefaultModifiers(); $break ./ -Modifiersopt ::= Modifiers -/.$putCase consumeModifiers(); $break ./ - -BlockStatementsopt ::= $empty -/.$putCase consumeEmptyBlockStatementsopt(); $break ./ -BlockStatementsopt -> BlockStatements - -Dimsopt ::= $empty -/. $putCase consumeEmptyDimsopt(); $break ./ -Dimsopt -> Dims - -ArgumentListopt ::= $empty -/. $putCase consumeEmptyArgumentListopt(); $break ./ -ArgumentListopt -> ArgumentList - -MethodHeaderThrowsClauseopt ::= $empty -MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause - -FormalParameterListopt ::= $empty -/.$putcase consumeFormalParameterListopt(); $break ./ -FormalParameterListopt -> FormalParameterList - -ClassHeaderImplementsopt ::= $empty -ClassHeaderImplementsopt -> ClassHeaderImplements - -InterfaceMemberDeclarationsopt ::= $empty -/. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./ -InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations -/. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./ - -NestedType ::= $empty -/.$putCase consumeNestedType(); $break./ - -ForInitopt ::= $empty -/. $putCase consumeEmptyForInitopt(); $break ./ -ForInitopt -> ForInit - -ForUpdateopt ::= $empty -/. $putCase consumeEmptyForUpdateopt(); $break ./ - ForUpdateopt -> ForUpdate - -InterfaceHeaderExtendsopt ::= $empty -InterfaceHeaderExtendsopt -> InterfaceHeaderExtends - -Catchesopt ::= $empty -/. $putCase consumeEmptyCatchesopt(); $break ./ -Catchesopt -> Catches - -ArrayInitializeropt ::= $empty -/. $putCase consumeEmptyArrayInitializeropt(); $break ./ -ArrayInitializeropt -> ArrayInitializer - -/. } -} ./ - ---------------------------------------------------------------------------------------- - -$names - --- BodyMarker ::= '"class Identifier { ... MethodHeader "' - --- void ::= 'void' - -PLUS_PLUS ::= '++' -MINUS_MINUS ::= '--' -EQUAL_EQUAL ::= '==' -LESS_EQUAL ::= '<=' -GREATER_EQUAL ::= '>=' -NOT_EQUAL ::= '!=' -LEFT_SHIFT ::= '<<' -RIGHT_SHIFT ::= '>>' -UNSIGNED_RIGHT_SHIFT ::= '>>>' -PLUS_EQUAL ::= '+=' -MINUS_EQUAL ::= '-=' -MULTIPLY_EQUAL ::= '*=' -DIVIDE_EQUAL ::= '/=' -AND_EQUAL ::= '&=' -OR_EQUAL ::= '|=' -XOR_EQUAL ::= '^=' -REMAINDER_EQUAL ::= '%=' -LEFT_SHIFT_EQUAL ::= '<<=' -RIGHT_SHIFT_EQUAL ::= '>>=' -UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>=' -OR_OR ::= '||' -AND_AND ::= '&&' - -PLUS ::= '+' -MINUS ::= '-' -NOT ::= '!' -REMAINDER ::= '%' -XOR ::= '^' -AND ::= '&' -MULTIPLY ::= '*' -OR ::= '|' -TWIDDLE ::= '~' -DIVIDE ::= '/' -GREATER ::= '>' -LESS ::= '<' -LPAREN ::= '(' -RPAREN ::= ')' -LBRACE ::= '{' -RBRACE ::= '}' -LBRACKET ::= '[' -RBRACKET ::= ']' -SEMICOLON ::= ';' -QUESTION ::= '?' -COLON ::= ':' -COMMA ::= ',' -DOT ::= '.' -EQUAL ::= '=' - -$end --- need a carriage return after the $end -*/ -} -protected void ignoreExpressionAssignment() { - // Assignment ::= InvalidArrayInitializerAssignement - // encoded operator would be: intStack[intPtr] - intPtr--; - ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--]; - expressionLengthPtr -- ; - // report a syntax error and abort parsing - problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd); -} -protected void ignoreInterfaceDeclaration() { - // BlockStatement ::= InvalidInterfaceDeclaration - //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody - - // length declarations - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - //there are length declarations - //dispatch according to the type of the declarations - dispatchDeclarationInto(length); - } - - flushAnnotationsDefinedPriorTo(endStatementPosition); - - // report the problem and continue parsing - TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr]; - typeDecl.bodyEnd = endStatementPosition; - problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd); - - // mark fields and initializer with local type mark if needed - markFieldsWithLocalType(typeDecl); - - // remove the ast node created in interface header - astPtr--; - // Don't create an astnode for this inner interface, but have to push - // a 0 on the astLengthStack to be consistent with the reduction made - // at the end of the method: - // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) - pushOnAstLengthStack(0); -} -protected void ignoreInvalidConstructorDeclaration(boolean hasBody) { - // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true - // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false + ASTNode[] noAstNodes = new ASTNode[AstStackIncrement]; - /* - astStack : modifiers arguments throws statements - identifierStack : name - ==> - astStack : MethodDeclaration - identifierStack : - */ - - //must provide a default constructor call when needed - - if (hasBody) { - // pop the position of the { (body of the method) pushed in block decl - intPtr--; - } + public CompilationUnitDeclaration compilationUnit; /* + * the result from parse() + */ - //statements - if (hasBody) { - realBlockPtr--; - } + protected ReferenceContext referenceContext; - int length; - if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) { - astPtr -= length; - } -} -protected void ignoreMethodBody() { - // InterfaceMemberDeclaration ::= InvalidMethodDeclaration + protected ProblemReporter problemReporter; - /* - astStack : modifiers arguments throws statements - identifierStack : type name - intStack : dim dim dim - ==> - astStack : MethodDeclaration - identifierStack : - intStack : - */ - - // pop the position of the { (body of the method) pushed in block decl - intPtr--; - // retrieve end position of method declarator - - //statements - realBlockPtr--; - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - } + protected CompilerOptions options; - //watch for } that could be given as a unicode ! ( u007D is '}' ) - MethodDeclaration md = (MethodDeclaration) astStack[astPtr]; - md.bodyEnd = endPosition; - md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); - - // report the problem and continue the parsing - narrowing the problem onto the method - problemReporter().abstractMethodNeedingNoBody(md); -} -public void initialize() { - //positionning the parser for a new compilation unit - //avoiding stack reallocation and all that.... - astPtr = -1; - astLengthPtr = -1; - expressionPtr = -1; - expressionLengthPtr = -1; - identifierPtr = -1; - identifierLengthPtr = -1; - intPtr = -1; - nestedMethod[nestedType = 0] = 0; // need to reset for further reuse - variablesCounter[nestedType] = 0; - dimensions = 0 ; - realBlockPtr = -1; - compilationUnit = null; - referenceContext = null; - endStatementPosition = 0; - - //remove objects from stack too, while the same parser/compiler couple is - //re-used between two compilations .... - - int astLength = astStack.length; - if (noAstNodes.length < astLength){ - noAstNodes = new AstNode[astLength]; - //System.out.println("Resized AST stacks : "+ astLength); - - } - System.arraycopy(noAstNodes, 0, astStack, 0, astLength); + private ArrayList includesList; - int expressionLength = expressionStack.length; - if (noExpressions.length < expressionLength){ - noExpressions = new Expression[expressionLength]; - //System.out.println("Resized EXPR stacks : "+ expressionLength); - } - System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength); - - // reset scanner state - scanner.commentPtr = -1; - scanner.eofPosition = Integer.MAX_VALUE; - - resetModifiers(); - - // recovery - lastCheckPoint = -1; - currentElement = null; - restartRecovery = false; - hasReportedError = false; - recoveredStaticInitializerStart = 0; - lastIgnoredToken = -1; - lastErrorEndPosition = -1; - listLength = 0; -} -public void initializeScanner(){ - this.scanner = new Scanner(false, false, this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore , this.assertMode); -} -public final static void initTables() throws java.io.IOException { - - final String prefix = FILEPREFIX; - int i = 0; - lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ - char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ - check_table = new short[chars.length]; - for (int c = chars.length; c-- > 0;) { - check_table[c] = (short) (chars[c] - 32768); - } - asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ - asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ - symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$ - action = lhs; -} -public final void jumpOverMethodBody() { - //on diet parsing.....do not buffer method statements - - //the scanner.diet is reinitialized to false - //automatically by the scanner once it has jumped over - //the statements - - if (diet && (dietInt == 0)) - scanner.diet = true; -} -protected void markCurrentMethodWithLocalType() { - if (this.currentElement != null) return; // this is already done in the recovery code - for (int i = this.astPtr; i >= 0; i--) { - AstNode node = this.astStack[i]; - if (node instanceof AbstractMethodDeclaration - || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type - node.bits |= AstNode.HasLocalTypeMASK; - return; - } - } - // default to reference context (case of parse method body) - if (this.referenceContext instanceof AbstractMethodDeclaration - || this.referenceContext instanceof TypeDeclaration) { - ((AstNode)this.referenceContext).bits |= AstNode.HasLocalTypeMASK; - } -} -protected void markFieldsWithLocalType(TypeDeclaration type) { - if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0) return; - for (int i = 0, length = type.fields.length; i < length; i++) { - type.fields[i].bits |= AstNode.HasLocalTypeMASK; - } -} -/* - * Move checkpoint location (current implementation is moving it by one token) - * - * Answers true if successfully moved checkpoint (i.e. did not attempt to move it - * beyond end of file). - */ -protected boolean moveRecoveryCheckpoint() { - - int pos = lastCheckPoint; - /* reset scanner, and move checkpoint by one token */ - scanner.startPosition = pos; - scanner.currentPosition = pos; - scanner.diet = false; // quit jumping over method bodies - - /* if about to restart, then no need to shift token */ - if (restartRecovery){ - lastIgnoredToken = -1; - return true; - } - - /* protect against shifting on an invalid token */ - lastIgnoredToken = nextIgnoredToken; - nextIgnoredToken = -1; - do { - try { - nextIgnoredToken = scanner.getNextToken(); - if(scanner.currentPosition == scanner.startPosition){ - scanner.currentPosition++; // on fake completion identifier - nextIgnoredToken = -1; - } - - } catch(InvalidInputException e){ - pos = scanner.currentPosition; - } - } while (nextIgnoredToken < 0); - - if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point - if (currentToken == TokenNameEOF) { // already tried one iteration on EOF - return false; - } - } - lastCheckPoint = scanner.currentPosition; - - /* reset scanner again to previous checkpoint location*/ - scanner.startPosition = pos; - scanner.currentPosition = pos; - scanner.commentPtr = -1; - - return true; - -/* - The following implementation moves the checkpoint location by one line: - - int pos = lastCheckPoint; - // reset scanner, and move checkpoint by one token - scanner.startPosition = pos; - scanner.currentPosition = pos; - scanner.diet = false; // quit jumping over method bodies - - // if about to restart, then no need to shift token - if (restartRecovery){ - lastIgnoredToken = -1; - return true; - } - - // protect against shifting on an invalid token - lastIgnoredToken = nextIgnoredToken; - nextIgnoredToken = -1; - - boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace; - scanner.tokenizeWhiteSpace = true; - checkpointMove: - do { - try { - nextIgnoredToken = scanner.getNextToken(); - switch(nextIgnoredToken){ - case Scanner.TokenNameWHITESPACE : - if(scanner.getLineNumber(scanner.startPosition) - == scanner.getLineNumber(scanner.currentPosition)){ - nextIgnoredToken = -1; - } - break; - case TokenNameSEMICOLON : - case TokenNameLBRACE : - case TokenNameRBRACE : - break; - case TokenNameIdentifier : - if(scanner.currentPosition == scanner.startPosition){ - scanner.currentPosition++; // on fake completion identifier - } - default: - nextIgnoredToken = -1; - break; - case TokenNameEOF : - break checkpointMove; - } - } catch(InvalidInputException e){ - pos = scanner.currentPosition; - } - } while (nextIgnoredToken < 0); - scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace; - - if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point - if (currentToken == TokenNameEOF) { // already tried one iteration on EOF - return false; + // protected CompilationResult compilationResult; + /** + * Returns this parser's problem reporter initialized with its reference + * context. Also it is assumed that a problem is going to be reported, so + * initializes the compilation result's line positions. + */ + public ProblemReporter problemReporter() { + if (scanner.recordLineSeparator) { + compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); } + problemReporter.referenceContext = referenceContext; + return problemReporter; } - lastCheckPoint = scanner.currentPosition; - - // reset scanner again to previous checkpoint location - scanner.startPosition = pos; - scanner.currentPosition = pos; - scanner.commentPtr = -1; - - return true; -*/ -} -protected MessageSend newMessageSend() { - // '(' ArgumentListopt ')' - // the arguments are on the expression stack - - MessageSend m = new MessageSend(); - int length; - if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) { - expressionPtr -= length; - System.arraycopy( - expressionStack, - expressionPtr + 1, - m.arguments = new Expression[length], - 0, - length); - }; - return m; -} -protected static int ntAction(int state, int sym) { - return action[state + sym]; -} -private final void optimizedConcatNodeLists() { - /*back from a recursive loop. Virtualy group the - astNode into an array using astLengthStack*/ /* - * This is a case where you have two sublists into the astStack that you want - * to merge in one list. There is no action required on the astStack. The only - * thing you need to do is merge the two lengths specified on the astStackLength. - * The top two length are for example: - * ... p n - * and you want to result in a list like: - * ... n+p - * This means that the p could be equals to 0 in case there is no astNode pushed - * on the astStack. - * Look at the InterfaceMemberDeclarations for an example. - * This case optimizes the fact that p == 1. + * Reconsider the entire source looking for inconsistencies in {} () [] */ - - astLengthStack[--astLengthPtr]++; -} -protected static int original_state(int state) { - return -check(state); -} -/*main loop of the automat -When a rule is reduced, the method consumeRule(int) is called with the number -of the consumed rule. When a terminal is consumed, the method consumeToken(int) is -called in order to remember (when needed) the consumed token */ -// (int)asr[asi(act)] -// name[symbol_index[currentKind]] -protected void parse() { - - hasReportedError = false; - int act = START_STATE; - stateStackTop = -1; - currentToken = getFirstToken(); - ProcessTerminals : for (;;) { + // public boolean checkAndReportBracketAnomalies(ProblemReporter + // problemReporter) { + // scanner.wasAcr = false; + // boolean anomaliesDetected = false; + // try { + // char[] source = scanner.source; + // int[] leftCount = { 0, 0, 0 }; + // int[] rightCount = { 0, 0, 0 }; + // int[] depths = { 0, 0, 0 }; + // int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] + // }; + // int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] }; + // int[][] rightPositions = new int[][] { new int[10], new int[10], new + // int[10] }; + // int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] + // }; + // scanner.currentPosition = scanner.initialPosition; //starting + // // point + // // (first-zero-based + // // char) + // while (scanner.currentPosition < scanner.eofPosition) { //loop for + // // jumping + // // over + // // comments + // try { + // // ---------Consume white space and handles + // // startPosition--------- + // boolean isWhiteSpace; + // do { + // scanner.startPosition = scanner.currentPosition; + // // if (((scanner.currentCharacter = + // // source[scanner.currentPosition++]) == '\\') && + // // (source[scanner.currentPosition] == 'u')) { + // // isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace(); + // // } else { + // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || + // (scanner.currentCharacter == '\n'))) { + // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { + // // only record line positions we have not + // // recorded yet + // scanner.pushLineSeparator(); + // } + // } + // isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter); + // // } + // } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition)); + // // -------consume token until } is found--------- + // switch (scanner.currentCharacter) { + // case '{': { + // int index = leftCount[CurlyBracket]++; + // if (index == leftPositions[CurlyBracket].length) { + // System.arraycopy(leftPositions[CurlyBracket], 0, + // (leftPositions[CurlyBracket] = new int[index * 2]), 0, index); + // System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = + // new int[index * 2]), 0, index); + // } + // leftPositions[CurlyBracket][index] = scanner.startPosition; + // leftDepths[CurlyBracket][index] = depths[CurlyBracket]++; + // } + // break; + // case '}': { + // int index = rightCount[CurlyBracket]++; + // if (index == rightPositions[CurlyBracket].length) { + // System.arraycopy(rightPositions[CurlyBracket], 0, + // (rightPositions[CurlyBracket] = new int[index * 2]), 0, index); + // System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = + // new int[index * 2]), 0, index); + // } + // rightPositions[CurlyBracket][index] = scanner.startPosition; + // rightDepths[CurlyBracket][index] = --depths[CurlyBracket]; + // } + // break; + // case '(': { + // int index = leftCount[RoundBracket]++; + // if (index == leftPositions[RoundBracket].length) { + // System.arraycopy(leftPositions[RoundBracket], 0, + // (leftPositions[RoundBracket] = new int[index * 2]), 0, index); + // System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = + // new int[index * 2]), 0, index); + // } + // leftPositions[RoundBracket][index] = scanner.startPosition; + // leftDepths[RoundBracket][index] = depths[RoundBracket]++; + // } + // break; + // case ')': { + // int index = rightCount[RoundBracket]++; + // if (index == rightPositions[RoundBracket].length) { + // System.arraycopy(rightPositions[RoundBracket], 0, + // (rightPositions[RoundBracket] = new int[index * 2]), 0, index); + // System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = + // new int[index * 2]), 0, index); + // } + // rightPositions[RoundBracket][index] = scanner.startPosition; + // rightDepths[RoundBracket][index] = --depths[RoundBracket]; + // } + // break; + // case '[': { + // int index = leftCount[SquareBracket]++; + // if (index == leftPositions[SquareBracket].length) { + // System.arraycopy(leftPositions[SquareBracket], 0, + // (leftPositions[SquareBracket] = new int[index * 2]), 0, index); + // System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = + // new int[index * 2]), 0, index); + // } + // leftPositions[SquareBracket][index] = scanner.startPosition; + // leftDepths[SquareBracket][index] = depths[SquareBracket]++; + // } + // break; + // case ']': { + // int index = rightCount[SquareBracket]++; + // if (index == rightPositions[SquareBracket].length) { + // System.arraycopy(rightPositions[SquareBracket], 0, + // (rightPositions[SquareBracket] = new int[index * 2]), 0, index); + // System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] + // = new int[index * 2]), 0, index); + // } + // rightPositions[SquareBracket][index] = scanner.startPosition; + // rightDepths[SquareBracket][index] = --depths[SquareBracket]; + // } + // break; + // case '\'': { + // if (scanner.getNextChar('\\')) { + // scanner.scanEscapeCharacter(); + // } else { // consume next character + // scanner.unicodeAsBackSlash = false; + // // if (((scanner.currentCharacter = + // // source[scanner.currentPosition++]) == + // // '\\') && + // // (source[scanner.currentPosition] == + // // 'u')) { + // // scanner.getNextUnicodeChar(); + // // } else { + // if (scanner.withoutUnicodePtr != 0) { + // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = + // scanner.currentCharacter; + // } + // // } + // } + // scanner.getNextChar('\''); + // break; + // } + // case '"': + // // consume next character + // scanner.unicodeAsBackSlash = false; + // // if (((scanner.currentCharacter = + // // source[scanner.currentPosition++]) == '\\') && + // // (source[scanner.currentPosition] == 'u')) { + // // scanner.getNextUnicodeChar(); + // // } else { + // if (scanner.withoutUnicodePtr != 0) { + // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = + // scanner.currentCharacter; + // } + // // } + // while (scanner.currentCharacter != '"') { + // if (scanner.currentCharacter == '\r') { + // if (source[scanner.currentPosition] == '\n') + // scanner.currentPosition++; + // break; // the string cannot go further that + // // the line + // } + // if (scanner.currentCharacter == '\n') { + // break; // the string cannot go further that + // // the line + // } + // if (scanner.currentCharacter == '\\') { + // scanner.scanEscapeCharacter(); + // } + // // consume next character + // scanner.unicodeAsBackSlash = false; + // // if (((scanner.currentCharacter = + // // source[scanner.currentPosition++]) == '\\') + // // && (source[scanner.currentPosition] == 'u')) + // // { + // // scanner.getNextUnicodeChar(); + // // } else { + // if (scanner.withoutUnicodePtr != 0) { + // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = + // scanner.currentCharacter; + // } + // // } + // } + // break; + // case '/': { + // int test; + // if ((test = scanner.getNextChar('/', '*')) == 0) { //line + // // comment + // //get the next char + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == + // '\\') + // && (source[scanner.currentPosition] == 'u')) { + // //-------------unicode traitement + // // ------------ + // int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + // scanner.currentPosition++; + // while (source[scanner.currentPosition] == 'u') { + // scanner.currentPosition++; + // } + // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 || c1 < 0 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c2 < 0 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c3 < 0 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c4 < 0) { //error + // // don't + // // care of the + // // value + // scanner.currentCharacter = 'A'; + // } //something different from \n and \r + // else { + // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + // } + // } + // while (scanner.currentCharacter != '\r' && scanner.currentCharacter != + // '\n') { + // //get the next char + // scanner.startPosition = scanner.currentPosition; + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == + // '\\') + // && (source[scanner.currentPosition] == 'u')) { + // //-------------unicode traitement + // // ------------ + // int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + // scanner.currentPosition++; + // while (source[scanner.currentPosition] == 'u') { + // scanner.currentPosition++; + // } + // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 || c1 < 0 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c2 < 0 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c3 < 0 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c4 < 0) { //error + // // don't + // // care of the + // // value + // scanner.currentCharacter = 'A'; + // } //something different from \n + // // and \r + // else { + // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + // } + // } + // } + // if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || + // (scanner.currentCharacter == '\n'))) { + // if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) { + // // only record line positions we + // // have not recorded yet + // scanner.pushLineSeparator(); + // if (this.scanner.taskTags != null) { + // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), + // this.scanner + // .getCurrentTokenEndPosition()); + // } + // } + // } + // break; + // } + // if (test > 0) { //traditional and annotation + // // comment + // boolean star = false; + // // consume next character + // scanner.unicodeAsBackSlash = false; + // // if (((scanner.currentCharacter = + // // source[scanner.currentPosition++]) == + // // '\\') && + // // (source[scanner.currentPosition] == + // // 'u')) { + // // scanner.getNextUnicodeChar(); + // // } else { + // if (scanner.withoutUnicodePtr != 0) { + // scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = + // scanner.currentCharacter; + // } + // // } + // if (scanner.currentCharacter == '*') { + // star = true; + // } + // //get the next char + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == + // '\\') + // && (source[scanner.currentPosition] == 'u')) { + // //-------------unicode traitement + // // ------------ + // int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + // scanner.currentPosition++; + // while (source[scanner.currentPosition] == 'u') { + // scanner.currentPosition++; + // } + // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 || c1 < 0 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c2 < 0 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c3 < 0 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c4 < 0) { //error + // // don't + // // care of the + // // value + // scanner.currentCharacter = 'A'; + // } //something different from * and / + // else { + // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + // } + // } + // //loop until end of comment */ + // while ((scanner.currentCharacter != '/') || (!star)) { + // star = scanner.currentCharacter == '*'; + // //get next char + // if (((scanner.currentCharacter = source[scanner.currentPosition++]) == + // '\\') + // && (source[scanner.currentPosition] == 'u')) { + // //-------------unicode traitement + // // ------------ + // int c1 = 0, c2 = 0, c3 = 0, c4 = 0; + // scanner.currentPosition++; + // while (source[scanner.currentPosition] == 'u') { + // scanner.currentPosition++; + // } + // if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > + // 15 || c1 < 0 + // || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c2 < 0 + // || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c3 < 0 + // || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 + // || c4 < 0) { //error + // // don't + // // care of the + // // value + // scanner.currentCharacter = 'A'; + // } //something different from * and + // // / + // else { + // scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); + // } + // } + // } + // if (this.scanner.taskTags != null) { + // this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), + // this.scanner.getCurrentTokenEndPosition()); + // } + // break; + // } + // break; + // } + // default: + // if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) { + // scanner.scanIdentifierOrKeyword(false); + // break; + // } + // if (Character.isDigit(scanner.currentCharacter)) { + // scanner.scanNumber(false); + // break; + // } + // } + // //-----------------end switch while + // // try-------------------- + // } catch (IndexOutOfBoundsException e) { + // break; // read until EOF + // } catch (InvalidInputException e) { + // return false; // no clue + // } + // } + // if (scanner.recordLineSeparator) { + // compilationUnit.compilationResult.lineSeparatorPositions = + // scanner.getLineEnds(); + // } + // // check placement anomalies against other kinds of brackets + // for (int kind = 0; kind < BracketKinds; kind++) { + // for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) { + // int start = leftPositions[kind][leftIndex]; // deepest + // // first + // // find matching closing bracket + // int depth = leftDepths[kind][leftIndex]; + // int end = -1; + // for (int i = 0; i < rightCount[kind]; i++) { + // int pos = rightPositions[kind][i]; + // // want matching bracket further in source with same + // // depth + // if ((pos > start) && (depth == rightDepths[kind][i])) { + // end = pos; + // break; + // } + // } + // if (end < 0) { // did not find a good closing match + // problemReporter.unmatchedBracket(start, referenceContext, + // compilationUnit.compilationResult); + // return true; + // } + // // check if even number of opening/closing other brackets + // // in between this pair of brackets + // int balance = 0; + // for (int otherKind = 0; (balance == 0) && (otherKind < BracketKinds); + // otherKind++) { + // for (int i = 0; i < leftCount[otherKind]; i++) { + // int pos = leftPositions[otherKind][i]; + // if ((pos > start) && (pos < end)) + // balance++; + // } + // for (int i = 0; i < rightCount[otherKind]; i++) { + // int pos = rightPositions[otherKind][i]; + // if ((pos > start) && (pos < end)) + // balance--; + // } + // if (balance != 0) { + // problemReporter.unmatchedBracket(start, referenceContext, + // compilationUnit.compilationResult); //bracket + // // anomaly + // return true; + // } + // } + // } + // // too many opening brackets ? + // for (int i = rightCount[kind]; i < leftCount[kind]; i++) { + // anomaliesDetected = true; + // problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - + // 1], referenceContext, + // compilationUnit.compilationResult); + // } + // // too many closing brackets ? + // for (int i = leftCount[kind]; i < rightCount[kind]; i++) { + // anomaliesDetected = true; + // problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, + // compilationUnit.compilationResult); + // } + // if (anomaliesDetected) + // return true; + // } + // return anomaliesDetected; + // } catch (ArrayStoreException e) { // jdk1.2.2 jit bug + // return anomaliesDetected; + // } catch (NullPointerException e) { // jdk1.2.2 jit bug + // return anomaliesDetected; + // } + // } + protected void pushOnAstLengthStack(int pos) { try { - stack[++stateStackTop] = act; + astLengthStack[++astLengthPtr] = pos; } catch (IndexOutOfBoundsException e) { - int oldStackLength = stack.length; - int oldStack[] = stack; - stack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldStack, 0, stack, 0, oldStackLength); - stack[stateStackTop] = act; - }; - - act = tAction(act, currentToken); - - if (act == ERROR_ACTION || restartRecovery) { - int errorPos = scanner.currentPosition; - if (!hasReportedError){ - this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop); - hasReportedError = true; - } - if (resumeOnSyntaxError()) { - if (act == ERROR_ACTION) lastErrorEndPosition = errorPos; - act = START_STATE; - stateStackTop = -1; - currentToken = getFirstToken(); - continue ProcessTerminals; - } else { - act = ERROR_ACTION; - } break ProcessTerminals; - } - if (act <= NUM_RULES) - stateStackTop--; - else - if (act > ERROR_ACTION) { /* shift-reduce */ - consumeToken(currentToken); - if (currentElement != null) this.recoveryTokenCheck(); - try{ - currentToken = scanner.getNextToken(); - } catch(InvalidInputException e){ - if (!hasReportedError){ - this.problemReporter().scannerError(this, e.getMessage()); - hasReportedError = true; - } - lastCheckPoint = scanner.currentPosition; - restartRecovery = true; - } - act -= ERROR_ACTION; - } else - if (act < ACCEPT_ACTION) { /* shift */ - consumeToken(currentToken); - if (currentElement != null) this.recoveryTokenCheck(); - try{ - currentToken = scanner.getNextToken(); - } catch(InvalidInputException e){ - if (!hasReportedError){ - this.problemReporter().scannerError(this, e.getMessage()); - hasReportedError = true; - } - lastCheckPoint = scanner.currentPosition; - restartRecovery = true; - } - continue ProcessTerminals; - } else - break ProcessTerminals; - - ProcessNonTerminals : do { /* reduce */ - consumeRule(act); - stateStackTop -= (rhs[act] - 1); - act = ntAction(stack[stateStackTop], lhs[act]); - } while (act <= NUM_RULES); - } - endParse(act); -} -// A P I - -public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) { - //only parse the method body of cd - //fill out its statements - - //convert bugs into parse error - - initialize(); - goForConstructorBody(); - nestedMethod[nestedType]++; - - referenceContext = cd; - compilationUnit = unit; - - scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd); - try { - parse(); - } catch (AbortCompilation ex) { - lastAct = ERROR_ACTION; - } finally { - nestedMethod[nestedType]--; - } - - if (lastAct == ERROR_ACTION) { - initialize(); - return; - } - - //statements - cd.explicitDeclarations = realBlockStack[realBlockPtr--]; - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) { - astPtr -= length; - if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) - //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ? - { - System.arraycopy( - astStack, - astPtr + 2, - cd.statements = new Statement[length - 1], - 0, - length - 1); - cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1]; - } else { //need to add explicitly the super(); - System.arraycopy( - astStack, - astPtr + 1, - cd.statements = new Statement[length], - 0, - length); - cd.constructorCall = SuperReference.implicitSuperConstructorCall(); - } - } else { - cd.constructorCall = SuperReference.implicitSuperConstructorCall(); + int oldStackLength = astLengthStack.length; + int[] oldPos = astLengthStack; + astLengthStack = new int[oldStackLength + StackIncrement]; + System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); + astLengthStack[astLengthPtr] = pos; + } } - if (cd.constructorCall.sourceEnd == 0) { - cd.constructorCall.sourceEnd = cd.sourceEnd; - cd.constructorCall.sourceStart = cd.sourceStart; + protected void pushOnAstStack(ASTNode node) { + /* + * add a new obj on top of the ast stack + */ + try { + astStack[++astPtr] = node; + } catch (IndexOutOfBoundsException e) { + int oldStackLength = astStack.length; + ASTNode[] oldStack = astStack; + astStack = new ASTNode[oldStackLength + AstStackIncrement]; + System.arraycopy(oldStack, 0, astStack, 0, oldStackLength); + astPtr = oldStackLength; + astStack[astPtr] = node; + } + try { + astLengthStack[++astLengthPtr] = 1; + } catch (IndexOutOfBoundsException e) { + int oldStackLength = astLengthStack.length; + int[] oldPos = astLengthStack; + astLengthStack = new int[oldStackLength + AstStackIncrement]; + System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); + astLengthStack[astLengthPtr] = 1; + } } -} -// A P I - -public void parse( - Initializer ini, - TypeDeclaration type, - CompilationUnitDeclaration unit) { - //only parse the method body of md - //fill out method statements - //convert bugs into parse error - - initialize(); - goForInitializer(); - nestedMethod[nestedType]++; + protected void resetModifiers() { + this.modifiers = AccDefault; + this.modifiersSourceStart = -1; // <-- see comment into + // modifiersFlag(int) + this.scanner.commentPtr = -1; + } + + protected void consumePackageDeclarationName(IFile file) { + // create a package name similar to java package names + String projectPath = ProjectPrefUtil.getDocumentRoot(file.getProject()).toString(); + String filePath = file.getRawLocation().toString(); + String ext = file.getRawLocation().getFileExtension(); + int fileExtensionLength = ext == null ? 0 : ext.length() + 1; + ImportReference impt; + char[][] tokens; + if (filePath.startsWith(projectPath)) { + tokens = CharOperation + .splitOn('/', filePath.toCharArray(), projectPath.length() + 1, filePath.length() - fileExtensionLength); + } else { + String name = file.getName(); + tokens = new char[1][]; + tokens[0] = name.substring(0, name.length() - fileExtensionLength).toCharArray(); + } - referenceContext = type; - compilationUnit = unit; + this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true); - scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning { - try { - parse(); - } catch (AbortCompilation ex) { - lastAct = ERROR_ACTION; - } finally { - nestedMethod[nestedType]--; - } + impt.declarationSourceStart = 0; + impt.declarationSourceEnd = 0; + impt.declarationEnd = 0; + // endPosition is just before the ; - if (lastAct == ERROR_ACTION) { - return; } - ini.block = ((Initializer) astStack[astPtr]).block; - - // mark initializer with local type if one was found during parsing - if ((type.bits & AstNode.HasLocalTypeMASK) != 0) { - ini.bits |= AstNode.HasLocalTypeMASK; - } -} -// A P I - -public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) { - //only parse the method body of md - //fill out method statements - - //convert bugs into parse error - - if (md.isAbstract()) - return; - if (md.isNative()) - return; - if ((md.modifiers & AccSemicolonBody) != 0) - return; - - initialize(); - goForMethodBody(); - nestedMethod[nestedType]++; - - referenceContext = md; - compilationUnit = unit; + public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV", "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", + "$_SESSION", "$_SERVER" }; - scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd); - // reset the scanner to parser from { down to } - try { - parse(); - } catch (AbortCompilation ex) { - lastAct = ERROR_ACTION; - } finally { - nestedMethod[nestedType]--; + /** + * + */ + private void pushFunctionVariableSet() { + HashSet set = new HashSet(); + if (fStackUnassigned.isEmpty()) { + for (int i = 0; i < GLOBALS.length; i++) { + set.add(GLOBALS[i]); + } + } + fStackUnassigned.add(set); } - if (lastAct == ERROR_ACTION) { - return; + private void pushIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + HashSet set = new HashSet(); + fStackUnassigned.add(set); + } } - //refill statements - md.explicitDeclarations = realBlockStack[realBlockPtr--]; - int length; - if ((length = astLengthStack[astLengthPtr--]) != 0) - System.arraycopy( - astStack, - (astPtr -= length) + 1, - md.statements = new Statement[length], - 0, - length); -} -// A P I - -public CompilationUnitDeclaration parse( - ICompilationUnit sourceUnit, - CompilationResult compilationResult) { - // parses a compilation unit and manages error handling (even bugs....) - - CompilationUnitDeclaration unit; - try { - /* automaton initialization */ - initialize(); - goForCompilationUnit(); - - /* scanner initialization */ - scanner.setSource(sourceUnit.getContents()); - - /* unit creation */ - referenceContext = - compilationUnit = - new CompilationUnitDeclaration( - problemReporter, - compilationResult, - scanner.source.length); - /* run automaton */ - parse(); - } finally { - unit = compilationUnit; - compilationUnit = null; // reset parser + private HashSet removeIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1); + } + return null; } - return unit; -} -// A P I - -public CompilationUnitDeclaration parse( - ICompilationUnit sourceUnit, - CompilationResult compilationResult, - int start, - int end) { - // parses a compilation unit and manages error handling (even bugs....) - - CompilationUnitDeclaration unit; - try { - /* automaton initialization */ - initialize(); - goForCompilationUnit(); - /* scanner initialization */ - scanner.setSource(sourceUnit.getContents()); - scanner.resetTo(start, end); - /* unit creation */ - referenceContext = - compilationUnit = - new CompilationUnitDeclaration( - problemReporter, - compilationResult, - scanner.source.length); - /* run automaton */ - parse(); - } finally { - unit = compilationUnit; - compilationUnit = null; // reset parser - } - return unit; -} -/** - * Returns this parser's problem reporter initialized with its reference context. - * Also it is assumed that a problem is going to be reported, so initializes - * the compilation result's line positions. - */ -public ProblemReporter problemReporter(){ - if (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); - } - problemReporter.referenceContext = referenceContext; - return problemReporter; -} -protected void pushIdentifier() { - /*push the consumeToken on the identifier stack. - Increase the total number of identifier in the stack. - identifierPtr points on the next top */ - - try { - identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource(); - identifierPositionStack[identifierPtr] = - (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1); - } catch (IndexOutOfBoundsException e) { - /*---stack reallaocation (identifierPtr is correct)---*/ - int oldStackLength = identifierStack.length; - char[][] oldStack = identifierStack; - identifierStack = new char[oldStackLength + 20][]; - System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength); - identifierStack[identifierPtr] = scanner.getCurrentTokenSource(); - /*identifier position stack*/ - long[] oldPos = identifierPositionStack; - identifierPositionStack = new long[oldStackLength + 20]; - System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength); - identifierPositionStack[identifierPtr] = - (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1); - }; - - try { - identifierLengthStack[++identifierLengthPtr] = 1; - } catch (IndexOutOfBoundsException e) { - /*---stack reallocation (identifierLengthPtr is correct)---*/ - int oldStackLength = identifierLengthStack.length; - int oldStack[] = identifierLengthStack; - identifierLengthStack = new int[oldStackLength + 10]; - System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength); - identifierLengthStack[identifierLengthPtr] = 1; - }; - -} -protected void pushIdentifier(int flag) { - /*push a special flag on the stack : - -zero stands for optional Name - -negative number for direct ref to base types. - identifierLengthPtr points on the top */ - - try { - identifierLengthStack[++identifierLengthPtr] = flag; - } catch (IndexOutOfBoundsException e) { - /*---stack reallaocation (identifierLengthPtr is correct)---*/ - int oldStackLength = identifierLengthStack.length; - int oldStack[] = identifierLengthStack; - identifierLengthStack = new int[oldStackLength + 10]; - System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength); - identifierLengthStack[identifierLengthPtr] = flag; - }; - -} -protected void pushOnAstLengthStack(int pos) { - try { - astLengthStack[++astLengthPtr] = pos; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = astLengthStack.length; - int[] oldPos = astLengthStack; - astLengthStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); - astLengthStack[astLengthPtr] = pos; - } -} -protected void pushOnAstStack(AstNode node) { - /*add a new obj on top of the ast stack - astPtr points on the top*/ - - try { - astStack[++astPtr] = node; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = astStack.length; - AstNode[] oldStack = astStack; - astStack = new AstNode[oldStackLength + AstStackIncrement]; - System.arraycopy(oldStack, 0, astStack, 0, oldStackLength); - astPtr = oldStackLength; - astStack[astPtr] = node; + /** + * Returns the set of assigned variables returns null if no Set is + * defined at the current scanner position + */ + private HashSet peekVariableSet() { + if (!fStackUnassigned.isEmpty()) { + return (HashSet) fStackUnassigned.get(fStackUnassigned.size() - 1); + } + return null; } - try { - astLengthStack[++astLengthPtr] = 1; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = astLengthStack.length; - int[] oldPos = astLengthStack; - astLengthStack = new int[oldStackLength + AstStackIncrement]; - System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength); - astLengthStack[astLengthPtr] = 1; - } -} -protected void pushOnExpressionStack(Expression expr) { - - try { - expressionStack[++expressionPtr] = expr; - } catch (IndexOutOfBoundsException e) { - //expressionPtr is correct - int oldStackLength = expressionStack.length; - Expression[] oldStack = expressionStack; - expressionStack = new Expression[oldStackLength + ExpressionStackIncrement]; - System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength); - expressionStack[expressionPtr] = expr; + /** + * add the current identifier source to the set of assigned variables + * + * @param set + */ + private void addVariableSet(HashSet set) { + if (set != null) { + set.add(new String(scanner.getCurrentTokenSource())); + } } - try { - expressionLengthStack[++expressionLengthPtr] = 1; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = expressionLengthStack.length; - int[] oldPos = expressionLengthStack; - expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement]; - System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength); - expressionLengthStack[expressionLengthPtr] = 1; - } -} -protected void pushOnExpressionStackLengthStack(int pos) { - try { - expressionLengthStack[++expressionLengthPtr] = pos; - } catch (IndexOutOfBoundsException e) { - int oldStackLength = expressionLengthStack.length; - int[] oldPos = expressionLengthStack; - expressionLengthStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength); - expressionLengthStack[expressionLengthPtr] = pos; - } -} -protected void pushOnIntStack(int pos) { - - try { - intStack[++intPtr] = pos; - } catch (IndexOutOfBoundsException e) { - //intPtr is correct - int oldStackLength = intStack.length; - int oldStack[] = intStack; - intStack = new int[oldStackLength + StackIncrement]; - System.arraycopy(oldStack, 0, intStack, 0, oldStackLength); - intStack[intPtr] = pos; + /** + * add the current identifier source to the set of assigned variables + * + */ + private void addVariableSet() { + HashSet set = peekVariableSet(); + if (set != null) { + set.add(new String(scanner.getCurrentTokenSource())); + } } -} -protected static char[] readTable(String filename) throws java.io.IOException { - //files are located at Parser.class directory - - InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename)); - if (stream == null) { - throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$ - } - byte[] bytes = null; - try { - bytes = Util.getInputStreamAsByteArray(stream, -1); - } finally { - try { - stream.close(); - } catch (IOException e) { + /** + * add the current identifier source to the set of assigned variables + * + */ + private void addVariableSet(char[] token) { + HashSet set = peekVariableSet(); + if (set != null) { + set.add(new String(token)); } } - //minimal integrity check (even size expected) - int length = bytes.length; - if (length % 2 != 0) - throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$ + /** + * check if the current identifier source is in the set of assigned + * variables Returns true, if no set is defined for the current scanner + * position + * + */ + private boolean containsVariableSet() { + return containsVariableSet(scanner.getCurrentTokenSource()); + } - // convert bytes into chars - char[] chars = new char[length / 2]; - int i = 0; - int charIndex = 0; + private boolean containsVariableSet(char[] token) { - while (true) { - chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF)); - if (i == length) - break; - } - return chars; -} -/* Token check performed on every token shift once having entered - * recovery mode. - */ -public void recoveryTokenCheck() { - switch (currentToken) { - case TokenNameLBRACE : { - RecoveredElement newElement = - currentElement.updateOnOpeningBrace(scanner.currentPosition - 1); - lastCheckPoint = scanner.currentPosition; - if (newElement != null){ // null means nothing happened - restartRecovery = true; // opening brace detected - currentElement = newElement; - } - break; - } - case TokenNameRBRACE : { - endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1); - RecoveredElement newElement = - currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition -1); - lastCheckPoint = scanner.currentPosition; - if (newElement != currentElement){ - currentElement = newElement; + if (!fStackUnassigned.isEmpty()) { + HashSet set; + String str = new String(token); + for (int i = 0; i < fStackUnassigned.size(); i++) { + set = (HashSet) fStackUnassigned.get(i); + if (set.contains(str)) { + return true; + } } + return false; } - } -} -protected void reportSyntaxError(int act, int currentKind, int stateStackTop) { - - /* remember current scanner position */ - int startPos = scanner.startPosition; - int currentPos = scanner.currentPosition; - - String[] expectings; - String tokenName = name[symbol_index[currentKind]]; - - //fetch all "accurate" possible terminals that could recover the error - int start, end = start = asi(stack[stateStackTop]); - while (asr[end] != 0) - end++; - int length = end - start; - expectings = new String[length]; - if (length != 0) { - char[] indexes = new char[length]; - System.arraycopy(asr, start, indexes, 0, length); - for (int i = 0; i < length; i++) { - expectings[i] = name[symbol_index[indexes[i]]]; - } - } - - //if the pb is an EOF, try to tell the user that they are some - if (tokenName.equals(UNEXPECTED_EOF)) { - if (!this.checkAndReportBracketAnomalies(problemReporter())) { - char[] tokenSource; - try { - tokenSource = this.scanner.getCurrentTokenSource(); - } catch (Exception e) { - tokenSource = new char[] {}; - } - problemReporter().parseError( - this.scanner.startPosition, - this.scanner.currentPosition - 1, - tokenSource, - tokenName, - expectings); - } - } else { //the next test is HEAVILY grammar DEPENDENT. - if ((length == 2) - && (tokenName.equals(";")) //$NON-NLS-1$ - && (expectings[0] == "++") //$NON-NLS-1$ - && (expectings[1] == "--") //$NON-NLS-1$ - && (expressionPtr > -1)) { - // the ; is not the expected token ==> it ends a statement when an expression is not ended - problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]); - } else { - char[] tokenSource; - try { - tokenSource = this.scanner.getCurrentTokenSource(); - } catch (Exception e) { - tokenSource = new char[] {}; - } - problemReporter().parseError( - this.scanner.startPosition, - this.scanner.currentPosition - 1, - tokenSource, - tokenName, - expectings); - this.checkAndReportBracketAnomalies(problemReporter()); - } - } - /* reset scanner where it was */ - scanner.startPosition = startPos; - scanner.currentPosition = currentPos; -} -protected void resetModifiers() { - modifiers = AccDefault; - modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int) - scanner.commentPtr = -1; -} -/* - * Reset context so as to resume to regular parse loop - */ -protected void resetStacks() { - - astPtr = -1; - astLengthPtr = -1; - expressionPtr = -1; - expressionLengthPtr = -1; - identifierPtr = -1; - identifierLengthPtr = -1; - intPtr = -1; - nestedMethod[nestedType = 0] = 0; // need to reset for further reuse - variablesCounter[nestedType] = 0; - dimensions = 0 ; - realBlockStack[realBlockPtr = 0] = 0; - recoveredStaticInitializerStart = 0; - listLength = 0; -} -/* - * Reset context so as to resume to regular parse loop - * If unable to reset for resuming, answers false. - * - * Move checkpoint location, reset internal stacks and - * decide which grammar goal is activated. - */ -protected boolean resumeAfterRecovery() { - - // reset internal stacks - this.resetStacks(); - - /* attempt to move checkpoint location */ - if (!this.moveRecoveryCheckpoint()) return false; - - // only look for headers - if (referenceContext instanceof CompilationUnitDeclaration){ - goForHeaders(); - diet = true; // passed this point, will not consider method bodies return true; } - // does not know how to restart - return false; -} -/* - * Syntax error was detected. Will attempt to perform some recovery action in order - * to resume to the regular parse loop. - */ -protected boolean resumeOnSyntaxError() { - - /* request recovery initialization */ - if (currentElement == null){ - currentElement = - this.buildInitialRecoveryState(); // build some recovered elements - } - /* do not investigate deeper in recovery when no recovered element */ - if (currentElement == null) return false; - - /* manual forced recovery restart - after headers */ - if (restartRecovery){ - restartRecovery = false; - } - /* update recovery state with current error state of the parser */ - this.updateRecoveryState(); - - /* attempt to reset state in order to resume to parse loop */ - return this.resumeAfterRecovery(); -} -protected static int tAction(int state, int sym) { - return action[check(state + sym) == sym ? state + sym : state]; -} -public String toString() { - - String s = "identifierStack : char[][] = {"; //$NON-NLS-1$ - for (int i = 0; i <= identifierPtr; i++) { - s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$ - }; - s = s + "}\n"; //$NON-NLS-1$ - - s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$ - for (int i = 0; i <= identifierLengthPtr; i++) { - s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$ - }; - s = s + "}\n"; //$NON-NLS-1$ - - s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$ - for (int i = 0; i <= astLengthPtr; i++) { - s = s + astLengthStack[i] + ","; //$NON-NLS-1$ - }; - s = s + "}\n"; //$NON-NLS-1$ - s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ - - s = s + "intStack : int[] = {"; //$NON-NLS-1$ - for (int i = 0; i <= intPtr; i++) { - s = s + intStack[i] + ","; //$NON-NLS-1$ - }; - s = s + "}\n"; //$NON-NLS-1$ - - s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$ - for (int i = 0; i <= expressionLengthPtr; i++) { - s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$ - }; - s = s + "}\n"; //$NON-NLS-1$ - - s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ - - s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$ - return s; - -} -/* - * Update recovery state based on current parser/scanner state - */ -protected void updateRecoveryState() { - - /* expose parser state to recovery state */ - currentElement.updateFromParserState(); - - /* check and update recovered state based on current token, - this action is also performed when shifting token after recovery - got activated once. - */ - this.recoveryTokenCheck(); -} -protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) { - //fields is a definition of fields that are grouped together like in - //public int[] a, b[], c - //which results into 3 fields. - - FieldDeclaration field; - int endTypeDeclarationPosition = - -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart; - for (int i = 0; i < variableDeclaratorsCounter - 1; i++) { - //last one is special(see below) - field = (FieldDeclaration) astStack[astPtr - i - 1]; - field.endPart1Position = endTypeDeclarationPosition; - field.endPart2Position = -1 + astStack[astPtr - i].sourceStart; - } - //last one - (field = (FieldDeclaration) astStack[astPtr]).endPart1Position = - endTypeDeclarationPosition; - field.endPart2Position = field.declarationSourceEnd; - -} -protected void updateSourcePosition(Expression exp) { - //update the source Position of the expression - - //intStack : int int - //--> - //intStack : - - exp.sourceEnd = intStack[intPtr--]; - exp.sourceStart = intStack[intPtr--]; -} -} +} \ No newline at end of file