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 977cc0f..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,7642 +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 java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +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.CompilationResult; 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.AbstractVariableDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression; -import net.sourceforge.phpdt.internal.compiler.ast.AnonymousLocalTypeDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.Argument; -import net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression; -import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer; -import net.sourceforge.phpdt.internal.compiler.ast.ArrayQualifiedTypeReference; -import net.sourceforge.phpdt.internal.compiler.ast.ArrayReference; -import net.sourceforge.phpdt.internal.compiler.ast.ArrayTypeReference; -import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement; -import net.sourceforge.phpdt.internal.compiler.ast.Assignment; -import net.sourceforge.phpdt.internal.compiler.ast.AstNode; import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression; import net.sourceforge.phpdt.internal.compiler.ast.Block; -import net.sourceforge.phpdt.internal.compiler.ast.Break; -import net.sourceforge.phpdt.internal.compiler.ast.Case; -import net.sourceforge.phpdt.internal.compiler.ast.CastExpression; -import net.sourceforge.phpdt.internal.compiler.ast.CharLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess; +import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement; import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment; import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; -import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.Continue; -import net.sourceforge.phpdt.internal.compiler.ast.DefaultCase; -import net.sourceforge.phpdt.internal.compiler.ast.DoStatement; -import net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement; import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression; -import net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall; import net.sourceforge.phpdt.internal.compiler.ast.Expression; -import net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral; import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.FieldReference; -import net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.ForStatement; import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; import net.sourceforge.phpdt.internal.compiler.ast.ImportReference; -import net.sourceforge.phpdt.internal.compiler.ast.Initializer; import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression; -import net.sourceforge.phpdt.internal.compiler.ast.IntLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue; -import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement; -import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.LocalTypeDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.LongLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue; -import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.MessageSend; import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; -import net.sourceforge.phpdt.internal.compiler.ast.NameReference; -import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral; import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression; -import net.sourceforge.phpdt.internal.compiler.ast.OperatorExpression; import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds; -import net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression; -import net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression; -import net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression; -import net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference; -import net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference; -import net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference; -import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference; -import net.sourceforge.phpdt.internal.compiler.ast.Reference; import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; -import net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference; 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.SuperReference; -import net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement; -import net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement; -import net.sourceforge.phpdt.internal.compiler.ast.ThisReference; -import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement; -import net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral; -import net.sourceforge.phpdt.internal.compiler.ast.TryStatement; +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.ast.UnaryExpression; -import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement; -import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit; import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions; import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; -import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds; import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; -import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds; -import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation; +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; - -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 - protected final static int StackIncrement = 255; - protected int stateStackTop; - protected int[] stack = new int[StackIncrement]; - //scanner token - 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; - 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()); - } - } - - 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 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); - } - 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; - } - 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; - } - - //resize - System.arraycopy(chars, 0, chars = new char[ic], 0, ic); - - buildFileForTable(filename, chars); - } - private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException { - - 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); - } - - 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 - - //build from the lpg javadcl.java files that represents the parser tables - //lhs check_table asb asr symbol_index - - //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")] - - 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; - } - 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(); - } - 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 - */ - 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; - } - } - } - } - } - - 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; - } - 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 (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; - } - continue; - } - if (node instanceof ImportReference) { - ImportReference importRef = (ImportReference) node; - element = element.add(importRef, 0); - lastCheckPoint = importRef.declarationSourceEnd + 1; - } - } - 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; - } - 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; - } - } - 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(); - } 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); - } - } - 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; - } - 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]); - } - 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--; - } - - 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; - } - 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; - } - } - 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); - } - } else { - expressionStack[expressionPtr] = - new BinaryExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op); - } - } - } - } - 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; - 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; - } - } - protected void consumeClassHeaderName() { - // ClassHeaderName ::= Modifiersopt 'class' 'Identifier' - TypeDeclaration typeDecl; - if (nestedMethod[nestedType] == 0) { - if (nestedType != 0) { - typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult); - } else { - typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); - } - } 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; - } - } - 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(); - } - } - - // 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; - } - - //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; - } - } - - // 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)); - } - } - 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); - } - 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); - } - - 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); - } 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; - } - - 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; - } else { - declaration.type = this.copyDims(type, dimension); - } - } - 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; - 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); - } - 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; - } - } - // 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); - } - - 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); - } else { - typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult); - } - } 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--; - } - - 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); - } - - // 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); - } - if (currentToken == TokenNameLBRACE) { - md.bodyStart = endPosition + 1; - } - // 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; - } 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; - } - - //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); - } - - 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); - } - } - 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--] }; - } 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--]; - } - } - } - //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); - } else { - astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition); - } - } - } - 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); - } - } - } 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); - } 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; - } - 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++; - } else { - if (astNode instanceof TypeDeclaration) { - flag[i] = 4; - size3++; - } else { - //field - flag[i] = 1; - size1++; - } - } - } - - //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); - break; - case 3 : - size2 += (length2 = end - start); - System.arraycopy(astStack, astPtr + start + 1, typeDecl.methods, size2 - length2, length2); - break; - case 4 : - size3 += (length2 = end - start); - System.arraycopy(astStack, astPtr + start + 1, typeDecl.memberTypes, size3 - length2, length2); - break; - }; - flagI = flag[start = end]; - } - } - - if (typeDecl.memberTypes != null) { - for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) { - typeDecl.memberTypes[i].enclosingType = typeDecl; - } - } - } - 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 (scanner.recordLineSeparator) { - compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); - } - 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; - } - 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++; - } - } - } - // 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); - } - 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++; - } - } - 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 - } - } - 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); - } - } - 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--]); - } 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; - 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 ./ - - SwitchBlockStatements -> SwitchBlockStatement - SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement - /.$putCase consumeSwitchBlockStatements() ; $break ./ - - SwitchBlockStatement ::= SwitchLabels BlockStatements - /.$putCase consumeSwitchBlockStatement() ; $break ./ - - SwitchLabels -> SwitchLabel - SwitchLabels ::= SwitchLabels SwitchLabel - /.$putCase consumeSwitchLabels() ; $break ./ - - SwitchLabel ::= 'case' ConstantExpression ':' - /. $putCase consumeCaseLabel(); $break ./ - - SwitchLabel ::= 'default' ':' - /. $putCase consumeDefaultLabel(); $break ./ - - WhileStatement ::= 'while' '(' Expression ')' Statement - /.$putCase consumeStatementWhile() ; $break ./ - - WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf - /.$putCase consumeStatementWhile() ; $break ./ - - DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';' - /.$putCase consumeStatementDo() ; $break ./ - - ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement - /.$putCase consumeStatementFor() ; $break ./ - ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf - /.$putCase consumeStatementFor() ; $break ./ - - --the minus one allows to avoid a stack-to-stack transfer - ForInit ::= StatementExpressionList - /.$putCase consumeForInit() ; $break ./ - ForInit -> LocalVariableDeclaration - - ForUpdate -> StatementExpressionList - - StatementExpressionList -> StatementExpression - StatementExpressionList ::= StatementExpressionList ',' StatementExpression - /.$putCase consumeStatementExpressionList() ; $break ./ - - -- 1.4 feature - AssertStatement ::= 'assert' Expression ';' - /.$putCase consumeSimpleAssertStatement() ; $break ./ - - AssertStatement ::= 'assert' Expression ':' Expression ';' - /.$putCase consumeAssertStatement() ; $break ./ - - BreakStatement ::= 'break' ';' - /.$putCase consumeStatementBreak() ; $break ./ - - BreakStatement ::= 'break' Identifier ';' - /.$putCase consumeStatementBreakWithLabel() ; $break ./ - - ContinueStatement ::= 'continue' ';' - /.$putCase consumeStatementContinue() ; $break ./ - - ContinueStatement ::= 'continue' Identifier ';' - /.$putCase consumeStatementContinueWithLabel() ; $break ./ - - ReturnStatement ::= 'return' Expressionopt ';' - /.$putCase consumeStatementReturn() ; $break ./ - - ThrowStatement ::= 'throw' Expression ';' - /.$putCase consumeStatementThrow(); - $break ./ - - SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block - /.$putCase consumeStatementSynchronized(); $break ./ - OnlySynchronized ::= 'synchronized' - /.$putCase consumeOnlySynchronized(); $break ./ - - - TryStatement ::= 'try' Block Catches - /.$putCase consumeStatementTry(false); $break ./ - TryStatement ::= 'try' Block Catchesopt Finally - /.$putCase consumeStatementTry(true); $break ./ - - Catches -> CatchClause - Catches ::= Catches CatchClause - /.$putCase consumeCatches(); $break ./ - - CatchClause ::= 'catch' '(' FormalParameter ')' Block - /.$putCase consumeStatementCatch() ; $break ./ - - Finally ::= 'finally' Block - - --18.12 Productions from 14: Expressions - - --for source positionning purpose - PushLPAREN ::= '(' - /.$putCase consumeLeftParen(); $break ./ - PushRPAREN ::= ')' - /.$putCase consumeRightParen(); $break ./ - - Primary -> PrimaryNoNewArray - Primary -> ArrayCreationExpression - - PrimaryNoNewArray -> Literal - PrimaryNoNewArray ::= 'this' - /.$putCase consumePrimaryNoNewArrayThis(); $break ./ - - PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN - /.$putCase consumePrimaryNoNewArray(); $break ./ - - PrimaryNoNewArray -> ClassInstanceCreationExpression - PrimaryNoNewArray -> FieldAccess - --1.1 feature - PrimaryNoNewArray ::= Name '.' 'this' - /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./ - PrimaryNoNewArray ::= Name '.' 'super' - /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./ - - --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 ./ - - PrimaryNoNewArray ::= ArrayType '.' 'class' - /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./ - - PrimaryNoNewArray ::= PrimitiveType '.' 'class' - /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./ - - PrimaryNoNewArray -> MethodInvocation - PrimaryNoNewArray -> ArrayAccess - - --1.1 feature - -- - -- In Java 1.0 a ClassBody could not appear at all in a - -- ClassInstanceCreationExpression. - -- - - AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')' - /.$putCase consumeAllocationHeader(); $break ./ - - ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt - /.$putCase consumeClassInstanceCreationExpression(); $break ./ - --1.1 feature - - ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt - /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ - - --1.1 feature - ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt - /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./ - - 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 - - /* - 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--; - } - - //statements - if (hasBody) { - realBlockPtr--; - } - - int length; - if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) { - astPtr -= length; - } - } - protected void ignoreMethodBody() { - // InterfaceMemberDeclaration ::= InvalidMethodDeclaration - - /* - 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; - } - - //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); - - 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; - } - } - 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. - */ - - 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 (;;) { - try { - stack[++stateStackTop] = act; - } 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(); - } - - if (cd.constructorCall.sourceEnd == 0) { - cd.constructorCall.sourceEnd = cd.sourceEnd; - cd.constructorCall.sourceStart = cd.sourceStart; - } - } - // 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]++; - - referenceContext = type; - compilationUnit = unit; - - scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning { - try { - parse(); - } catch (AbortCompilation ex) { - lastAct = ERROR_ACTION; - } finally { - nestedMethod[nestedType]--; - } - - 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; - - 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]--; - } - - if (lastAct == ERROR_ACTION) { - return; - } - - //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 - } - 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; - } - - 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; - } - - 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; - } - } - 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) { - } - } - - //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$ - - // convert bytes into chars - char[] chars = new char[length / 2]; - int i = 0; - int charIndex = 0; - - 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; - } - } - } - } - 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--]; - } -} +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]; + + 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; + + int token; + + protected int modifiers; + + protected int modifiersSourceStart; + + protected Parser(ProblemReporter problemReporter) { + this.problemReporter = problemReporter; + this.options = problemReporter.options; + this.token = TokenNameEOF; + this.initializeScanner(); + } + + public void setFileToParse(IFile fileToParse) { + this.token = TokenNameEOF; + this.initializeScanner(); + } + + /** + * 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); + } + + /** + * 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); + } + + private void reportSyntaxError(String error) { + int problemStartPosition = scanner.getCurrentTokenStartPosition(); + int problemEndPosition = scanner.getCurrentTokenEndPosition(); + reportSyntaxError(error, problemStartPosition, problemEndPosition + 1); + } + + private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { + if (referenceContext != null) { + problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, + compilationUnit.compilationResult); + } + } + + // private void reportSyntaxWarning(String error, int problemStartPosition, + // int problemEndPosition) { + // if (referenceContext != null) { + // problemReporter.phpParsingWarning(new String[] { error }, + // problemStartPosition, problemEndPosition, referenceContext, + // compilationUnit.compilationResult); + // } + // } + + /** + * 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; + } + + 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); + } + + /** + * 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(); + } + + /** + * 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); + + endParse(0); + } + + /** + * 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); + } + + /** + * Parses a string with php tags i.e. '<body> <?php phpinfo() ?> + * </body>' + */ + 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; + } + } + } + + 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 (scanner.recordLineSeparator) { + compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds(); + } + 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]); + } + } + compilationUnit.imports = new ImportReference[includesList.size()]; + for (int i = 0; i < includesList.size(); i++) { + compilationUnit.imports[i] = (ImportReference) includesList.get(i); + } + return compilationUnit; + } + + 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 (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; + } + } + } 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; + } + 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."); + } + } + + 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 (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + expressionList(); + if (token == TokenNameSEMICOLON) { + getNextToken(); + } else { + throwSyntaxError("';' expected after 'for'."); + } + } + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + expressionList(); + if (token == TokenNameRPAREN) { + getNextToken(); + } else { + throwSyntaxError("')' expected after 'for'."); + } + } + 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(); + } + 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(); + } + } + } + // 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 { + statement(); + } + } + + 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(); + } + } + + 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(); + } + } + + private void foreach_variable() { + // w_variable + // | '&' w_variable + if (token == TokenNameAND) { + getNextToken(); + } + w_variable(true); + } + + private void foreach_optional_arg() { + // /* empty */ + // | T_DOUBLE_ARROW foreach_variable + if (token == TokenNameEQUAL_GREATER) { + getNextToken(); + foreach_variable(); + } + } + + 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(); + } + } + + 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 { + r_variable(); + } + } + } + + 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; + } + } + } + + 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(); + } + } + + 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 { + // 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."); + } + } + + 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"); + } + } + + // 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(); + } + } + + private void implements_list(TypeDeclaration typeDecl) { + // /* empty */ + // | T_IMPLEMENTS interface_list + if (token == TokenNameimplements) { + getNextToken(); + interface_list(); + } + } + + 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); + } + } + } + + 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(); + } + } + + // 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; + } + + 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(); + } + + private void functionDefinition(MethodDeclaration methodDecl) { + boolean isAbstract = false; + if (astPtr == 0) { + if (compilationUnit != null) { + compilationUnit.types.add(methodDecl); + } + } else { + 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); + } + } + } + + 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 { + methodDecl.selector = "".toCharArray(); + methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1; + throwSyntaxError("Function name expected after keyword 'function'."); + } + } + + // + 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 (!empty_allowed) { + throwSyntaxError("Identifier expected in parameter list."); + } + } + + 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."); + } + 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); + } + + 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 { + iState.sourceEnd = scanner.getCurrentTokenEndPosition(); + getNextToken(); + } + } + + 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(); + } + + 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); + } + } + } + } + + 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); + } + 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); + } + 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 { + iState.checkUnreachable = false; + } + iState.sourceEnd = scanner.getCurrentTokenStartPosition(); + } + + 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; + } + } + + private Block inner_statement_list() { + // inner_statement_list inner_statement + // /* empty */ + return statementList(); + } + + /** + * @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 { + if (!(s instanceof ReturnStatement) && !(s instanceof ContinueStatement) && !(s instanceof BreakStatement)) { + if (!(s instanceof IfStatement) || !((IfStatement) s).checkUnreachable) { + iState.checkUnreachable = false; + } + } + } + } + + // 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 { + // '{' [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(); + } + } + + 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(); + } + } + + 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 { + statement(); + } + } + + 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 { + 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 { + 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); + // } + } + + 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 TokenNameAND_AND: + getNextToken(); + expression = new AND_AND_Expression(expression, expr(), token); + break; + case TokenNameEQUAL_EQUAL: + getNextToken(); + expression = new EqualExpression(expression, expr(), token); + break; + 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; + } + } + + 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; + } + + 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(); + } + } + + 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(); + } + } + + 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(); + } + } + + 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(); + } + } + + private void assignment_list() { + // assignment_list: + // assignment_list ',' assignment_list_element + // | assignment_list_element + while (true) { + assignment_list_element(); + if (token != TokenNameCOMMA) { + break; + } + getNextToken(); + } + } + + 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."); + } + } + } + } + + 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(); + } + } + + 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; + } + } + } + + // 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 = 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; + } + + // 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(); + } + } + + private void fully_qualified_class_name() { + if (token == TokenNameIdentifier) { + getNextToken(); + } else { + throwSyntaxError("Class name expected."); + } + } + + 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); + } + + 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); + } + + 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; + } + + // 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; + } + + 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(); + } + } + + 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; + } + } + } + + 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(); + } + } + + private void r_variable() { + variable(false, false); + } + + private void w_variable(boolean lefthandside) { + variable(lefthandside, false); + } + + private void rw_variable() { + variable(false, false); + } + + 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; + } + + private void variable_properties() { + // variable_properties: + // variable_properties variable_property + // | /* empty */ + while (token == TokenNameMINUS_GREATER) { + variable_property(); + } + } + + 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."); + } + } + + 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); + } + + 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(); + + 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; + } + + 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(); + } + } + + 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; + } + } + + /** + * 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 + } + } + } + } + } + } + + 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; + } + } + } + + 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."); + } + } + + 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; + } + } + } + + // 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; + // } + + public static final int RoundBracket = 0; + + public static final int SquareBracket = 1; + + public static final int CurlyBracket = 2; + + public static final int BracketKinds = 3; + + protected int[] nestedMethod; // the ptr is nestedType + + protected int nestedType, dimensions; + + // variable set stack + final static int VariableStackIncrement = 10; + + HashMap fTypeVariables = null; + + HashMap fMethodVariables = null; + + ArrayList fStackUnassigned = new ArrayList(); + + // ast stack + final static int AstStackIncrement = 100; + + protected int astPtr; + + protected ASTNode[] astStack = new ASTNode[AstStackIncrement]; + + protected int astLengthPtr; + + protected int[] astLengthStack; + + ASTNode[] noAstNodes = new ASTNode[AstStackIncrement]; + + public CompilationUnitDeclaration compilationUnit; /* + * the result from parse() + */ + + protected ReferenceContext referenceContext; + + protected ProblemReporter problemReporter; + + protected CompilerOptions options; + + private ArrayList includesList; + + // 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; + } + + /* + * 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 = 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 { + 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 + */ + 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; + } + } + + 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(); + } + + this.compilationUnit.currentPackage = impt = new ImportReference(tokens, new char[0], 0, 0, true); + + impt.declarationSourceStart = 0; + impt.declarationSourceEnd = 0; + impt.declarationEnd = 0; + // endPosition is just before the ; + + } + + public final static String[] GLOBALS = { "$this", "$_COOKIE", "$_ENV", "$_FILES", "$_GET", "$GLOBALS", "$_POST", "$_REQUEST", + "$_SESSION", "$_SERVER" }; + + /** + * + */ + 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); + } + + private void pushIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + HashSet set = new HashSet(); + fStackUnassigned.add(set); + } + } + + private HashSet removeIfVariableSet() { + if (!fStackUnassigned.isEmpty()) { + return (HashSet) fStackUnassigned.remove(fStackUnassigned.size() - 1); + } + return null; + } + + /** + * 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; + } + + /** + * 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())); + } + } + + /** + * 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())); + } + } + + /** + * 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)); + } + } + + /** + * 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()); + } + + private boolean containsVariableSet(char[] token) { + + 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; + } + return true; + } +} \ No newline at end of file