1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
13 import java.io.BufferedInputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
19 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
20 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
21 import net.sourceforge.phpdt.internal.compiler.CompilationResult;
22 import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression;
23 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
24 import net.sourceforge.phpdt.internal.compiler.ast.AbstractVariableDeclaration;
25 import net.sourceforge.phpdt.internal.compiler.ast.AllocationExpression;
26 import net.sourceforge.phpdt.internal.compiler.ast.AnonymousLocalTypeDeclaration;
27 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
28 import net.sourceforge.phpdt.internal.compiler.ast.ArrayAllocationExpression;
29 import net.sourceforge.phpdt.internal.compiler.ast.ArrayInitializer;
30 import net.sourceforge.phpdt.internal.compiler.ast.ArrayQualifiedTypeReference;
31 import net.sourceforge.phpdt.internal.compiler.ast.ArrayReference;
32 import net.sourceforge.phpdt.internal.compiler.ast.ArrayTypeReference;
33 import net.sourceforge.phpdt.internal.compiler.ast.AssertStatement;
34 import net.sourceforge.phpdt.internal.compiler.ast.Assignment;
35 import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
36 import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression;
37 import net.sourceforge.phpdt.internal.compiler.ast.Block;
38 import net.sourceforge.phpdt.internal.compiler.ast.Break;
39 import net.sourceforge.phpdt.internal.compiler.ast.Case;
40 import net.sourceforge.phpdt.internal.compiler.ast.CastExpression;
41 import net.sourceforge.phpdt.internal.compiler.ast.CharLiteral;
42 import net.sourceforge.phpdt.internal.compiler.ast.ClassLiteralAccess;
43 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
44 import net.sourceforge.phpdt.internal.compiler.ast.CompoundAssignment;
45 import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression;
46 import net.sourceforge.phpdt.internal.compiler.ast.ConstructorDeclaration;
47 import net.sourceforge.phpdt.internal.compiler.ast.Continue;
48 import net.sourceforge.phpdt.internal.compiler.ast.DefaultCase;
49 import net.sourceforge.phpdt.internal.compiler.ast.DoStatement;
50 import net.sourceforge.phpdt.internal.compiler.ast.DoubleLiteral;
51 import net.sourceforge.phpdt.internal.compiler.ast.EmptyStatement;
52 import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression;
53 import net.sourceforge.phpdt.internal.compiler.ast.ExplicitConstructorCall;
54 import net.sourceforge.phpdt.internal.compiler.ast.Expression;
55 import net.sourceforge.phpdt.internal.compiler.ast.FalseLiteral;
56 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
57 import net.sourceforge.phpdt.internal.compiler.ast.FieldReference;
58 import net.sourceforge.phpdt.internal.compiler.ast.FloatLiteral;
59 import net.sourceforge.phpdt.internal.compiler.ast.ForStatement;
60 import net.sourceforge.phpdt.internal.compiler.ast.IfStatement;
61 import net.sourceforge.phpdt.internal.compiler.ast.ImportReference;
62 import net.sourceforge.phpdt.internal.compiler.ast.Initializer;
63 import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression;
64 import net.sourceforge.phpdt.internal.compiler.ast.IntLiteral;
65 import net.sourceforge.phpdt.internal.compiler.ast.IntLiteralMinValue;
66 import net.sourceforge.phpdt.internal.compiler.ast.LabeledStatement;
67 import net.sourceforge.phpdt.internal.compiler.ast.LocalDeclaration;
68 import net.sourceforge.phpdt.internal.compiler.ast.LocalTypeDeclaration;
69 import net.sourceforge.phpdt.internal.compiler.ast.LongLiteral;
70 import net.sourceforge.phpdt.internal.compiler.ast.LongLiteralMinValue;
71 import net.sourceforge.phpdt.internal.compiler.ast.MemberTypeDeclaration;
72 import net.sourceforge.phpdt.internal.compiler.ast.MessageSend;
73 import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration;
74 import net.sourceforge.phpdt.internal.compiler.ast.NameReference;
75 import net.sourceforge.phpdt.internal.compiler.ast.NullLiteral;
76 import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression;
77 import net.sourceforge.phpdt.internal.compiler.ast.OperatorExpression;
78 import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds;
79 import net.sourceforge.phpdt.internal.compiler.ast.PostfixExpression;
80 import net.sourceforge.phpdt.internal.compiler.ast.PrefixExpression;
81 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedAllocationExpression;
82 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedNameReference;
83 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedSuperReference;
84 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedThisReference;
85 import net.sourceforge.phpdt.internal.compiler.ast.QualifiedTypeReference;
86 import net.sourceforge.phpdt.internal.compiler.ast.Reference;
87 import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement;
88 import net.sourceforge.phpdt.internal.compiler.ast.SingleNameReference;
89 import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference;
90 import net.sourceforge.phpdt.internal.compiler.ast.Statement;
91 import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral;
92 import net.sourceforge.phpdt.internal.compiler.ast.SuperReference;
93 import net.sourceforge.phpdt.internal.compiler.ast.SwitchStatement;
94 import net.sourceforge.phpdt.internal.compiler.ast.SynchronizedStatement;
95 import net.sourceforge.phpdt.internal.compiler.ast.ThisReference;
96 import net.sourceforge.phpdt.internal.compiler.ast.ThrowStatement;
97 import net.sourceforge.phpdt.internal.compiler.ast.TrueLiteral;
98 import net.sourceforge.phpdt.internal.compiler.ast.TryStatement;
99 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
100 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
101 import net.sourceforge.phpdt.internal.compiler.ast.UnaryExpression;
102 import net.sourceforge.phpdt.internal.compiler.ast.WhileStatement;
103 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
104 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
105 import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
106 import net.sourceforge.phpdt.internal.compiler.lookup.BindingIds;
107 import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers;
108 import net.sourceforge.phpdt.internal.compiler.lookup.TypeIds;
109 import net.sourceforge.phpdt.internal.compiler.problem.AbortCompilation;
110 import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
111 import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities;
112 import net.sourceforge.phpdt.internal.compiler.util.Util;
114 public class Parser implements BindingIds, ParserBasicInformation, ITerminalSymbols, CompilerModifiers, OperatorIds, TypeIds {
115 protected ProblemReporter problemReporter;
116 public int firstToken; // handle for multiple parsing goals
117 public int lastAct; //handle for multiple parsing goals
118 protected ReferenceContext referenceContext;
119 public int currentToken;
120 private int synchronizedBlockSourceStart;
122 //error recovery management
123 protected int lastCheckPoint;
124 protected RecoveredElement currentElement;
125 public static boolean VERBOSE_RECOVERY = false;
126 protected boolean restartRecovery;
127 protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
128 protected boolean hasReportedError;
129 protected int recoveredStaticInitializerStart;
130 protected int lastIgnoredToken, nextIgnoredToken;
131 protected int lastErrorEndPosition;
134 protected boolean assertMode = false;
136 //internal data for the automat
137 protected final static int StackIncrement = 255;
138 protected int stateStackTop;
139 protected int[] stack = new int[StackIncrement];
141 public Scanner scanner;
143 final static int AstStackIncrement = 100;
144 protected int astPtr;
145 protected AstNode[] astStack = new AstNode[AstStackIncrement];
146 protected int astLengthPtr;
147 protected int[] astLengthStack;
148 public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
149 AstNode[] noAstNodes = new AstNode[AstStackIncrement];
151 final static int ExpressionStackIncrement = 100;
152 protected int expressionPtr;
153 protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
154 protected int expressionLengthPtr;
155 protected int[] expressionLengthStack;
156 Expression[] noExpressions = new Expression[ExpressionStackIncrement];
158 protected int identifierPtr;
159 protected char[][] identifierStack;
160 protected int identifierLengthPtr;
161 protected int[] identifierLengthStack;
162 protected long[] identifierPositionStack;
163 //positions , dimensions , .... (what ever is int) ..... stack
164 protected int intPtr;
165 protected int[] intStack;
166 protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
167 protected int endStatementPosition;
168 protected int lParenPos, rParenPos; //accurate only when used !
169 //modifiers dimensions nestedType etc.......
170 protected boolean optimizeStringLiterals = true;
171 protected int modifiers;
172 protected int modifiersSourceStart;
173 protected int nestedType, dimensions;
174 protected int[] nestedMethod; //the ptr is nestedType
175 protected int[] realBlockStack;
176 protected int realBlockPtr;
177 protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
178 protected int dietInt = 0;
179 // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
180 protected int[] variablesCounter;
181 //===DATA===DATA===DATA===DATA===DATA===DATA===//
182 public final static byte rhs[] =
622 public static char asb[] = null;
623 public static char asr[] = null;
624 public static char symbol_index[] = null;
625 private static final String UNEXPECTED_EOF = "Unexpected End Of File"; //$NON-NLS-1$
627 public final static String name[] = { null, "++",
647 ">>>=", //$NON-NLS-1$
675 "$empty", //$NON-NLS-1$
676 "Identifier", //$NON-NLS-1$
677 "abstract", //$NON-NLS-1$
678 "assert", //$NON-NLS-1$
679 "boolean", //$NON-NLS-1$
680 "break", //$NON-NLS-1$
681 "byte", //$NON-NLS-1$
682 "case", //$NON-NLS-1$
683 "catch", //$NON-NLS-1$
684 "char", //$NON-NLS-1$
685 "class", //$NON-NLS-1$
686 "continue", //$NON-NLS-1$
687 "default", //$NON-NLS-1$
689 "double", //$NON-NLS-1$
690 "else", //$NON-NLS-1$
691 "extends", //$NON-NLS-1$
692 "false", //$NON-NLS-1$
693 "final", //$NON-NLS-1$
694 "finally", //$NON-NLS-1$
695 "float", //$NON-NLS-1$
698 "implements", //$NON-NLS-1$
699 "import", //$NON-NLS-1$
700 "instanceof", //$NON-NLS-1$
702 "interface", //$NON-NLS-1$
703 "long", //$NON-NLS-1$
704 "native", //$NON-NLS-1$
706 "null", //$NON-NLS-1$
707 "package", //$NON-NLS-1$
708 "private", //$NON-NLS-1$
709 "protected", //$NON-NLS-1$
710 "public", //$NON-NLS-1$
711 "return", //$NON-NLS-1$
712 "short", //$NON-NLS-1$
713 "static", //$NON-NLS-1$
714 "strictfp", //$NON-NLS-1$
715 "super", //$NON-NLS-1$
716 "switch", //$NON-NLS-1$
717 "synchronized", //$NON-NLS-1$
718 "this", //$NON-NLS-1$
719 "throw", //$NON-NLS-1$
720 "throws", //$NON-NLS-1$
721 "transient", //$NON-NLS-1$
722 "true", //$NON-NLS-1$
724 "void", //$NON-NLS-1$
725 "volatile", //$NON-NLS-1$
726 "while", //$NON-NLS-1$
727 "IntegerLiteral", //$NON-NLS-1$
728 "LongLiteral", //$NON-NLS-1$
729 "FloatingPointLiteral", //$NON-NLS-1$
730 "DoubleLiteral", //$NON-NLS-1$
731 "CharacterLiteral", //$NON-NLS-1$
732 "StringLiteral", //$NON-NLS-1$
733 UNEXPECTED_EOF, "Invalid Character",
735 "Goal", //$NON-NLS-1$
736 "MethodBody", //$NON-NLS-1$
737 "ConstructorBody", //$NON-NLS-1$
738 "StaticInitializer", //$NON-NLS-1$
739 "Initializer", //$NON-NLS-1$
740 "Headers", //$NON-NLS-1$
741 "BlockStatements", //$NON-NLS-1$
742 "MethodPushModifiersHeader", //$NON-NLS-1$
743 "CatchHeader", //$NON-NLS-1$
744 "FieldDeclaration", //$NON-NLS-1$
745 "ImportDeclaration", //$NON-NLS-1$
746 "PackageDeclaration", //$NON-NLS-1$
747 "TypeDeclaration", //$NON-NLS-1$
748 "GenericMethodDeclaration", //$NON-NLS-1$
749 "ClassBodyDeclaration", //$NON-NLS-1$
750 "Expression", //$NON-NLS-1$
751 "Type", //$NON-NLS-1$
752 "PrimitiveType", //$NON-NLS-1$
753 "ReferenceType", //$NON-NLS-1$
754 "ClassOrInterfaceType", //$NON-NLS-1$
755 "ArrayType", //$NON-NLS-1$
756 "Name", //$NON-NLS-1$
757 "Dims", //$NON-NLS-1$
758 "ClassType", //$NON-NLS-1$
759 "SimpleName", //$NON-NLS-1$
760 "Header", //$NON-NLS-1$
761 "ClassHeader", //$NON-NLS-1$
762 "InterfaceHeader", //$NON-NLS-1$
763 "MethodHeader", //$NON-NLS-1$
764 "ConstructorHeader", //$NON-NLS-1$
765 "FormalParameter", //$NON-NLS-1$
766 "ImportDeclarations", //$NON-NLS-1$
767 "TypeDeclarations", //$NON-NLS-1$
768 "PackageDeclarationName", //$NON-NLS-1$
769 "SingleTypeImportDeclarationName", //$NON-NLS-1$
770 "TypeImportOnDemandDeclarationName", //$NON-NLS-1$
771 "Modifiers", //$NON-NLS-1$
772 "Modifier", //$NON-NLS-1$
773 "ClassBody", //$NON-NLS-1$
774 "ClassHeaderName", //$NON-NLS-1$
775 "InterfaceTypeList", //$NON-NLS-1$
776 "InterfaceType", //$NON-NLS-1$
777 "ClassBodyDeclarations", //$NON-NLS-1$
778 "Block", //$NON-NLS-1$
779 "VariableDeclarators", //$NON-NLS-1$
780 "VariableDeclarator", //$NON-NLS-1$
781 "VariableDeclaratorId", //$NON-NLS-1$
782 "VariableInitializer", //$NON-NLS-1$
783 "ArrayInitializer", //$NON-NLS-1$
784 "MethodHeaderName", //$NON-NLS-1$
785 "MethodHeaderParameters", //$NON-NLS-1$
786 "MethodPushModifiersHeaderName", //$NON-NLS-1$
787 "ClassTypeList", //$NON-NLS-1$
788 "ConstructorHeaderName", //$NON-NLS-1$
789 "FormalParameterList", //$NON-NLS-1$
790 "ClassTypeElt", //$NON-NLS-1$
791 "StaticOnly", //$NON-NLS-1$
792 "ExplicitConstructorInvocation", //$NON-NLS-1$
793 "Primary", //$NON-NLS-1$
794 "InterfaceBody", //$NON-NLS-1$
795 "InterfaceHeaderName", //$NON-NLS-1$
796 "InterfaceMemberDeclarations", //$NON-NLS-1$
797 "InterfaceMemberDeclaration", //$NON-NLS-1$
798 "VariableInitializers", //$NON-NLS-1$
799 "BlockStatement", //$NON-NLS-1$
800 "Statement", //$NON-NLS-1$
801 "LocalVariableDeclaration", //$NON-NLS-1$
802 "StatementWithoutTrailingSubstatement", //$NON-NLS-1$
803 "StatementNoShortIf", //$NON-NLS-1$
804 "StatementExpression", //$NON-NLS-1$
805 "PostIncrementExpression", //$NON-NLS-1$
806 "PostDecrementExpression", //$NON-NLS-1$
807 "MethodInvocation", //$NON-NLS-1$
808 "ClassInstanceCreationExpression", //$NON-NLS-1$
809 "SwitchBlock", //$NON-NLS-1$
810 "SwitchBlockStatements", //$NON-NLS-1$
811 "SwitchLabels", //$NON-NLS-1$
812 "SwitchBlockStatement", //$NON-NLS-1$
813 "SwitchLabel", //$NON-NLS-1$
814 "ConstantExpression", //$NON-NLS-1$
815 "StatementExpressionList", //$NON-NLS-1$
816 "OnlySynchronized", //$NON-NLS-1$
817 "Catches", //$NON-NLS-1$
818 "Finally", //$NON-NLS-1$
819 "CatchClause", //$NON-NLS-1$
820 "PushLPAREN", //$NON-NLS-1$
821 "PushRPAREN", //$NON-NLS-1$
822 "PrimaryNoNewArray", //$NON-NLS-1$
823 "FieldAccess", //$NON-NLS-1$
824 "ArrayAccess", //$NON-NLS-1$
825 "ClassInstanceCreationExpressionName", //$NON-NLS-1$
826 "ArgumentList", //$NON-NLS-1$
827 "DimWithOrWithOutExprs", //$NON-NLS-1$
828 "DimWithOrWithOutExpr", //$NON-NLS-1$
829 "DimsLoop", //$NON-NLS-1$
830 "OneDimLoop", //$NON-NLS-1$
831 "PostfixExpression", //$NON-NLS-1$
832 "UnaryExpression", //$NON-NLS-1$
833 "UnaryExpressionNotPlusMinus", //$NON-NLS-1$
834 "MultiplicativeExpression", //$NON-NLS-1$
835 "AdditiveExpression", //$NON-NLS-1$
836 "ShiftExpression", //$NON-NLS-1$
837 "RelationalExpression", //$NON-NLS-1$
838 "EqualityExpression", //$NON-NLS-1$
839 "AndExpression", //$NON-NLS-1$
840 "ExclusiveOrExpression", //$NON-NLS-1$
841 "InclusiveOrExpression", //$NON-NLS-1$
842 "ConditionalAndExpression", //$NON-NLS-1$
843 "ConditionalOrExpression", //$NON-NLS-1$
844 "ConditionalExpression", //$NON-NLS-1$
845 "AssignmentExpression", //$NON-NLS-1$
846 "LeftHandSide", //$NON-NLS-1$
847 "AssignmentOperator" //$NON-NLS-1$
850 public static short check_table[] = null;
851 public static char lhs[] = null;
852 public static char action[] = lhs;
853 private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
858 } catch (java.io.IOException ex) {
859 throw new ExceptionInInitializerError(ex.getMessage());
863 public static final int RoundBracket = 0;
864 public static final int SquareBracket = 1;
865 public static final int CurlyBracket = 2;
866 public static final int BracketKinds = 3;
868 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) {
870 this.problemReporter = problemReporter;
871 this.optimizeStringLiterals = optimizeStringLiterals;
872 this.assertMode = assertMode;
873 this.initializeScanner();
874 astLengthStack = new int[50];
875 expressionLengthStack = new int[30];
876 intStack = new int[50];
877 identifierStack = new char[30][];
878 identifierLengthStack = new int[30];
879 nestedMethod = new int[30];
880 realBlockStack = new int[30];
881 identifierPositionStack = new long[30];
882 variablesCounter = new int[30];
888 protected void adjustInterfaceModifiers() {
889 intStack[intPtr - 1] |= AccInterface;
891 public final void arrayInitializer(int length) {
892 //length is the size of the array Initializer
893 //expressionPtr points on the last elt of the arrayInitializer
894 //i.e. it has not been decremented yet.
896 ArrayInitializer ai = new ArrayInitializer();
898 expressionPtr -= length;
899 System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
901 pushOnExpressionStack(ai);
903 ai.sourceEnd = endStatementPosition;
904 int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart;
906 //does not work with comments(that contain '{') nor '{' describes as a unicode....
907 while (scanner.source[--searchPosition] != '{') {
909 } catch (IndexOutOfBoundsException ex) {
910 //should never occur (except for strange cases like whose describe above)
911 searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1;
913 ai.sourceStart = searchPosition;
915 protected static int asi(int state) {
917 return asb[original_state(state)];
919 protected void blockReal() {
920 // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
921 // increment the amount of declared variables for this block
922 realBlockStack[realBlockPtr]++;
924 private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort)
925 throws java.io.IOException {
927 //transform the String tokens into chars before dumping then into file
931 while (!tokens[i++].equals(tag)) {
934 char[] chars = new char[tokens.length]; //can't be bigger
937 while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
938 int c = Integer.parseInt(token);
941 chars[ic++] = (char) c;
945 System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
947 buildFileForTable(filename, chars);
949 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
951 byte[] bytes = new byte[chars.length * 2];
952 for (int i = 0; i < chars.length; i++) {
953 bytes[2 * i] = (byte) (chars[i] >>> 8);
954 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
957 java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
960 System.out.println(filename + " creation complete"); //$NON-NLS-1$
962 public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException {
964 //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
966 //build from the lpg javadcl.java files that represents the parser tables
967 //lhs check_table asb asr symbol_index
969 //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
971 char[] contents = new char[] {
974 contents = Util.getFileCharContent(new File(dataFilename), null);
975 } catch (IOException ex) {
976 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
979 java.util.StringTokenizer st = new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;"); //$NON-NLS-1$
980 String[] tokens = new String[st.countTokens()];
982 while (st.hasMoreTokens()) {
983 tokens[i++] = st.nextToken();
985 final String prefix = FILEPREFIX;
987 buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
988 buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$
989 buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
990 buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
991 buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
992 System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
995 * Build initial recovery state.
996 * Recovery state is inferred from the current state of the parser (reduced node stack).
998 public RecoveredElement buildInitialRecoveryState() {
1000 /* initialize recovery by retrieving available reduced nodes
1001 * also rebuild bracket balance
1005 RecoveredElement element = null;
1006 if (referenceContext instanceof CompilationUnitDeclaration) {
1007 element = new RecoveredUnit(compilationUnit, 0, this);
1009 /* ignore current stack state, since restarting from the beginnning
1010 since could not trust simple brace count */
1011 if (true) { // experimenting restart recovery from scratch
1012 compilationUnit.currentPackage = null;
1013 compilationUnit.imports = null;
1014 compilationUnit.types = null;
1019 if (compilationUnit.currentPackage != null) {
1020 lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd + 1;
1022 if (compilationUnit.imports != null) {
1023 lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length - 1].declarationSourceEnd + 1;
1026 if (referenceContext instanceof AbstractMethodDeclaration) {
1027 element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this);
1028 lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart;
1030 /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
1031 if (referenceContext instanceof TypeDeclaration) {
1032 TypeDeclaration type = (TypeDeclaration) referenceContext;
1033 for (int i = 0; i < type.fields.length; i++) {
1034 FieldDeclaration field = type.fields[i];
1035 if (!field.isField()
1036 && field.declarationSourceStart <= scanner.initialPosition
1037 && scanner.initialPosition <= field.declarationSourceEnd
1038 && scanner.eofPosition <= field.declarationSourceEnd + 1) {
1039 element = new RecoveredInitializer((Initializer) field, null, 1, this);
1040 lastCheckPoint = field.declarationSourceStart;
1048 if (element == null)
1051 for (int i = 0; i <= astPtr; i++) {
1052 AstNode node = astStack[i];
1053 if (node instanceof AbstractMethodDeclaration) {
1054 AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
1055 if (method.declarationSourceEnd == 0) {
1056 element = element.add(method, 0);
1057 lastCheckPoint = method.bodyStart;
1059 element = element.add(method, 0);
1060 lastCheckPoint = method.declarationSourceEnd + 1;
1064 if (node instanceof Initializer) {
1065 Initializer initializer = (Initializer) node;
1066 if (initializer.declarationSourceEnd == 0) {
1067 element = element.add(initializer, 1);
1068 lastCheckPoint = initializer.bodyStart;
1070 element = element.add(initializer, 0);
1071 lastCheckPoint = initializer.declarationSourceEnd + 1;
1075 if (node instanceof FieldDeclaration) {
1076 FieldDeclaration field = (FieldDeclaration) node;
1077 if (field.declarationSourceEnd == 0) {
1078 element = element.add(field, 0);
1079 if (field.initialization == null) {
1080 lastCheckPoint = field.sourceEnd + 1;
1082 lastCheckPoint = field.initialization.sourceEnd + 1;
1085 element = element.add(field, 0);
1086 lastCheckPoint = field.declarationSourceEnd + 1;
1090 if (node instanceof TypeDeclaration) {
1091 TypeDeclaration type = (TypeDeclaration) node;
1092 if (type.declarationSourceEnd == 0) {
1093 element = element.add(type, 0);
1094 lastCheckPoint = type.bodyStart;
1096 element = element.add(type, 0);
1097 lastCheckPoint = type.declarationSourceEnd + 1;
1101 if (node instanceof ImportReference) {
1102 ImportReference importRef = (ImportReference) node;
1103 element = element.add(importRef, 0);
1104 lastCheckPoint = importRef.declarationSourceEnd + 1;
1109 protected static short check(int i) {
1110 return check_table[i - (NUM_RULES + 1)];
1113 * Reconsider the entire source looking for inconsistencies in {} () []
1115 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
1117 scanner.wasAcr = false;
1118 boolean anomaliesDetected = false;
1120 char[] source = scanner.source;
1121 int[] leftCount = { 0, 0, 0 };
1122 int[] rightCount = { 0, 0, 0 };
1123 int[] depths = { 0, 0, 0 };
1124 int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] };
1125 int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
1126 int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] };
1127 int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] };
1128 scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
1129 while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
1131 // ---------Consume white space and handles startPosition---------
1132 boolean isWhiteSpace;
1134 scanner.startPosition = scanner.currentPosition;
1135 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1136 && (source[scanner.currentPosition] == 'u')) {
1137 isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
1139 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
1140 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
1141 // only record line positions we have not recorded yet
1142 scanner.pushLineSeparator();
1145 isWhiteSpace = Character.isWhitespace(scanner.currentCharacter);
1147 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
1149 // -------consume token until } is found---------
1151 switch (scanner.currentCharacter) {
1154 int index = leftCount[CurlyBracket]++;
1155 if (index == leftPositions[CurlyBracket].length) {
1156 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
1157 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
1159 leftPositions[CurlyBracket][index] = scanner.startPosition;
1160 leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
1165 int index = rightCount[CurlyBracket]++;
1166 if (index == rightPositions[CurlyBracket].length) {
1167 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
1168 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
1170 rightPositions[CurlyBracket][index] = scanner.startPosition;
1171 rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
1176 int index = leftCount[RoundBracket]++;
1177 if (index == leftPositions[RoundBracket].length) {
1178 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
1179 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
1181 leftPositions[RoundBracket][index] = scanner.startPosition;
1182 leftDepths[RoundBracket][index] = depths[RoundBracket]++;
1187 int index = rightCount[RoundBracket]++;
1188 if (index == rightPositions[RoundBracket].length) {
1189 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
1190 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
1192 rightPositions[RoundBracket][index] = scanner.startPosition;
1193 rightDepths[RoundBracket][index] = --depths[RoundBracket];
1198 int index = leftCount[SquareBracket]++;
1199 if (index == leftPositions[SquareBracket].length) {
1200 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
1201 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
1203 leftPositions[SquareBracket][index] = scanner.startPosition;
1204 leftDepths[SquareBracket][index] = depths[SquareBracket]++;
1209 int index = rightCount[SquareBracket]++;
1210 if (index == rightPositions[SquareBracket].length) {
1212 rightPositions[SquareBracket],
1214 (rightPositions[SquareBracket] = new int[index * 2]),
1217 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
1219 rightPositions[SquareBracket][index] = scanner.startPosition;
1220 rightDepths[SquareBracket][index] = --depths[SquareBracket];
1225 if (scanner.getNextChar('\\')) {
1226 scanner.scanEscapeCharacter();
1227 } else { // consume next character
1228 scanner.unicodeAsBackSlash = false;
1229 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1230 && (source[scanner.currentPosition] == 'u')) {
1231 scanner.getNextUnicodeChar();
1233 if (scanner.withoutUnicodePtr != 0) {
1234 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1238 scanner.getNextChar('\'');
1241 case '"' : // consume next character
1242 scanner.unicodeAsBackSlash = false;
1243 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1244 && (source[scanner.currentPosition] == 'u')) {
1245 scanner.getNextUnicodeChar();
1247 if (scanner.withoutUnicodePtr != 0) {
1248 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1251 while (scanner.currentCharacter != '"') {
1252 if (scanner.currentCharacter == '\r') {
1253 if (source[scanner.currentPosition] == '\n')
1254 scanner.currentPosition++;
1255 break; // the string cannot go further that the line
1257 if (scanner.currentCharacter == '\n') {
1258 break; // the string cannot go further that the line
1260 if (scanner.currentCharacter == '\\') {
1261 scanner.scanEscapeCharacter();
1263 // consume next character
1264 scanner.unicodeAsBackSlash = false;
1265 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1266 && (source[scanner.currentPosition] == 'u')) {
1267 scanner.getNextUnicodeChar();
1269 if (scanner.withoutUnicodePtr != 0) {
1270 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1278 if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment
1280 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1281 && (source[scanner.currentPosition] == 'u')) {
1282 //-------------unicode traitement ------------
1283 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1284 scanner.currentPosition++;
1285 while (source[scanner.currentPosition] == 'u') {
1286 scanner.currentPosition++;
1288 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1290 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1292 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1294 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1295 || c4 < 0) { //error don't care of the value
1296 scanner.currentCharacter = 'A';
1297 } //something different from \n and \r
1299 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1302 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
1304 scanner.startPosition = scanner.currentPosition;
1305 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1306 && (source[scanner.currentPosition] == 'u')) {
1307 //-------------unicode traitement ------------
1308 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1309 scanner.currentPosition++;
1310 while (source[scanner.currentPosition] == 'u') {
1311 scanner.currentPosition++;
1313 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1315 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1317 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1319 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1320 || c4 < 0) { //error don't care of the value
1321 scanner.currentCharacter = 'A';
1322 } //something different from \n and \r
1324 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1328 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
1329 if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
1330 // only record line positions we have not recorded yet
1331 scanner.pushLineSeparator();
1336 if (test > 0) { //traditional and annotation comment
1337 boolean star = false;
1338 // consume next character
1339 scanner.unicodeAsBackSlash = false;
1340 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1341 && (source[scanner.currentPosition] == 'u')) {
1342 scanner.getNextUnicodeChar();
1344 if (scanner.withoutUnicodePtr != 0) {
1345 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
1348 if (scanner.currentCharacter == '*') {
1352 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1353 && (source[scanner.currentPosition] == 'u')) {
1354 //-------------unicode traitement ------------
1355 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1356 scanner.currentPosition++;
1357 while (source[scanner.currentPosition] == 'u') {
1358 scanner.currentPosition++;
1360 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1362 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1364 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1366 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1367 || c4 < 0) { //error don't care of the value
1368 scanner.currentCharacter = 'A';
1369 } //something different from * and /
1371 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1374 //loop until end of comment */
1375 while ((scanner.currentCharacter != '/') || (!star)) {
1376 star = scanner.currentCharacter == '*';
1378 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\')
1379 && (source[scanner.currentPosition] == 'u')) {
1380 //-------------unicode traitement ------------
1381 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
1382 scanner.currentPosition++;
1383 while (source[scanner.currentPosition] == 'u') {
1384 scanner.currentPosition++;
1386 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1388 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1390 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1392 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
1393 || c4 < 0) { //error don't care of the value
1394 scanner.currentCharacter = 'A';
1395 } //something different from * and /
1397 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1406 if (Character.isJavaIdentifierStart(scanner.currentCharacter)) {
1407 scanner.scanIdentifierOrKeyword();
1410 if (Character.isDigit(scanner.currentCharacter)) {
1411 scanner.scanNumber(false);
1415 //-----------------end switch while try--------------------
1416 } catch (IndexOutOfBoundsException e) {
1417 break; // read until EOF
1418 } catch (InvalidInputException e) {
1419 return false; // no clue
1422 if (scanner.recordLineSeparator) {
1423 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
1426 // check placement anomalies against other kinds of brackets
1427 for (int kind = 0; kind < BracketKinds; kind++) {
1428 for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
1429 int start = leftPositions[kind][leftIndex]; // deepest first
1430 // find matching closing bracket
1431 int depth = leftDepths[kind][leftIndex];
1433 for (int i = 0; i < rightCount[kind]; i++) {
1434 int pos = rightPositions[kind][i];
1435 // want matching bracket further in source with same depth
1436 if ((pos > start) && (depth == rightDepths[kind][i])) {
1441 if (end < 0) { // did not find a good closing match
1442 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
1445 // check if even number of opening/closing other brackets in between this pair of brackets
1447 for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
1448 for (int i = 0; i < leftCount[otherKind]; i++) {
1449 int pos = leftPositions[otherKind][i];
1450 if ((pos > start) && (pos < end))
1453 for (int i = 0; i < rightCount[otherKind]; i++) {
1454 int pos = rightPositions[otherKind][i];
1455 if ((pos > start) && (pos < end))
1459 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
1464 // too many opening brackets ?
1465 for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
1466 anomaliesDetected = true;
1467 problemReporter.unmatchedBracket(
1468 leftPositions[kind][leftCount[kind] - i - 1],
1470 compilationUnit.compilationResult);
1472 // too many closing brackets ?
1473 for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
1474 anomaliesDetected = true;
1475 problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
1477 if (anomaliesDetected)
1481 return anomaliesDetected;
1482 } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
1483 return anomaliesDetected;
1484 } catch (NullPointerException e) { // jdk1.2.2 jit bug
1485 return anomaliesDetected;
1488 public final void checkAndSetModifiers(int flag) {
1489 /*modify the current modifiers buffer.
1490 When the startPosition of the modifiers is 0
1491 it means that the modifier being parsed is the first
1492 of a list of several modifiers. The startPosition
1493 is zeroed when a copy of modifiers-buffer is push
1494 onto the astStack. */
1496 if ((modifiers & flag) != 0) { // duplicate modifier
1497 modifiers |= AccAlternateModifierProblem;
1501 if (modifiersSourceStart < 0)
1502 modifiersSourceStart = scanner.startPosition;
1504 public void checkAnnotation() {
1506 boolean deprecated = false;
1507 boolean checkDeprecated = false;
1508 int lastAnnotationIndex = -1;
1510 //since jdk1.2 look only in the last java doc comment...
1511 found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--) {
1512 //look for @deprecated into the first javadoc comment preceeding the declaration
1513 int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
1514 // javadoc only (non javadoc comment have negative end positions.)
1515 if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
1518 if (scanner.commentStops[lastAnnotationIndex] < 0) {
1521 checkDeprecated = true;
1522 int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
1523 char[] comment = scanner.source;
1525 for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
1526 if ((comment[i] == '@')
1527 && (comment[i + 1] == 'd')
1528 && (comment[i + 2] == 'e')
1529 && (comment[i + 3] == 'p')
1530 && (comment[i + 4] == 'r')
1531 && (comment[i + 5] == 'e')
1532 && (comment[i + 6] == 'c')
1533 && (comment[i + 7] == 'a')
1534 && (comment[i + 8] == 't')
1535 && (comment[i + 9] == 'e')
1536 && (comment[i + 10] == 'd')) {
1537 // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
1538 int nextPos = i + 11;
1540 (comment[nextPos] == ' ')
1541 || (comment[nextPos] == '\t')
1542 || (comment[nextPos] == '\n')
1543 || (comment[nextPos] == '\r')
1544 || (comment[nextPos] == '*');
1551 checkAndSetModifiers(AccDeprecated);
1553 // modify the modifier source start to point at the first comment
1554 if (lastAnnotationIndex >= 0 && checkDeprecated) {
1555 modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex];
1558 protected void classInstanceCreation(boolean alwaysQualified) {
1559 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1561 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1562 // An empty class body produces a 0 on the length stack.....
1564 AllocationExpression alloc;
1566 if (((length = astLengthStack[astLengthPtr--]) == 1) && (astStack[astPtr] == null)) {
1569 if (alwaysQualified) {
1570 alloc = new QualifiedAllocationExpression();
1572 alloc = new AllocationExpression();
1574 alloc.sourceEnd = endPosition; //the position has been stored explicitly
1576 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
1577 expressionPtr -= length;
1578 System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[length], 0, length);
1580 alloc.type = getTypeReference(0);
1581 //the default constructor with the correct number of argument
1582 //will be created and added by the TC (see createsInternalConstructorWithBinding)
1583 alloc.sourceStart = intStack[intPtr--];
1584 pushOnExpressionStack(alloc);
1586 dispatchDeclarationInto(length);
1587 AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr];
1588 anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition;
1589 anonymousTypeDeclaration.bodyEnd = endStatementPosition;
1590 if (anonymousTypeDeclaration.allocation != null) {
1591 anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition;
1596 // mark fields and initializer with local type mark if needed
1597 markFieldsWithLocalType(anonymousTypeDeclaration);
1600 protected final void concatExpressionLists() {
1601 expressionLengthStack[--expressionLengthPtr]++;
1603 private final void concatNodeLists() {
1605 * This is a case where you have two sublists into the astStack that you want
1606 * to merge in one list. There is no action required on the astStack. The only
1607 * thing you need to do is merge the two lengths specified on the astStackLength.
1608 * The top two length are for example:
1610 * and you want to result in a list like:
1612 * This means that the p could be equals to 0 in case there is no astNode pushed
1614 * Look at the InterfaceMemberDeclarations for an example.
1617 astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--];
1619 protected void consumeAllocationHeader() {
1620 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1622 // ClassBodyopt produces a null item on the astStak if it produces NO class body
1623 // An empty class body produces a 0 on the length stack.....
1625 if (currentElement == null) {
1626 return; // should never occur, this consumeRule is only used in recovery mode
1628 if (currentToken == TokenNameLBRACE) {
1629 // beginning of an anonymous type
1630 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
1631 anonymousType.sourceStart = intStack[intPtr--];
1632 anonymousType.sourceEnd = rParenPos; // closing parenthesis
1633 lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition;
1634 currentElement = currentElement.add(anonymousType, 0);
1635 lastIgnoredToken = -1;
1636 currentToken = 0; // opening brace already taken into account
1639 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1640 restartRecovery = true; // request to restart from here on
1642 protected void consumeArgumentList() {
1643 // ArgumentList ::= ArgumentList ',' Expression
1644 concatExpressionLists();
1646 protected void consumeArrayAccess(boolean unspecifiedReference) {
1647 // ArrayAccess ::= Name '[' Expression ']' ==> true
1648 // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
1652 if (unspecifiedReference) {
1653 exp = expressionStack[expressionPtr] = new ArrayReference(getUnspecifiedReferenceOptimized(), expressionStack[expressionPtr]);
1656 expressionLengthPtr--;
1657 exp = expressionStack[expressionPtr] = new ArrayReference(expressionStack[expressionPtr], expressionStack[expressionPtr + 1]);
1659 exp.sourceEnd = endPosition;
1661 protected void consumeArrayCreationExpression() {
1662 // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
1663 // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
1666 ArrayAllocationExpression aae = new ArrayAllocationExpression();
1667 if (expressionLengthStack[expressionLengthPtr] != 0) {
1668 expressionLengthPtr--;
1669 aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--];
1671 expressionLengthPtr--;
1674 aae.type = getTypeReference(0);
1675 length = (expressionLengthStack[expressionLengthPtr--]);
1676 expressionPtr -= length;
1677 System.arraycopy(expressionStack, expressionPtr + 1, aae.dimensions = new Expression[length], 0, length);
1678 aae.sourceStart = intStack[intPtr--];
1679 if (aae.initializer == null) {
1680 aae.sourceEnd = endPosition;
1682 aae.sourceEnd = aae.initializer.sourceEnd;
1684 pushOnExpressionStack(aae);
1686 protected void consumeArrayInitializer() {
1687 // ArrayInitializer ::= '{' VariableInitializers '}'
1688 // ArrayInitializer ::= '{' VariableInitializers , '}'
1690 arrayInitializer(expressionLengthStack[expressionLengthPtr--]);
1693 protected void consumeAssertStatement() {
1694 // AssertStatement ::= 'assert' Expression ':' Expression ';'
1695 expressionLengthPtr -= 2;
1696 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--]));
1699 protected void consumeAssignment() {
1700 // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
1701 //optimize the push/pop
1703 int op = intStack[intPtr--]; //<--the encoded operator
1706 expressionLengthPtr--;
1707 expressionStack[expressionPtr] =
1709 ? new CompoundAssignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op, scanner.startPosition - 1)
1710 : new Assignment(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], scanner.startPosition - 1);
1712 protected void consumeAssignmentOperator(int pos) {
1713 // AssignmentOperator ::= '='
1714 // AssignmentOperator ::= '*='
1715 // AssignmentOperator ::= '/='
1716 // AssignmentOperator ::= '%='
1717 // AssignmentOperator ::= '+='
1718 // AssignmentOperator ::= '-='
1719 // AssignmentOperator ::= '<<='
1720 // AssignmentOperator ::= '>>='
1721 // AssignmentOperator ::= '>>>='
1722 // AssignmentOperator ::= '&='
1723 // AssignmentOperator ::= '^='
1724 // AssignmentOperator ::= '|='
1727 intStack[++intPtr] = pos;
1728 } catch (IndexOutOfBoundsException e) {
1730 int oldStackLength = intStack.length;
1731 int oldStack[] = intStack;
1732 intStack = new int[oldStackLength + StackIncrement];
1733 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
1734 intStack[intPtr] = pos;
1737 protected void consumeBinaryExpression(int op) {
1738 // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
1739 // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
1740 // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
1741 // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
1742 // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
1743 // ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
1744 // ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
1745 // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
1746 // RelationalExpression ::= RelationalExpression '<' ShiftExpression
1747 // RelationalExpression ::= RelationalExpression '>' ShiftExpression
1748 // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
1749 // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
1750 // AndExpression ::= AndExpression '&' EqualityExpression
1751 // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
1752 // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
1753 // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
1754 // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
1756 //optimize the push/pop
1759 expressionLengthPtr--;
1761 expressionStack[expressionPtr] = new OR_OR_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1763 if (op == AND_AND) {
1764 expressionStack[expressionPtr] =
1765 new AND_AND_Expression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1767 // look for "string1" + "string2"
1768 if ((op == PLUS) && optimizeStringLiterals) {
1769 Expression expr1, expr2;
1770 expr1 = expressionStack[expressionPtr];
1771 expr2 = expressionStack[expressionPtr + 1];
1772 if (expr1 instanceof StringLiteral) {
1773 if (expr2 instanceof CharLiteral) { // string+char
1774 expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((CharLiteral) expr2);
1775 } else if (expr2 instanceof StringLiteral) { //string+string
1776 expressionStack[expressionPtr] = ((StringLiteral) expr1).extendWith((StringLiteral) expr2);
1778 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1781 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1784 expressionStack[expressionPtr] =
1785 new BinaryExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
1790 protected void consumeBlock() {
1791 // Block ::= OpenBlock '{' BlockStatementsopt '}'
1792 // simpler action for empty blocks
1795 if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block
1796 pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition));
1797 realBlockPtr--; // still need to pop the block variable counter
1799 Block bk = new Block(realBlockStack[realBlockPtr--]);
1801 System.arraycopy(astStack, astPtr + 1, bk.statements = new Statement[length], 0, length);
1803 bk.sourceStart = intStack[intPtr--];
1804 bk.sourceEnd = endStatementPosition;
1807 protected void consumeBlockStatements() {
1808 // BlockStatements ::= BlockStatements BlockStatement
1811 protected void consumeCaseLabel() {
1812 // SwitchLabel ::= 'case' ConstantExpression ':'
1813 expressionLengthPtr--;
1814 pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--]));
1816 protected void consumeCastExpression() {
1817 // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
1818 // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
1820 //intStack : posOfLeftParen dim posOfRightParen
1822 //optimize the push/pop
1824 Expression exp, cast, castType;
1825 int end = intStack[intPtr--];
1826 expressionStack[expressionPtr] =
1827 cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--]));
1828 castType.sourceEnd = end - 1;
1829 castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1;
1830 cast.sourceEnd = exp.sourceEnd;
1832 protected void consumeCastExpressionLL1() {
1833 //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus
1834 // Expression is used in order to make the grammar LL1
1838 Expression castType, cast, exp;
1840 expressionStack[expressionPtr] =
1842 new CastExpression(exp = expressionStack[expressionPtr + 1], castType = getTypeReference(expressionStack[expressionPtr]));
1843 expressionLengthPtr--;
1844 updateSourcePosition(castType);
1845 cast.sourceStart = castType.sourceStart;
1846 cast.sourceEnd = exp.sourceEnd;
1847 castType.sourceStart++;
1848 castType.sourceEnd--;
1850 protected void consumeCatches() {
1851 // Catches ::= Catches CatchClause
1852 optimizedConcatNodeLists();
1854 protected void consumeCatchHeader() {
1855 // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1857 if (currentElement == null) {
1858 return; // should never occur, this consumeRule is only used in recovery mode
1860 // current element should be a block due to the presence of the opening brace
1861 if (!(currentElement instanceof RecoveredBlock)) {
1864 // exception argument is already on astStack
1865 ((RecoveredBlock) currentElement).attach(new RecoveredLocalVariable((Argument) astStack[astPtr--], currentElement, 0));
1866 // insert catch variable in catch block
1867 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1868 restartRecovery = true; // request to restart from here on
1869 lastIgnoredToken = -1;
1871 protected void consumeClassBodyDeclaration() {
1872 // ClassBodyDeclaration ::= Diet Block
1873 //push an Initializer
1874 //optimize the push/pop
1875 nestedMethod[nestedType]--;
1876 Initializer initializer = new Initializer((Block) astStack[astPtr], 0);
1877 intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1878 realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1879 int javadocCommentStart = intStack[intPtr--];
1880 if (javadocCommentStart != -1) {
1881 initializer.declarationSourceStart = javadocCommentStart;
1883 astStack[astPtr] = initializer;
1884 initializer.sourceEnd = endStatementPosition;
1885 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1887 protected void consumeClassBodyDeclarations() {
1888 // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1891 protected void consumeClassBodyDeclarationsopt() {
1892 // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1895 protected void consumeClassBodyopt() {
1896 // ClassBodyopt ::= $empty
1897 pushOnAstStack(null);
1898 endPosition = scanner.startPosition - 1;
1900 protected void consumeClassDeclaration() {
1901 // ClassDeclaration ::= ClassHeader ClassBody
1904 if ((length = astLengthStack[astLengthPtr--]) != 0) {
1905 //there are length declarations
1906 //dispatch according to the type of the declarations
1907 dispatchDeclarationInto(length);
1910 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1912 // mark fields and initializer with local type mark if needed
1913 markFieldsWithLocalType(typeDecl);
1915 //convert constructor that do not have the type's name into methods
1916 boolean hasConstructor = typeDecl.checkConstructors(this);
1918 //add the default constructor when needed (interface don't have it)
1919 if (!hasConstructor) {
1920 boolean insideFieldInitializer = false;
1922 for (int i = nestedType; i > 0; i--) {
1923 if (variablesCounter[i] > 0) {
1924 insideFieldInitializer = true;
1929 typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true);
1932 //always add <clinit> (will be remove at code gen time if empty)
1933 if (this.scanner.containsAssertKeyword) {
1934 typeDecl.bits |= AstNode.AddAssertionMASK;
1936 typeDecl.addClinit();
1937 typeDecl.bodyEnd = endStatementPosition;
1938 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1940 protected void consumeClassHeader() {
1941 // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1943 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1944 if (currentToken == TokenNameLBRACE) {
1945 typeDecl.bodyStart = scanner.currentPosition;
1947 if (currentElement != null) {
1948 restartRecovery = true; // used to avoid branching back into the regular automaton
1950 // flush the comments related to the class header
1951 scanner.commentPtr = -1;
1953 protected void consumeClassHeaderExtends() {
1954 // ClassHeaderExtends ::= 'extends' ClassType
1955 // There is a class declaration on the top of stack
1956 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1958 typeDecl.superclass = getTypeReference(0);
1959 typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1961 if (currentElement != null) {
1962 lastCheckPoint = typeDecl.bodyStart;
1965 protected void consumeClassHeaderImplements() {
1966 // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1967 int length = astLengthStack[astLengthPtr--];
1970 // There is a class declaration on the top of stack
1971 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1972 System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
1973 typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
1974 listLength = 0; // reset after having read super-interfaces
1976 if (currentElement != null) { // is recovering
1977 lastCheckPoint = typeDecl.bodyStart;
1980 protected void consumeClassHeaderName() {
1981 // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1982 TypeDeclaration typeDecl;
1983 if (nestedMethod[nestedType] == 0) {
1984 if (nestedType != 0) {
1985 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
1987 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1990 // Record that the block has a declaration for local types
1991 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
1992 markCurrentMethodWithLocalType();
1996 //highlight the name of the type
1997 long pos = identifierPositionStack[identifierPtr];
1998 typeDecl.sourceEnd = (int) pos;
1999 typeDecl.sourceStart = (int) (pos >>> 32);
2000 typeDecl.name = identifierStack[identifierPtr--];
2001 identifierLengthPtr--;
2003 //compute the declaration source too
2004 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2005 // we want to keep the beginning position but get rid of the end position
2006 // it is only used for the ClassLiteralAccess positions.
2007 typeDecl.declarationSourceStart = intStack[intPtr--];
2008 intPtr--; // remove the end position of the class token
2010 typeDecl.modifiersSourceStart = intStack[intPtr--];
2011 typeDecl.modifiers = intStack[intPtr--];
2012 if (typeDecl.modifiersSourceStart >= 0) {
2013 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2015 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2016 pushOnAstStack(typeDecl);
2018 listLength = 0; // will be updated when reading super-interfaces
2020 if (currentElement != null) {
2021 lastCheckPoint = typeDecl.bodyStart;
2022 currentElement = currentElement.add(typeDecl, 0);
2023 lastIgnoredToken = -1;
2026 protected void consumeClassInstanceCreationExpression() {
2027 // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
2028 classInstanceCreation(false);
2030 protected void consumeClassInstanceCreationExpressionName() {
2031 // ClassInstanceCreationExpressionName ::= Name '.'
2032 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2034 protected void consumeClassInstanceCreationExpressionQualified() {
2035 // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
2036 // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
2038 classInstanceCreation(true); // <-- push the Qualifed....
2040 expressionLengthPtr--;
2041 QualifiedAllocationExpression qae = (QualifiedAllocationExpression) expressionStack[expressionPtr--];
2042 qae.enclosingInstance = expressionStack[expressionPtr];
2043 expressionStack[expressionPtr] = qae;
2044 qae.sourceStart = qae.enclosingInstance.sourceStart;
2046 protected void consumeClassTypeElt() {
2047 // ClassTypeElt ::= ClassType
2048 pushOnAstStack(getTypeReference(0));
2049 /* if incomplete thrown exception list, listLength counter will not have been reset,
2050 indicating that some items are available on the stack */
2053 protected void consumeClassTypeList() {
2054 // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
2055 optimizedConcatNodeLists();
2057 protected void consumeCompilationUnit() {
2058 // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
2059 // do nothing by default
2061 protected void consumeConditionalExpression(int op) {
2062 // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
2063 //optimize the push/pop
2066 expressionLengthPtr -= 2;
2067 expressionStack[expressionPtr] =
2068 new ConditionalExpression(
2069 expressionStack[expressionPtr],
2070 expressionStack[expressionPtr + 1],
2071 expressionStack[expressionPtr + 2]);
2073 protected void consumeConstructorBlockStatements() {
2074 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
2075 concatNodeLists(); // explictly add the first statement into the list of statements
2077 protected void consumeConstructorBody() {
2078 // ConstructorBody ::= NestedMethod '{' BlockStatementsopt '}'
2079 // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation '}'
2080 nestedMethod[nestedType]--;
2082 protected void consumeConstructorDeclaration() {
2083 // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
2086 astStack : MethodDeclaration statements
2087 identifierStack : name
2089 astStack : MethodDeclaration
2093 //must provide a default constructor call when needed
2097 // pop the position of the { (body of the method) pushed in block decl
2102 ExplicitConstructorCall constructorCall = null;
2103 Statement[] statements = null;
2104 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2106 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) {
2107 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
2108 System.arraycopy(astStack, astPtr + 2, statements = new Statement[length - 1], 0, length - 1);
2109 constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
2110 } else { //need to add explicitly the super();
2111 System.arraycopy(astStack, astPtr + 1, statements = new Statement[length], 0, length);
2112 constructorCall = SuperReference.implicitSuperConstructorCall();
2116 // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
2117 constructorCall = SuperReference.implicitSuperConstructorCall();
2121 // now we know that the top of stack is a constructorDeclaration
2122 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
2123 cd.constructorCall = constructorCall;
2124 cd.statements = statements;
2126 //highlight of the implicit call on the method name
2127 if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
2128 cd.constructorCall.sourceEnd = cd.sourceEnd;
2129 cd.constructorCall.sourceStart = cd.sourceStart;
2132 //watch for } that could be given as a unicode ! ( u007D is '}' )
2133 // store the endPosition (position just before the '}') in case there is
2134 // a trailing comment behind the end of the method
2135 cd.bodyEnd = endPosition;
2136 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2139 protected void consumeInvalidConstructorDeclaration() {
2140 // ConstructorDeclaration ::= ConstructorHeader ';'
2141 // now we know that the top of stack is a constructorDeclaration
2142 ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
2144 cd.bodyEnd = endPosition; // position just before the trailing semi-colon
2145 cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2146 // report the problem and continue the parsing - narrowing the problem onto the method
2148 protected void consumeConstructorHeader() {
2149 // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
2151 AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
2153 if (currentToken == TokenNameLBRACE) {
2154 method.bodyStart = scanner.currentPosition;
2157 if (currentElement != null) {
2158 restartRecovery = true; // used to avoid branching back into the regular automaton
2161 protected void consumeConstructorHeaderName() {
2163 /* recovering - might be an empty message send */
2164 if (currentElement != null) {
2165 if (lastIgnoredToken == TokenNamenew) { // was an allocation expression
2166 lastCheckPoint = scanner.startPosition; // force to restart at this exact position
2167 restartRecovery = true;
2172 // ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
2173 ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
2175 //name -- this is not really revelant but we do .....
2176 cd.selector = identifierStack[identifierPtr];
2177 long selectorSource = identifierPositionStack[identifierPtr--];
2178 identifierLengthPtr--;
2181 cd.declarationSourceStart = intStack[intPtr--];
2182 cd.modifiers = intStack[intPtr--];
2184 //highlight starts at the selector starts
2185 cd.sourceStart = (int) (selectorSource >>> 32);
2187 cd.sourceEnd = lParenPos;
2188 cd.bodyStart = lParenPos + 1;
2189 listLength = 0; // initialize listLength before reading parameters/throws
2192 if (currentElement != null) {
2193 lastCheckPoint = cd.bodyStart;
2194 if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT) || cd.modifiers != 0) {
2195 currentElement = currentElement.add(cd, 0);
2196 lastIgnoredToken = -1;
2200 protected void consumeDefaultLabel() {
2201 // SwitchLabel ::= 'default' ':'
2202 pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--]));
2204 protected void consumeDefaultModifiers() {
2205 checkAnnotation(); // might update modifiers with AccDeprecated
2206 pushOnIntStack(modifiers); // modifiers
2207 pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
2210 protected void consumeDiet() {
2213 pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one
2214 jumpOverMethodBody();
2216 protected void consumeDims() {
2217 // Dims ::= DimsLoop
2218 pushOnIntStack(dimensions);
2221 protected void consumeDimWithOrWithOutExpr() {
2222 // DimWithOrWithOutExpr ::= '[' ']'
2223 pushOnExpressionStack(null);
2225 protected void consumeDimWithOrWithOutExprs() {
2226 // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
2227 concatExpressionLists();
2229 protected void consumeEmptyArgumentListopt() {
2230 // ArgumentListopt ::= $empty
2231 pushOnExpressionStackLengthStack(0);
2233 protected void consumeEmptyArrayInitializer() {
2234 // ArrayInitializer ::= '{' ,opt '}'
2235 arrayInitializer(0);
2237 protected void consumeEmptyArrayInitializeropt() {
2238 // ArrayInitializeropt ::= $empty
2239 pushOnExpressionStackLengthStack(0);
2241 protected void consumeEmptyBlockStatementsopt() {
2242 // BlockStatementsopt ::= $empty
2243 pushOnAstLengthStack(0);
2245 protected void consumeEmptyCatchesopt() {
2246 // Catchesopt ::= $empty
2247 pushOnAstLengthStack(0);
2249 protected void consumeEmptyClassBodyDeclarationsopt() {
2250 // ClassBodyDeclarationsopt ::= $empty
2251 pushOnAstLengthStack(0);
2253 protected void consumeEmptyClassMemberDeclaration() {
2254 // ClassMemberDeclaration ::= ';'
2255 pushOnAstLengthStack(0);
2257 protected void consumeEmptyDimsopt() {
2258 // Dimsopt ::= $empty
2261 protected void consumeEmptyExpression() {
2262 // Expressionopt ::= $empty
2263 pushOnExpressionStackLengthStack(0);
2265 protected void consumeEmptyForInitopt() {
2266 // ForInitopt ::= $empty
2267 pushOnAstLengthStack(0);
2269 protected void consumeEmptyForUpdateopt() {
2270 // ForUpdateopt ::= $empty
2271 pushOnExpressionStackLengthStack(0);
2273 protected void consumeEmptyImportDeclarationsopt() {
2274 // ImportDeclarationsopt ::= $empty
2275 pushOnAstLengthStack(0);
2277 protected void consumeEmptyInterfaceMemberDeclaration() {
2278 // InterfaceMemberDeclaration ::= ';'
2279 pushOnAstLengthStack(0);
2281 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
2282 // InterfaceMemberDeclarationsopt ::= $empty
2283 pushOnAstLengthStack(0);
2285 protected void consumeEmptyStatement() {
2286 // EmptyStatement ::= ';'
2287 if (this.scanner.source[endStatementPosition] == ';') {
2288 pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition));
2290 // we have a Unicode for the ';' (/u003B)
2291 pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition));
2294 protected void consumeEmptySwitchBlock() {
2295 // SwitchBlock ::= '{' '}'
2296 pushOnAstLengthStack(0);
2298 protected void consumeEmptyTypeDeclaration() {
2299 // TypeDeclaration ::= ';'
2300 pushOnAstLengthStack(0);
2302 protected void consumeEmptyTypeDeclarationsopt() {
2303 // TypeDeclarationsopt ::= $empty
2304 pushOnAstLengthStack(0);
2306 protected void consumeEnterAnonymousClassBody() {
2307 // EnterAnonymousClassBody ::= $empty
2308 QualifiedAllocationExpression alloc;
2309 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
2310 alloc = anonymousType.allocation = new QualifiedAllocationExpression(anonymousType);
2311 markCurrentMethodWithLocalType();
2312 pushOnAstStack(anonymousType);
2314 alloc.sourceEnd = rParenPos; //the position has been stored explicitly
2316 if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
2317 expressionPtr -= argumentLength;
2318 System.arraycopy(expressionStack, expressionPtr + 1, alloc.arguments = new Expression[argumentLength], 0, argumentLength);
2320 alloc.type = getTypeReference(0);
2322 anonymousType.sourceEnd = alloc.sourceEnd;
2323 //position at the type while it impacts the anonymous declaration
2324 anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
2325 alloc.sourceStart = intStack[intPtr--];
2326 pushOnExpressionStack(alloc);
2328 anonymousType.bodyStart = scanner.currentPosition;
2329 listLength = 0; // will be updated when reading super-interfaces
2331 if (currentElement != null) {
2332 lastCheckPoint = anonymousType.bodyStart;
2333 // the recoveryTokenCheck will deal with the open brace
2334 currentElement = currentElement.add(anonymousType, 0);
2335 currentToken = 0; // opening brace already taken into account
2336 lastIgnoredToken = -1;
2339 protected void consumeEnterCompilationUnit() {
2340 // EnterCompilationUnit ::= $empty
2341 // do nothing by default
2343 protected void consumeEnterVariable() {
2344 // EnterVariable ::= $empty
2345 // do nothing by default
2347 char[] name = identifierStack[identifierPtr];
2348 long namePosition = identifierPositionStack[identifierPtr];
2349 int extendedDimension = intStack[intPtr--];
2350 AbstractVariableDeclaration declaration;
2351 // create the ast node
2352 boolean isLocalDeclaration = nestedMethod[nestedType] != 0;
2353 if (isLocalDeclaration) {
2354 // create the local variable declarations
2355 declaration = this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
2357 // create the field declaration
2358 declaration = this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
2362 identifierLengthPtr--;
2364 int variableIndex = variablesCounter[nestedType];
2366 if (variableIndex == 0) {
2367 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
2368 if (isLocalDeclaration) {
2369 declaration.declarationSourceStart = intStack[intPtr--];
2370 declaration.modifiers = intStack[intPtr--];
2371 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
2372 if (declaration.declarationSourceStart == -1) {
2373 // this is true if there is no modifiers for the local variable declaration
2374 declaration.declarationSourceStart = type.sourceStart;
2376 pushOnAstStack(type);
2378 type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
2379 pushOnAstStack(type);
2380 declaration.declarationSourceStart = intStack[intPtr--];
2381 declaration.modifiers = intStack[intPtr--];
2384 type = (TypeReference) astStack[astPtr - variableIndex];
2385 typeDim = type.dimensions();
2386 AbstractVariableDeclaration previousVariable = (AbstractVariableDeclaration) astStack[astPtr];
2387 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
2388 declaration.modifiers = previousVariable.modifiers;
2391 if (extendedDimension == 0) {
2392 declaration.type = type;
2394 int dimension = typeDim + extendedDimension;
2395 //on the identifierLengthStack there is the information about the type....
2397 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2399 int typeSourceStart = type.sourceStart;
2400 int typeSourceEnd = type.sourceEnd;
2401 type = TypeReference.baseTypeReference(-baseType, dimension);
2402 type.sourceStart = typeSourceStart;
2403 type.sourceEnd = typeSourceEnd;
2404 declaration.type = type;
2406 declaration.type = this.copyDims(type, dimension);
2409 variablesCounter[nestedType]++;
2410 pushOnAstStack(declaration);
2412 if (currentElement != null) {
2413 if (!(currentElement instanceof RecoveredType)
2414 && (currentToken == TokenNameDOT //|| declaration.modifiers != 0
2415 || (scanner.getLineNumber(declaration.type.sourceStart) != scanner.getLineNumber((int) (namePosition >>> 32))))) {
2416 lastCheckPoint = (int) (namePosition >>> 32);
2417 restartRecovery = true;
2420 if (isLocalDeclaration) {
2421 LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr];
2422 lastCheckPoint = localDecl.sourceEnd + 1;
2423 currentElement = currentElement.add(localDecl, 0);
2425 FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr];
2426 lastCheckPoint = fieldDecl.sourceEnd + 1;
2427 currentElement = currentElement.add(fieldDecl, 0);
2429 lastIgnoredToken = -1;
2432 protected void consumeEqualityExpression(int op) {
2433 // EqualityExpression ::= EqualityExpression '==' RelationalExpression
2434 // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
2436 //optimize the push/pop
2439 expressionLengthPtr--;
2440 expressionStack[expressionPtr] = new EqualExpression(expressionStack[expressionPtr], expressionStack[expressionPtr + 1], op);
2442 protected void consumeExitVariableWithInitialization() {
2443 // ExitVariableWithInitialization ::= $empty
2444 // do nothing by default
2445 expressionLengthPtr--;
2446 AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr];
2447 variableDecl.initialization = expressionStack[expressionPtr--];
2448 // we need to update the declarationSourceEnd of the local variable declaration to the
2449 // source end position of the initialization expression
2450 variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
2451 variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
2453 protected void consumeExitVariableWithoutInitialization() {
2454 // ExitVariableWithoutInitialization ::= $empty
2455 // do nothing by default
2457 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
2459 /* flag allows to distinguish 3 cases :
2461 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
2462 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
2464 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
2465 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
2467 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
2468 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
2470 int startPosition = intStack[intPtr--];
2471 ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
2473 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
2474 expressionPtr -= length;
2475 System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
2479 ecc.sourceStart = startPosition;
2482 expressionLengthPtr--;
2483 ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart;
2486 ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
2489 pushOnAstStack(ecc);
2490 ecc.sourceEnd = endPosition;
2492 protected void consumeExpressionStatement() {
2493 // ExpressionStatement ::= StatementExpression ';'
2494 expressionLengthPtr--;
2495 pushOnAstStack(expressionStack[expressionPtr--]);
2497 protected void consumeFieldAccess(boolean isSuperAccess) {
2498 // FieldAccess ::= Primary '.' 'Identifier'
2499 // FieldAccess ::= 'super' '.' 'Identifier'
2501 FieldReference fr = new FieldReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
2502 identifierLengthPtr--;
2503 if (isSuperAccess) {
2504 //considerates the fieldReference beginning at the 'super' ....
2505 fr.sourceStart = intStack[intPtr--];
2506 fr.receiver = new SuperReference(fr.sourceStart, endPosition);
2507 pushOnExpressionStack(fr);
2510 if ((fr.receiver = expressionStack[expressionPtr]).isThis()) {
2511 //fieldreference begins at the this
2512 fr.sourceStart = fr.receiver.sourceStart;
2514 expressionStack[expressionPtr] = fr;
2517 protected void consumeFieldDeclaration() {
2518 // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
2519 // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
2523 expressionStack: Expression Expression ...... Expression
2524 identifierStack : type identifier identifier ...... identifier
2525 intStack : typeDim dim dim dim
2527 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2533 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2535 for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2536 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2537 fieldDeclaration.declarationSourceEnd = endStatementPosition;
2538 fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included
2540 updateSourceDeclarationParts(variableDeclaratorsCounter);
2541 int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition);
2542 if (endPos != endStatementPosition) {
2543 for (int i = 0; i < variableDeclaratorsCounter; i++) {
2544 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2545 fieldDeclaration.declarationSourceEnd = endPos;
2548 // update the astStack, astPtr and astLengthStack
2549 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2550 System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
2551 astPtr--; // remove the type reference
2552 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2555 if (currentElement != null) {
2556 lastCheckPoint = endPos + 1;
2557 if (currentElement.parent != null && currentElement instanceof RecoveredField) {
2558 currentElement = currentElement.parent;
2560 restartRecovery = true;
2562 variablesCounter[nestedType] = 0;
2564 protected void consumeForceNoDiet() {
2565 // ForceNoDiet ::= $empty
2568 protected void consumeForInit() {
2569 // ForInit ::= StatementExpressionList
2570 pushOnAstLengthStack(-1);
2572 protected void consumeFormalParameter() {
2573 // FormalParameter ::= Type VariableDeclaratorId ==> false
2574 // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
2577 identifierStack : type identifier
2585 identifierLengthPtr--;
2586 char[] name = identifierStack[identifierPtr];
2587 long namePositions = identifierPositionStack[identifierPtr--];
2588 TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
2589 int modifierPositions = intStack[intPtr--];
2591 Argument arg = new Argument(name, namePositions, type, intStack[intPtr + 1] & ~AccDeprecated); // modifiers
2592 arg.declarationSourceStart = modifierPositions;
2593 pushOnAstStack(arg);
2595 /* if incomplete method header, listLength counter will not have been reset,
2596 indicating that some arguments are available on the stack */
2599 protected void consumeFormalParameterList() {
2600 // FormalParameterList ::= FormalParameterList ',' FormalParameter
2601 optimizedConcatNodeLists();
2603 protected void consumeFormalParameterListopt() {
2604 // FormalParameterListopt ::= $empty
2605 pushOnAstLengthStack(0);
2607 protected void consumeImportDeclarations() {
2608 // ImportDeclarations ::= ImportDeclarations ImportDeclaration
2609 optimizedConcatNodeLists();
2611 protected void consumeImportDeclarationsopt() {
2612 // ImportDeclarationsopt ::= ImportDeclarations
2614 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2616 System.arraycopy(astStack, astPtr + 1, compilationUnit.imports = new ImportReference[length], 0, length);
2619 protected void consumeInstanceOfExpression(int op) {
2620 // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
2621 //optimize the push/pop
2623 //by construction, no base type may be used in getTypeReference
2625 expressionStack[expressionPtr] =
2626 exp = new InstanceOfExpression(expressionStack[expressionPtr], getTypeReference(intStack[intPtr--]), op);
2627 if (exp.sourceEnd == 0) {
2628 //array on base type....
2629 exp.sourceEnd = scanner.startPosition - 1;
2631 //the scanner is on the next token already....
2633 protected void consumeInterfaceDeclaration() {
2634 // see consumeClassDeclaration in case of changes: duplicated code
2635 // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
2637 if ((length = astLengthStack[astLengthPtr--]) != 0) {
2638 //there are length declarations
2639 //dispatch.....according to the type of the declarations
2640 dispatchDeclarationInto(length);
2643 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2645 // mark fields and initializer with local type mark if needed
2646 markFieldsWithLocalType(typeDecl);
2648 //convert constructor that do not have the type's name into methods
2649 typeDecl.checkConstructors(this);
2651 //always add <clinit> (will be remove at code gen time if empty)
2652 if (this.scanner.containsAssertKeyword) {
2653 typeDecl.bits |= AstNode.AddAssertionMASK;
2655 typeDecl.addClinit();
2656 typeDecl.bodyEnd = endStatementPosition;
2657 typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2659 protected void consumeInterfaceHeader() {
2660 // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2662 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2663 if (currentToken == TokenNameLBRACE) {
2664 typeDecl.bodyStart = scanner.currentPosition;
2666 if (currentElement != null) {
2667 restartRecovery = true; // used to avoid branching back into the regular automaton
2669 // flush the comments related to the interface header
2670 scanner.commentPtr = -1;
2672 protected void consumeInterfaceHeaderExtends() {
2673 // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2674 int length = astLengthStack[astLengthPtr--];
2677 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2678 System.arraycopy(astStack, astPtr + 1, typeDecl.superInterfaces = new TypeReference[length], 0, length);
2679 typeDecl.bodyStart = typeDecl.superInterfaces[length - 1].sourceEnd + 1;
2680 listLength = 0; // reset after having read super-interfaces
2682 if (currentElement != null) {
2683 lastCheckPoint = typeDecl.bodyStart;
2686 protected void consumeInterfaceHeaderName() {
2687 // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2688 TypeDeclaration typeDecl;
2689 if (nestedMethod[nestedType] == 0) {
2690 if (nestedType != 0) {
2691 typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
2693 typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2696 // Record that the block has a declaration for local types
2697 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
2698 markCurrentMethodWithLocalType();
2702 //highlight the name of the type
2703 long pos = identifierPositionStack[identifierPtr];
2704 typeDecl.sourceEnd = (int) pos;
2705 typeDecl.sourceStart = (int) (pos >>> 32);
2706 typeDecl.name = identifierStack[identifierPtr--];
2707 identifierLengthPtr--;
2709 //compute the declaration source too
2710 // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2711 // we want to keep the beginning position but get rid of the end position
2712 // it is only used for the ClassLiteralAccess positions.
2713 typeDecl.declarationSourceStart = intStack[intPtr--];
2714 intPtr--; // remove the end position of the class token
2715 typeDecl.modifiersSourceStart = intStack[intPtr--];
2716 typeDecl.modifiers = intStack[intPtr--];
2717 if (typeDecl.modifiersSourceStart >= 0) {
2718 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2720 typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2721 pushOnAstStack(typeDecl);
2722 listLength = 0; // will be updated when reading super-interfaces
2724 if (currentElement != null) { // is recovering
2725 lastCheckPoint = typeDecl.bodyStart;
2726 currentElement = currentElement.add(typeDecl, 0);
2727 lastIgnoredToken = -1;
2730 protected void consumeInterfaceMemberDeclarations() {
2731 // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2734 protected void consumeInterfaceMemberDeclarationsopt() {
2735 // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2738 protected void consumeInterfaceType() {
2739 // InterfaceType ::= ClassOrInterfaceType
2740 pushOnAstStack(getTypeReference(0));
2741 /* if incomplete type header, listLength counter will not have been reset,
2742 indicating that some interfaces are available on the stack */
2745 protected void consumeInterfaceTypeList() {
2746 // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2747 optimizedConcatNodeLists();
2749 protected void consumeLeftHandSide() {
2750 // LeftHandSide ::= Name
2752 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2754 protected void consumeLeftParen() {
2755 // PushLPAREN ::= '('
2756 pushOnIntStack(lParenPos);
2758 protected void consumeLocalVariableDeclaration() {
2759 // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2763 expressionStack: Expression Expression ...... Expression
2764 identifierStack : type identifier identifier ...... identifier
2765 intStack : typeDim dim dim dim
2767 astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2773 int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2775 // update the astStack, astPtr and astLengthStack
2776 int startIndex = astPtr - variablesCounter[nestedType] + 1;
2777 System.arraycopy(astStack, startIndex, astStack, startIndex - 1, variableDeclaratorsCounter);
2778 astPtr--; // remove the type reference
2779 astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2780 variablesCounter[nestedType] = 0;
2782 protected void consumeLocalVariableDeclarationStatement() {
2783 // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2784 // see blockReal in case of change: duplicated code
2785 // increment the amount of declared variables for this block
2786 realBlockStack[realBlockPtr]++;
2788 protected void consumeMethodBody() {
2789 // MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
2790 nestedMethod[nestedType]--;
2792 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2793 // MethodDeclaration ::= MethodHeader MethodBody
2794 // AbstractMethodDeclaration ::= MethodHeader ';'
2797 astStack : modifiers arguments throws statements
2798 identifierStack : type name
2799 intStack : dim dim dim
2801 astStack : MethodDeclaration
2807 if (isNotAbstract) {
2808 // pop the position of the { (body of the method) pushed in block decl
2812 int explicitDeclarations = 0;
2813 Statement[] statements = null;
2814 if (isNotAbstract) {
2816 explicitDeclarations = realBlockStack[realBlockPtr--];
2817 if ((length = astLengthStack[astLengthPtr--]) != 0)
2818 System.arraycopy(astStack, (astPtr -= length) + 1, statements = new Statement[length], 0, length);
2821 // now we know that we have a method declaration at the top of the ast stack
2822 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2823 md.statements = statements;
2824 md.explicitDeclarations = explicitDeclarations;
2826 // cannot be done in consumeMethodHeader because we have no idea whether or not there
2827 // is a body when we reduce the method header
2828 if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2829 md.modifiers |= AccSemicolonBody;
2831 // store the endPosition (position just before the '}') in case there is
2832 // a trailing comment behind the end of the method
2833 md.bodyEnd = endPosition;
2834 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2836 protected void consumeMethodHeader() {
2837 // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2838 // retrieve end position of method declarator
2839 AbstractMethodDeclaration method = (AbstractMethodDeclaration) astStack[astPtr];
2841 if (currentToken == TokenNameLBRACE) {
2842 method.bodyStart = scanner.currentPosition;
2845 if (currentElement != null) {
2846 if (currentToken == TokenNameSEMICOLON) {
2847 method.modifiers |= AccSemicolonBody;
2848 method.declarationSourceEnd = scanner.currentPosition - 1;
2849 method.bodyEnd = scanner.currentPosition - 1;
2850 if (currentElement.parent != null) {
2851 currentElement = currentElement.parent;
2854 restartRecovery = true; // used to avoid branching back into the regular automaton
2857 protected void consumeMethodHeaderExtendedDims() {
2858 // MethodHeaderExtendedDims ::= Dimsopt
2859 // now we update the returnType of the method
2860 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2861 int extendedDims = intStack[intPtr--];
2862 if (extendedDims != 0) {
2863 TypeReference returnType = md.returnType;
2864 md.sourceEnd = endPosition;
2865 int dims = returnType.dimensions() + extendedDims;
2867 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2869 int sourceStart = returnType.sourceStart;
2870 int sourceEnd = returnType.sourceEnd;
2871 returnType = TypeReference.baseTypeReference(-baseType, dims);
2872 returnType.sourceStart = sourceStart;
2873 returnType.sourceEnd = sourceEnd;
2874 md.returnType = returnType;
2876 md.returnType = this.copyDims(md.returnType, dims);
2878 if (currentToken == TokenNameLBRACE) {
2879 md.bodyStart = endPosition + 1;
2882 if (currentElement != null) {
2883 lastCheckPoint = md.bodyStart;
2887 protected void consumeMethodHeaderName() {
2888 // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2889 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2892 md.selector = identifierStack[identifierPtr];
2893 long selectorSource = identifierPositionStack[identifierPtr--];
2894 identifierLengthPtr--;
2896 md.returnType = getTypeReference(intStack[intPtr--]);
2898 md.declarationSourceStart = intStack[intPtr--];
2899 md.modifiers = intStack[intPtr--];
2901 //highlight starts at selector start
2902 md.sourceStart = (int) (selectorSource >>> 32);
2904 md.sourceEnd = lParenPos;
2905 md.bodyStart = lParenPos + 1;
2906 listLength = 0; // initialize listLength before reading parameters/throws
2909 if (currentElement != null) {
2910 if (currentElement instanceof RecoveredType //|| md.modifiers != 0
2911 || (scanner.getLineNumber(md.returnType.sourceStart) == scanner.getLineNumber(md.sourceStart))) {
2912 lastCheckPoint = md.bodyStart;
2913 currentElement = currentElement.add(md, 0);
2914 lastIgnoredToken = -1;
2916 lastCheckPoint = md.sourceStart;
2917 restartRecovery = true;
2921 protected void consumeMethodHeaderParameters() {
2922 // MethodHeaderParameters ::= FormalParameterListopt ')'
2923 int length = astLengthStack[astLengthPtr--];
2925 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2926 md.sourceEnd = rParenPos;
2929 System.arraycopy(astStack, astPtr + 1, md.arguments = new Argument[length], 0, length);
2931 md.bodyStart = rParenPos + 1;
2932 listLength = 0; // reset listLength after having read all parameters
2934 if (currentElement != null) {
2935 lastCheckPoint = md.bodyStart;
2936 if (currentElement.parseTree() == md)
2939 // might not have been attached yet - in some constructor scenarii
2940 if (md.isConstructor()) {
2941 if ((length != 0) || (currentToken == TokenNameLBRACE) // || (currentToken == TokenNamethrows)
2943 currentElement = currentElement.add(md, 0);
2944 lastIgnoredToken = -1;
2949 protected void consumeMethodHeaderThrowsClause() {
2950 // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2951 int length = astLengthStack[astLengthPtr--];
2953 AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2954 System.arraycopy(astStack, astPtr + 1, md.thrownExceptions = new TypeReference[length], 0, length);
2955 md.sourceEnd = md.thrownExceptions[length - 1].sourceEnd;
2956 md.bodyStart = md.thrownExceptions[length - 1].sourceEnd + 1;
2957 listLength = 0; // reset listLength after having read all thrown exceptions
2959 if (currentElement != null) {
2960 lastCheckPoint = md.bodyStart;
2963 protected void consumeMethodInvocationName() {
2964 // MethodInvocation ::= Name '(' ArgumentListopt ')'
2966 // when the name is only an identifier...we have a message send to "this" (implicit)
2968 MessageSend m = newMessageSend();
2969 m.sourceEnd = rParenPos;
2970 m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2971 m.selector = identifierStack[identifierPtr--];
2972 if (identifierLengthStack[identifierLengthPtr] == 1) {
2973 m.receiver = ThisReference.ThisImplicit;
2974 identifierLengthPtr--;
2976 identifierLengthStack[identifierLengthPtr]--;
2977 m.receiver = getUnspecifiedReference();
2978 m.sourceStart = m.receiver.sourceStart;
2980 pushOnExpressionStack(m);
2982 protected void consumeMethodInvocationPrimary() {
2983 //optimize the push/pop
2984 //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2986 MessageSend m = newMessageSend();
2987 m.sourceStart = (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32);
2988 m.selector = identifierStack[identifierPtr--];
2989 identifierLengthPtr--;
2990 m.receiver = expressionStack[expressionPtr];
2991 m.sourceStart = m.receiver.sourceStart;
2992 m.sourceEnd = rParenPos;
2993 expressionStack[expressionPtr] = m;
2995 protected void consumeMethodInvocationSuper() {
2996 // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2998 MessageSend m = newMessageSend();
2999 m.sourceStart = intStack[intPtr--];
3000 m.sourceEnd = rParenPos;
3001 m.nameSourcePosition = identifierPositionStack[identifierPtr];
3002 m.selector = identifierStack[identifierPtr--];
3003 identifierLengthPtr--;
3004 m.receiver = new SuperReference(m.sourceStart, endPosition);
3005 pushOnExpressionStack(m);
3007 protected void consumeMethodPushModifiersHeaderName() {
3008 // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
3009 // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
3010 MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
3013 md.selector = identifierStack[identifierPtr];
3014 long selectorSource = identifierPositionStack[identifierPtr--];
3015 identifierLengthPtr--;
3018 md.declarationSourceStart = intStack[intPtr--];
3019 md.modifiers = intStack[intPtr--];
3022 md.returnType = getTypeReference(intStack[intPtr--]);
3024 //highlight starts at selector start
3025 md.sourceStart = (int) (selectorSource >>> 32);
3027 md.sourceEnd = lParenPos;
3028 md.bodyStart = lParenPos + 1;
3029 listLength = 0; // initialize listLength before reading parameters/throws
3032 if (currentElement != null) {
3033 lastCheckPoint = md.bodyStart;
3034 currentElement = currentElement.add(md, 0);
3035 lastIgnoredToken = -1;
3038 protected void consumeModifiers() {
3039 int savedModifiersSourceStart = modifiersSourceStart;
3040 checkAnnotation(); // might update modifiers with AccDeprecated
3041 pushOnIntStack(modifiers); // modifiers
3042 if (modifiersSourceStart >= savedModifiersSourceStart) {
3043 modifiersSourceStart = savedModifiersSourceStart;
3045 pushOnIntStack(modifiersSourceStart);
3048 protected void consumeNestedMethod() {
3049 // NestedMethod ::= $empty
3050 jumpOverMethodBody();
3051 nestedMethod[nestedType]++;
3054 protected void consumeNestedType() {
3055 // NestedType ::= $empty
3058 nestedMethod[nestedType] = 0;
3059 } catch (IndexOutOfBoundsException e) {
3060 //except in test's cases, it should never raise
3061 int oldL = nestedMethod.length;
3062 System.arraycopy(nestedMethod, 0, (nestedMethod = new int[oldL + 30]), 0, oldL);
3063 nestedMethod[nestedType] = 0;
3064 // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection
3065 System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL);
3067 variablesCounter[nestedType] = 0;
3069 protected void consumeOneDimLoop() {
3070 // OneDimLoop ::= '[' ']'
3073 protected void consumeOnlySynchronized() {
3074 // OnlySynchronized ::= 'synchronized'
3075 pushOnIntStack(this.synchronizedBlockSourceStart);
3078 protected void consumeOpenBlock() {
3079 // OpenBlock ::= $empty
3081 pushOnIntStack(scanner.startPosition);
3083 realBlockStack[++realBlockPtr] = 0;
3084 } catch (IndexOutOfBoundsException e) {
3085 //realBlockPtr is correct
3086 int oldStackLength = realBlockStack.length;
3087 int oldStack[] = realBlockStack;
3088 realBlockStack = new int[oldStackLength + StackIncrement];
3089 System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength);
3090 realBlockStack[realBlockPtr] = 0;
3093 protected void consumePackageDeclaration() {
3094 // PackageDeclaration ::= 'package' Name ';'
3095 /* build an ImportRef build from the last name
3096 stored in the identifier stack. */
3098 ImportReference impt = compilationUnit.currentPackage;
3099 // flush annotations defined prior to import statements
3100 impt.declarationEnd = endStatementPosition;
3101 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
3103 protected void consumePackageDeclarationName() {
3104 // PackageDeclarationName ::= 'package' Name
3105 /* build an ImportRef build from the last name
3106 stored in the identifier stack. */
3108 ImportReference impt;
3110 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
3111 identifierPtr -= length;
3112 long[] positions = new long[length];
3113 System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length);
3114 System.arraycopy(identifierPositionStack, identifierPtr--, positions, 0, length);
3115 compilationUnit.currentPackage = impt = new ImportReference(tokens, positions, true);
3117 if (currentToken == TokenNameSEMICOLON) {
3118 impt.declarationSourceEnd = scanner.currentPosition - 1;
3120 impt.declarationSourceEnd = impt.sourceEnd;
3122 impt.declarationEnd = impt.declarationSourceEnd;
3123 //endPosition is just before the ;
3124 impt.declarationSourceStart = intStack[intPtr--];
3127 if (currentElement != null) {
3128 lastCheckPoint = impt.declarationSourceEnd + 1;
3129 restartRecovery = true; // used to avoid branching back into the regular automaton
3132 protected void consumePostfixExpression() {
3133 // PostfixExpression ::= Name
3134 pushOnExpressionStack(getUnspecifiedReferenceOptimized());
3136 protected void consumePrimaryNoNewArray() {
3137 // PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
3138 updateSourcePosition(expressionStack[expressionPtr]);
3140 protected void consumePrimaryNoNewArrayArrayType() {
3141 // PrimaryNoNewArray ::= ArrayType '.' 'class'
3143 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(intStack[intPtr--])));
3145 protected void consumePrimaryNoNewArrayName() {
3146 // PrimaryNoNewArray ::= Name '.' 'class'
3148 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
3150 protected void consumePrimaryNoNewArrayNameSuper() {
3151 // PrimaryNoNewArray ::= Name '.' 'super'
3152 pushOnExpressionStack(new QualifiedSuperReference(getTypeReference(0), intStack[intPtr--], endPosition));
3154 protected void consumePrimaryNoNewArrayNameThis() {
3155 // PrimaryNoNewArray ::= Name '.' 'this'
3156 pushOnExpressionStack(new QualifiedThisReference(getTypeReference(0), intStack[intPtr--], endPosition));
3158 protected void consumePrimaryNoNewArrayPrimitiveType() {
3159 // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
3161 pushOnExpressionStack(new ClassLiteralAccess(intStack[intPtr--], getTypeReference(0)));
3163 protected void consumePrimaryNoNewArrayThis() {
3164 // PrimaryNoNewArray ::= 'this'
3165 pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition));
3167 protected void consumePrimitiveType() {
3168 // Type ::= PrimitiveType
3171 protected void consumePushModifiers() {
3172 if ((modifiers & AccSynchronized) != 0) {
3173 /* remove the starting position of the synchronized keyword
3174 * we don't need it when synchronized is part of the modifiers
3178 pushOnIntStack(modifiers); // modifiers
3179 pushOnIntStack(modifiersSourceStart);
3182 protected void consumePushPosition() {
3183 // for source managment purpose
3184 // PushPosition ::= $empty
3185 pushOnIntStack(endPosition);
3187 protected void consumeQualifiedName() {
3188 // QualifiedName ::= Name '.' SimpleName
3189 /*back from the recursive loop of QualifiedName.
3190 Updates identifier length into the length stack*/
3192 identifierLengthStack[--identifierLengthPtr]++;
3194 protected void consumeReferenceType() {
3195 // ReferenceType ::= ClassOrInterfaceType
3198 protected void consumeRestoreDiet() {
3199 // RestoreDiet ::= $empty
3202 protected void consumeRightParen() {
3203 // PushRPAREN ::= ')'
3204 pushOnIntStack(rParenPos);
3206 // This method is part of an automatic generation : do NOT edit-modify
3207 // This method is part of an automatic generation : do NOT edit-modify
3208 protected void consumeRule(int act) {
3210 case 29 : // System.out.println("Type ::= PrimitiveType");
3211 consumePrimitiveType();
3214 case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
3215 consumeReferenceType();
3218 case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName");
3219 consumeQualifiedName();
3222 case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
3223 consumeCompilationUnit();
3226 case 54 : // System.out.println("EnterCompilationUnit ::=");
3227 consumeEnterCompilationUnit();
3230 case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
3231 consumeCatchHeader();
3234 case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
3235 consumeImportDeclarations();
3238 case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
3239 consumeTypeDeclarations();
3242 case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
3243 consumePackageDeclaration();
3246 case 72 : // System.out.println("PackageDeclarationName ::= package Name");
3247 consumePackageDeclarationName();
3250 case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
3251 consumeSingleTypeImportDeclaration();
3254 case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
3255 consumeSingleTypeImportDeclarationName();
3258 case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
3259 consumeTypeImportOnDemandDeclaration();
3262 case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
3263 consumeTypeImportOnDemandDeclarationName();
3266 case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON");
3267 consumeEmptyTypeDeclaration();
3270 case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
3271 consumeClassDeclaration();
3274 case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
3275 consumeClassHeader();
3278 case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");
3279 consumeClassHeaderName();
3282 case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
3283 consumeClassHeaderExtends();
3286 case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
3287 consumeClassHeaderImplements();
3290 case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
3291 consumeInterfaceTypeList();
3294 case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
3295 consumeInterfaceType();
3298 case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
3299 consumeClassBodyDeclarations();
3302 case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
3303 consumeClassBodyDeclaration();
3306 case 110 : // System.out.println("Diet ::=");
3310 case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block");
3311 consumeClassBodyDeclaration();
3314 case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
3315 consumeEmptyClassMemberDeclaration();
3318 case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
3319 consumeFieldDeclaration();
3322 case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
3323 consumeVariableDeclarators();
3326 case 124 : // System.out.println("EnterVariable ::=");
3327 consumeEnterVariable();
3330 case 125 : // System.out.println("ExitVariableWithInitialization ::=");
3331 consumeExitVariableWithInitialization();
3334 case 126 : // System.out.println("ExitVariableWithoutInitialization ::=");
3335 consumeExitVariableWithoutInitialization();
3338 case 127 : // System.out.println("ForceNoDiet ::=");
3339 consumeForceNoDiet();
3342 case 128 : // System.out.println("RestoreDiet ::=");
3343 consumeRestoreDiet();
3346 case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
3347 // set to true to consume a method with a body
3348 consumeMethodDeclaration(true);
3351 case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
3352 // set to false to consume a method without body
3353 consumeMethodDeclaration(false);
3356 case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
3357 consumeMethodHeader();
3360 case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
3361 consumeMethodHeader();
3364 case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN");
3365 consumeMethodPushModifiersHeaderName();
3368 case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN");
3369 consumeMethodPushModifiersHeaderName();
3372 case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");
3373 consumeMethodHeaderName();
3376 case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
3377 consumeMethodHeaderParameters();
3380 case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
3381 consumeMethodHeaderExtendedDims();
3384 case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
3385 consumeMethodHeaderThrowsClause();
3388 case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
3389 consumeConstructorHeader();
3392 case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
3393 consumeConstructorHeaderName();
3396 case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
3397 consumeFormalParameterList();
3400 case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
3401 // the boolean is used to know if the modifiers should be reset
3402 consumeFormalParameter();
3405 case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
3406 consumeClassTypeList();
3409 case 150 : // System.out.println("ClassTypeElt ::= ClassType");
3410 consumeClassTypeElt();
3413 case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
3414 consumeMethodBody();
3417 case 152 : // System.out.println("NestedMethod ::=");
3418 consumeNestedMethod();
3421 case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block");
3422 consumeStaticInitializer();
3425 case 154 : // System.out.println("StaticOnly ::= static");
3426 consumeStaticOnly();
3429 case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3430 consumeConstructorDeclaration();
3433 case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3434 consumeInvalidConstructorDeclaration();
3437 case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
3438 consumeConstructorBody();
3441 case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
3442 consumeConstructorBlockStatements();
3445 case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
3446 consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.This);
3449 case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
3450 consumeExplicitConstructorInvocation(0, ExplicitConstructorCall.Super);
3453 case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
3454 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);
3457 case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
3458 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);
3461 case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
3462 consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);
3465 case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
3466 consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);
3469 case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
3470 consumeInterfaceDeclaration();
3473 case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
3474 consumeInterfaceHeader();
3477 case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");
3478 consumeInterfaceHeaderName();
3481 case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
3482 consumeInterfaceHeaderExtends();
3485 case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
3486 consumeInterfaceMemberDeclarations();
3489 case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
3490 consumeEmptyInterfaceMemberDeclaration();
3493 case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
3497 case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3498 ignoreInvalidConstructorDeclaration(true);
3501 case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3502 ignoreInvalidConstructorDeclaration(false);
3505 case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
3506 consumeEmptyArrayInitializer();
3509 case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
3510 consumeArrayInitializer();
3513 case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
3514 consumeArrayInitializer();
3517 case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
3518 consumeVariableInitializers();
3521 case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
3525 case 192 : // System.out.println("OpenBlock ::=");
3529 case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
3530 consumeBlockStatements();
3533 case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
3534 ignoreInterfaceDeclaration();
3537 case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
3538 consumeLocalVariableDeclarationStatement();
3541 case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
3542 consumeLocalVariableDeclaration();
3545 case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
3546 consumeLocalVariableDeclaration();
3549 case 202 : // System.out.println("PushModifiers ::=");
3550 consumePushModifiers();
3553 case 226 : // System.out.println("EmptyStatement ::= SEMICOLON");
3554 consumeEmptyStatement();
3557 case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");
3558 consumeStatementLabel();
3561 case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");
3562 consumeStatementLabel();
3565 case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
3566 consumeExpressionStatement();
3569 case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
3570 consumeStatementIfNoElse();
3573 case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
3574 consumeStatementIfWithElse();
3577 case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
3578 consumeStatementIfWithElse();
3581 case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
3582 consumeStatementSwitch();
3585 case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
3586 consumeEmptySwitchBlock();
3589 case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
3590 consumeSwitchBlock();
3593 case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
3594 consumeSwitchBlockStatements();
3597 case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
3598 consumeSwitchBlockStatement();
3601 case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
3602 consumeSwitchLabels();
3605 case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
3609 case 251 : // System.out.println("SwitchLabel ::= default COLON");
3610 consumeDefaultLabel();
3613 case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
3614 consumeStatementWhile();
3617 case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
3618 consumeStatementWhile();
3621 case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
3622 consumeStatementDo();
3625 case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
3626 consumeStatementFor();
3629 case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
3630 consumeStatementFor();
3633 case 257 : // System.out.println("ForInit ::= StatementExpressionList");
3637 case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
3638 consumeStatementExpressionList();
3641 case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
3642 consumeSimpleAssertStatement();
3645 case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
3646 consumeAssertStatement();
3649 case 264 : // System.out.println("BreakStatement ::= break SEMICOLON");
3650 consumeStatementBreak();
3653 case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
3654 consumeStatementBreakWithLabel();
3657 case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
3658 consumeStatementContinue();
3661 case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
3662 consumeStatementContinueWithLabel();
3665 case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
3666 consumeStatementReturn();
3669 case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
3670 consumeStatementThrow();
3674 case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
3675 consumeStatementSynchronized();
3678 case 271 : // System.out.println("OnlySynchronized ::= synchronized");
3679 consumeOnlySynchronized();
3682 case 272 : // System.out.println("TryStatement ::= try Block Catches");
3683 consumeStatementTry(false);
3686 case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
3687 consumeStatementTry(true);
3690 case 275 : // System.out.println("Catches ::= Catches CatchClause");
3694 case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
3695 consumeStatementCatch();
3698 case 278 : // System.out.println("PushLPAREN ::= LPAREN");
3702 case 279 : // System.out.println("PushRPAREN ::= RPAREN");
3703 consumeRightParen();
3706 case 283 : // System.out.println("PrimaryNoNewArray ::= this");
3707 consumePrimaryNoNewArrayThis();
3710 case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
3711 consumePrimaryNoNewArray();
3714 case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
3715 consumePrimaryNoNewArrayNameThis();
3718 case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
3719 consumePrimaryNoNewArrayNameSuper();
3722 case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
3723 consumePrimaryNoNewArrayName();
3726 case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
3727 consumePrimaryNoNewArrayArrayType();
3730 case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
3731 consumePrimaryNoNewArrayPrimitiveType();
3734 case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
3735 consumeAllocationHeader();
3738 case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
3739 consumeClassInstanceCreationExpression();
3742 case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
3743 consumeClassInstanceCreationExpressionQualified();
3746 case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
3747 consumeClassInstanceCreationExpressionQualified();
3750 case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
3751 consumeClassInstanceCreationExpressionName();
3754 case 299 : // System.out.println("ClassBodyopt ::=");
3755 consumeClassBodyopt();
3758 case 301 : // System.out.println("EnterAnonymousClassBody ::=");
3759 consumeEnterAnonymousClassBody();
3762 case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
3763 consumeArgumentList();
3766 case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
3767 consumeArrayCreationExpression();
3770 case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
3771 consumeArrayCreationExpression();
3774 case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
3775 consumeDimWithOrWithOutExprs();
3778 case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
3779 consumeDimWithOrWithOutExpr();
3782 case 310 : // System.out.println("Dims ::= DimsLoop");
3786 case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
3787 consumeOneDimLoop();
3790 case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier");
3791 consumeFieldAccess(false);
3794 case 315 : // System.out.println("FieldAccess ::= super DOT Identifier");
3795 consumeFieldAccess(true);
3798 case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");
3799 consumeMethodInvocationName();
3802 case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN");
3803 consumeMethodInvocationPrimary();
3806 case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN");
3807 consumeMethodInvocationSuper();
3810 case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
3811 consumeArrayAccess(true);
3814 case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
3815 consumeArrayAccess(false);
3818 case 322 : // System.out.println("PostfixExpression ::= Name");
3819 consumePostfixExpression();
3822 case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
3823 consumeUnaryExpression(OperatorExpression.PLUS, true);
3826 case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
3827 consumeUnaryExpression(OperatorExpression.MINUS, true);
3830 case 327 : // System.out.println("PushPosition ::=");
3831 consumePushPosition();
3834 case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
3835 consumeUnaryExpression(OperatorExpression.PLUS);
3838 case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
3839 consumeUnaryExpression(OperatorExpression.MINUS);
3842 case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
3843 consumeUnaryExpression(OperatorExpression.PLUS, false);
3846 case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
3847 consumeUnaryExpression(OperatorExpression.MINUS, false);
3850 case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
3851 consumeUnaryExpression(OperatorExpression.TWIDDLE);
3854 case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
3855 consumeUnaryExpression(OperatorExpression.NOT);
3858 case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
3859 consumeCastExpression();
3862 case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
3863 consumeCastExpression();
3866 case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
3867 consumeCastExpressionLL1();
3870 case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
3871 consumeBinaryExpression(OperatorExpression.MULTIPLY);
3874 case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
3875 consumeBinaryExpression(OperatorExpression.DIVIDE);
3878 case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
3879 consumeBinaryExpression(OperatorExpression.REMAINDER);
3882 case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
3883 consumeBinaryExpression(OperatorExpression.PLUS);
3886 case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
3887 consumeBinaryExpression(OperatorExpression.MINUS);
3890 case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
3891 consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);
3894 case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
3895 consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);
3898 case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
3899 consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);
3902 case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
3903 consumeBinaryExpression(OperatorExpression.LESS);
3906 case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
3907 consumeBinaryExpression(OperatorExpression.GREATER);
3910 case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
3911 consumeBinaryExpression(OperatorExpression.LESS_EQUAL);
3914 case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
3915 consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);
3918 case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
3919 consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);
3922 case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
3923 consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);
3926 case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
3927 consumeEqualityExpression(OperatorExpression.NOT_EQUAL);
3930 case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
3931 consumeBinaryExpression(OperatorExpression.AND);
3934 case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
3935 consumeBinaryExpression(OperatorExpression.XOR);
3938 case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
3939 consumeBinaryExpression(OperatorExpression.OR);
3942 case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
3943 consumeBinaryExpression(OperatorExpression.AND_AND);
3946 case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
3947 consumeBinaryExpression(OperatorExpression.OR_OR);
3950 case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
3951 consumeConditionalExpression(OperatorExpression.QUESTIONCOLON);
3954 case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
3955 consumeAssignment();
3958 case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
3959 ignoreExpressionAssignment();
3962 case 379 : // System.out.println("LeftHandSide ::= Name");
3963 consumeLeftHandSide();
3966 case 382 : // System.out.println("AssignmentOperator ::= EQUAL");
3967 consumeAssignmentOperator(EQUAL);
3970 case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
3971 consumeAssignmentOperator(MULTIPLY);
3974 case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
3975 consumeAssignmentOperator(DIVIDE);
3978 case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
3979 consumeAssignmentOperator(REMAINDER);
3982 case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
3983 consumeAssignmentOperator(PLUS);
3986 case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
3987 consumeAssignmentOperator(MINUS);
3990 case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
3991 consumeAssignmentOperator(LEFT_SHIFT);
3994 case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
3995 consumeAssignmentOperator(RIGHT_SHIFT);
3998 case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
3999 consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);
4002 case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
4003 consumeAssignmentOperator(AND);
4006 case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
4007 consumeAssignmentOperator(XOR);
4010 case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
4011 consumeAssignmentOperator(OR);
4014 case 400 : // System.out.println("Expressionopt ::=");
4015 consumeEmptyExpression();
4018 case 404 : // System.out.println("ImportDeclarationsopt ::=");
4019 consumeEmptyImportDeclarationsopt();
4022 case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
4023 consumeImportDeclarationsopt();
4026 case 406 : // System.out.println("TypeDeclarationsopt ::=");
4027 consumeEmptyTypeDeclarationsopt();
4030 case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
4031 consumeTypeDeclarationsopt();
4034 case 408 : // System.out.println("ClassBodyDeclarationsopt ::=");
4035 consumeEmptyClassBodyDeclarationsopt();
4038 case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
4039 consumeClassBodyDeclarationsopt();
4042 case 410 : // System.out.println("Modifiersopt ::=");
4043 consumeDefaultModifiers();
4046 case 411 : // System.out.println("Modifiersopt ::= Modifiers");
4050 case 412 : // System.out.println("BlockStatementsopt ::=");
4051 consumeEmptyBlockStatementsopt();
4054 case 414 : // System.out.println("Dimsopt ::=");
4055 consumeEmptyDimsopt();
4058 case 416 : // System.out.println("ArgumentListopt ::=");
4059 consumeEmptyArgumentListopt();
4062 case 420 : // System.out.println("FormalParameterListopt ::=");
4063 consumeFormalParameterListopt();
4066 case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
4067 consumeEmptyInterfaceMemberDeclarationsopt();
4070 case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
4071 consumeInterfaceMemberDeclarationsopt();
4074 case 426 : // System.out.println("NestedType ::=");
4075 consumeNestedType();
4078 case 427 : // System.out.println("ForInitopt ::=");
4079 consumeEmptyForInitopt();
4082 case 429 : // System.out.println("ForUpdateopt ::=");
4083 consumeEmptyForUpdateopt();
4086 case 433 : // System.out.println("Catchesopt ::=");
4087 consumeEmptyCatchesopt();
4090 case 435 : // System.out.println("ArrayInitializeropt ::=");
4091 consumeEmptyArrayInitializeropt();
4097 protected void consumeSimpleAssertStatement() {
4098 // AssertStatement ::= 'assert' Expression ';'
4099 expressionLengthPtr--;
4100 pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4103 protected void consumeSingleTypeImportDeclaration() {
4104 // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
4106 ImportReference impt = (ImportReference) astStack[astPtr];
4107 // flush annotations defined prior to import statements
4108 impt.declarationEnd = endStatementPosition;
4109 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
4112 if (currentElement != null) {
4113 lastCheckPoint = impt.declarationSourceEnd + 1;
4114 currentElement = currentElement.add(impt, 0);
4115 lastIgnoredToken = -1;
4116 restartRecovery = true;
4117 // used to avoid branching back into the regular automaton
4120 protected void consumeSingleTypeImportDeclarationName() {
4121 // SingleTypeImportDeclarationName ::= 'import' Name
4122 /* push an ImportRef build from the last name
4123 stored in the identifier stack. */
4125 ImportReference impt;
4127 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4128 identifierPtr -= length;
4129 long[] positions = new long[length];
4130 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4131 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4132 pushOnAstStack(impt = new ImportReference(tokens, positions, false));
4134 if (currentToken == TokenNameSEMICOLON) {
4135 impt.declarationSourceEnd = scanner.currentPosition - 1;
4137 impt.declarationSourceEnd = impt.sourceEnd;
4139 impt.declarationEnd = impt.declarationSourceEnd;
4140 //endPosition is just before the ;
4141 impt.declarationSourceStart = intStack[intPtr--];
4144 if (currentElement != null) {
4145 lastCheckPoint = impt.declarationSourceEnd + 1;
4146 currentElement = currentElement.add(impt, 0);
4147 lastIgnoredToken = -1;
4148 restartRecovery = true; // used to avoid branching back into the regular automaton
4151 protected void consumeStatementBreak() {
4152 // BreakStatement ::= 'break' ';'
4153 // break pushs a position on intStack in case there is no label
4155 pushOnAstStack(new Break(null, intStack[intPtr--], endPosition));
4157 protected void consumeStatementBreakWithLabel() {
4158 // BreakStatement ::= 'break' Identifier ';'
4159 // break pushs a position on intStack in case there is no label
4161 pushOnAstStack(new Break(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
4162 identifierLengthPtr--;
4164 protected void consumeStatementCatch() {
4165 // CatchClause ::= 'catch' '(' FormalParameter ')' Block
4167 //catch are stored directly into the Try
4168 //has they always comes two by two....
4169 //we remove one entry from the astlengthPtr.
4170 //The construction of the try statement must
4171 //then fetch the catches using 2*i and 2*i + 1
4174 listLength = 0; // reset formalParameter counter (incremented for catch variable)
4176 protected void consumeStatementContinue() {
4177 // ContinueStatement ::= 'continue' ';'
4178 // continue pushs a position on intStack in case there is no label
4180 pushOnAstStack(new Continue(null, intStack[intPtr--], endPosition));
4182 protected void consumeStatementContinueWithLabel() {
4183 // ContinueStatement ::= 'continue' Identifier ';'
4184 // continue pushs a position on intStack in case there is no label
4186 pushOnAstStack(new Continue(identifierStack[identifierPtr--], intStack[intPtr--], endPosition));
4187 identifierLengthPtr--;
4189 protected void consumeStatementDo() {
4190 // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
4192 //the 'while' pushes a value on intStack that we need to remove
4195 //optimize the push/pop
4196 Statement action = (Statement) astStack[astPtr];
4197 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4198 expressionLengthPtr--;
4199 astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
4201 expressionLengthPtr--;
4202 astStack[astPtr] = new DoStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
4205 protected void consumeStatementExpressionList() {
4206 // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
4207 concatExpressionLists();
4209 protected void consumeStatementFor() {
4210 // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
4211 // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
4214 Expression cond = null;
4215 Statement[] inits, updates;
4217 boolean scope = true;
4220 astLengthPtr--; // we need to consume it
4221 action = (Statement) astStack[astPtr--];
4222 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4226 //updates are on the expresion stack
4227 if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) {
4230 expressionPtr -= length;
4231 System.arraycopy(expressionStack, expressionPtr + 1, updates = new Statement[length], 0, length);
4234 if (expressionLengthStack[expressionLengthPtr--] != 0)
4235 cond = expressionStack[expressionPtr--];
4237 //inits may be on two different stacks
4238 if ((length = astLengthStack[astLengthPtr--]) == 0) {
4242 if (length == -1) { //on expressionStack
4244 length = expressionLengthStack[expressionLengthPtr--];
4245 expressionPtr -= length;
4246 System.arraycopy(expressionStack, expressionPtr + 1, inits = new Statement[length], 0, length);
4247 } else { //on astStack
4249 System.arraycopy(astStack, astPtr + 1, inits = new Statement[length], 0, length);
4252 if (action instanceof Block) {
4253 pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endStatementPosition));
4255 pushOnAstStack(new ForStatement(inits, cond, updates, action, scope, intStack[intPtr--], endPosition));
4258 protected void consumeStatementIfNoElse() {
4259 // IfThenStatement ::= 'if' '(' Expression ')' Statement
4261 //optimize the push/pop
4262 expressionLengthPtr--;
4263 Statement thenStatement = (Statement) astStack[astPtr];
4264 if (thenStatement instanceof Block) {
4265 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
4266 } else if (thenStatement instanceof EmptyStatement) {
4267 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
4269 astStack[astPtr] = new IfStatement(expressionStack[expressionPtr--], thenStatement, intStack[intPtr--], endStatementPosition);
4272 protected void consumeStatementIfWithElse() {
4273 // IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
4274 // IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
4276 astLengthPtr--; // optimized {..., Then, Else } ==> {..., If }
4277 expressionLengthPtr--;
4278 //optimize the push/pop
4279 Statement elseStatement = (Statement) astStack[astPtr--];
4280 Statement thenStatement = (Statement) astStack[astPtr];
4281 if (elseStatement instanceof EmptyStatement) {
4282 elseStatement = Block.None;
4284 if (thenStatement instanceof EmptyStatement) {
4285 thenStatement = Block.None;
4287 if (elseStatement instanceof Block) {
4289 new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
4292 new IfStatement(expressionStack[expressionPtr--], thenStatement, elseStatement, intStack[intPtr--], endStatementPosition);
4295 protected void consumeStatementLabel() {
4296 // LabeledStatement ::= 'Identifier' ':' Statement
4297 // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
4301 Statement stmt = (Statement) astStack[astPtr];
4302 if (stmt instanceof EmptyStatement) {
4304 new LabeledStatement(
4305 identifierStack[identifierPtr],
4307 (int) (identifierPositionStack[identifierPtr--] >>> 32),
4308 endStatementPosition);
4311 new LabeledStatement(
4312 identifierStack[identifierPtr],
4314 (int) (identifierPositionStack[identifierPtr--] >>> 32),
4315 endStatementPosition);
4317 identifierLengthPtr--;
4319 protected void consumeStatementReturn() {
4320 // ReturnStatement ::= 'return' Expressionopt ';'
4321 // return pushs a position on intStack in case there is no expression
4323 if (expressionLengthStack[expressionLengthPtr--] != 0) {
4324 pushOnAstStack(new ReturnStatement(expressionStack[expressionPtr--], intStack[intPtr--], endPosition));
4326 pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition));
4329 protected void consumeStatementSwitch() {
4330 // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
4332 //OpenBlock just makes the semantic action blockStart()
4333 //the block is inlined but a scope need to be created
4334 //if some declaration occurs.
4337 SwitchStatement s = new SwitchStatement();
4338 expressionLengthPtr--;
4339 s.testExpression = expressionStack[expressionPtr--];
4340 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4342 System.arraycopy(astStack, astPtr + 1, s.statements = new Statement[length], 0, length);
4344 s.explicitDeclarations = realBlockStack[realBlockPtr--];
4346 intPtr--; // because of OpenBlock
4347 s.sourceStart = intStack[intPtr--];
4348 s.sourceEnd = endStatementPosition;
4350 protected void consumeStatementSynchronized() {
4351 // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
4352 //optimize the push/pop
4354 if (astLengthStack[astLengthPtr] == 0) {
4355 astLengthStack[astLengthPtr] = 1;
4356 expressionLengthPtr--;
4357 astStack[++astPtr] =
4358 new SynchronizedStatement(expressionStack[expressionPtr--], Block.None, intStack[intPtr--], endStatementPosition);
4360 expressionLengthPtr--;
4362 new SynchronizedStatement(
4363 expressionStack[expressionPtr--],
4364 (Block) astStack[astPtr],
4366 endStatementPosition);
4370 protected void consumeStatementThrow() {
4371 // ThrowStatement ::= 'throw' Expression ';'
4372 expressionLengthPtr--;
4373 pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4375 protected void consumeStatementTry(boolean withFinally) {
4376 //TryStatement ::= 'try' Block Catches
4377 //TryStatement ::= 'try' Block Catchesopt Finally
4380 TryStatement tryStmt = new TryStatement();
4384 tryStmt.finallyBlock = (Block) astStack[astPtr--];
4386 //catches are handle by two <argument-block> [see statementCatch]
4387 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4389 tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--] };
4390 tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--] };
4392 Block[] bks = (tryStmt.catchBlocks = new Block[length]);
4393 Argument[] args = (tryStmt.catchArguments = new Argument[length]);
4394 while (length-- > 0) {
4395 bks[length] = (Block) astStack[astPtr--];
4396 args[length] = (Argument) astStack[astPtr--];
4402 tryStmt.tryBlock = (Block) astStack[astPtr--];
4405 tryStmt.sourceEnd = endStatementPosition;
4406 tryStmt.sourceStart = intStack[intPtr--];
4407 pushOnAstStack(tryStmt);
4409 protected void consumeStatementWhile() {
4410 // WhileStatement ::= 'while' '(' Expression ')' Statement
4411 // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
4413 Statement action = (Statement) astStack[astPtr];
4414 expressionLengthPtr--;
4415 if (action instanceof Block) {
4416 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endStatementPosition);
4418 if (action instanceof EmptyStatement && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4419 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], null, intStack[intPtr--], endPosition);
4421 astStack[astPtr] = new WhileStatement(expressionStack[expressionPtr--], action, intStack[intPtr--], endPosition);
4425 protected void consumeStaticInitializer() {
4426 // StaticInitializer ::= StaticOnly Block
4427 //push an Initializer
4428 //optimize the push/pop
4429 Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic);
4430 astStack[astPtr] = initializer;
4431 initializer.sourceEnd = endStatementPosition;
4432 initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
4433 nestedMethod[nestedType]--;
4434 initializer.declarationSourceStart = intStack[intPtr--];
4437 if (currentElement != null) {
4438 lastCheckPoint = initializer.declarationSourceEnd;
4439 currentElement = currentElement.add(initializer, 0);
4440 lastIgnoredToken = -1;
4443 protected void consumeStaticOnly() {
4444 // StaticOnly ::= 'static'
4445 int savedModifiersSourceStart = modifiersSourceStart;
4446 checkAnnotation(); // might update declaration source start
4447 if (modifiersSourceStart >= savedModifiersSourceStart) {
4448 modifiersSourceStart = savedModifiersSourceStart;
4450 pushOnIntStack(modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
4451 jumpOverMethodBody();
4452 nestedMethod[nestedType]++;
4456 if (currentElement != null) {
4457 recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers
4460 protected void consumeSwitchBlock() {
4461 // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
4464 protected void consumeSwitchBlockStatement() {
4465 // SwitchBlockStatement ::= SwitchLabels BlockStatements
4468 protected void consumeSwitchBlockStatements() {
4469 // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
4472 protected void consumeSwitchLabels() {
4473 // SwitchLabels ::= SwitchLabels SwitchLabel
4474 optimizedConcatNodeLists();
4476 protected void consumeToken(int type) {
4477 /* remember the last consumed value */
4478 /* try to minimize the number of build values */
4479 if (scanner.wasNonExternalizedStringLiteral) {
4480 StringLiteral[] literals = this.scanner.nonNLSStrings;
4481 // could not reproduce, but this is the only NPE
4482 // added preventive null check see PR 9035
4483 if (literals != null) {
4484 for (int i = 0, max = literals.length; i < max; i++) {
4485 problemReporter().nonExternalizedStringLiteral(literals[i]);
4488 scanner.currentLine = null;
4489 scanner.wasNonExternalizedStringLiteral = false;
4491 // clear the commentPtr of the scanner in case we read something different from a modifier
4493 // case TokenNameabstract :
4494 // case TokenNamestrictfp :
4495 // case TokenNamefinal :
4496 // case TokenNamenative :
4497 // case TokenNameprivate :
4498 // case TokenNameprotected :
4499 // case TokenNamepublic :
4500 // case TokenNametransient :
4501 // case TokenNamevolatile :
4502 case TokenNamestatic :
4503 // case TokenNamesynchronized :
4506 scanner.commentPtr = -1;
4508 //System.out.println(scanner.toStringAction(type));
4510 case TokenNameIdentifier :
4512 if (scanner.useAssertAsAnIndentifier) {
4513 long positions = identifierPositionStack[identifierPtr];
4514 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
4516 scanner.commentPtr = -1;
4518 // case TokenNameinterface :
4519 // adjustInterfaceModifiers();
4520 // //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
4521 // pushOnIntStack(scanner.startPosition);
4522 // pushOnIntStack(scanner.currentPosition - 1);
4523 // scanner.commentPtr = -1;
4525 // case TokenNameabstract :
4526 // checkAndSetModifiers(AccAbstract);
4528 // case TokenNamestrictfp :
4529 // checkAndSetModifiers(AccStrictfp);
4531 // case TokenNamefinal :
4532 // checkAndSetModifiers(AccFinal);
4534 // case TokenNamenative :
4535 // checkAndSetModifiers(AccNative);
4537 // case TokenNameprivate :
4538 // checkAndSetModifiers(AccPrivate);
4540 // case TokenNameprotected :
4541 // checkAndSetModifiers(AccProtected);
4543 // case TokenNamepublic :
4544 // checkAndSetModifiers(AccPublic);
4546 // case TokenNametransient :
4547 // checkAndSetModifiers(AccTransient);
4549 // case TokenNamevolatile :
4550 // checkAndSetModifiers(AccVolatile);
4552 case TokenNamestatic :
4553 checkAndSetModifiers(AccStatic);
4555 // case TokenNamesynchronized :
4556 // this.synchronizedBlockSourceStart = scanner.startPosition;
4557 // checkAndSetModifiers(AccSynchronized);
4559 // //==============================
4560 // case TokenNamevoid :
4561 // pushIdentifier(-T_void);
4562 // pushOnIntStack(scanner.currentPosition - 1);
4563 // pushOnIntStack(scanner.startPosition);
4564 // scanner.commentPtr = -1;
4566 // //push a default dimension while void is not part of the primitive
4567 // //declaration baseType and so takes the place of a type without getting into
4568 // //regular type parsing that generates a dimension on intStack
4569 // case TokenNameboolean :
4570 // pushIdentifier(-T_boolean);
4571 // pushOnIntStack(scanner.currentPosition - 1);
4572 // pushOnIntStack(scanner.startPosition);
4573 // scanner.commentPtr = -1;
4575 // case TokenNamebyte :
4576 // pushIdentifier(-T_byte);
4577 // pushOnIntStack(scanner.currentPosition - 1);
4578 // pushOnIntStack(scanner.startPosition);
4579 // scanner.commentPtr = -1;
4581 // case TokenNamechar :
4582 // pushIdentifier(-T_char);
4583 // pushOnIntStack(scanner.currentPosition - 1);
4584 // pushOnIntStack(scanner.startPosition);
4585 // scanner.commentPtr = -1;
4587 // case TokenNamedouble :
4588 // pushIdentifier(-T_double);
4589 // pushOnIntStack(scanner.currentPosition - 1);
4590 // pushOnIntStack(scanner.startPosition);
4591 // scanner.commentPtr = -1;
4593 // case TokenNamefloat :
4594 // pushIdentifier(-T_float);
4595 // pushOnIntStack(scanner.currentPosition - 1);
4596 // pushOnIntStack(scanner.startPosition);
4597 // scanner.commentPtr = -1;
4599 // case TokenNameint :
4600 // pushIdentifier(-T_int);
4601 // pushOnIntStack(scanner.currentPosition - 1);
4602 // pushOnIntStack(scanner.startPosition);
4603 // scanner.commentPtr = -1;
4605 // case TokenNamelong :
4606 // pushIdentifier(-T_long);
4607 // pushOnIntStack(scanner.currentPosition - 1);
4608 // pushOnIntStack(scanner.startPosition);
4609 // scanner.commentPtr = -1;
4611 // case TokenNameshort :
4612 // pushIdentifier(-T_short);
4613 // pushOnIntStack(scanner.currentPosition - 1);
4614 // pushOnIntStack(scanner.startPosition);
4615 // scanner.commentPtr = -1;
4617 //==============================
4618 case TokenNameIntegerLiteral :
4619 pushOnExpressionStack(new IntLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4620 scanner.commentPtr = -1;
4622 case TokenNameLongLiteral :
4623 pushOnExpressionStack(new LongLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4624 scanner.commentPtr = -1;
4626 case TokenNameFloatingPointLiteral :
4627 pushOnExpressionStack(
4628 new FloatLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4629 scanner.commentPtr = -1;
4631 case TokenNameDoubleLiteral :
4632 pushOnExpressionStack(
4633 new DoubleLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4634 scanner.commentPtr = -1;
4636 case TokenNameCharacterLiteral :
4637 pushOnExpressionStack(new CharLiteral(scanner.getCurrentTokenSource(), scanner.startPosition, scanner.currentPosition - 1));
4638 scanner.commentPtr = -1;
4640 case TokenNameStringLiteral :
4641 StringLiteral stringLiteral =
4642 new StringLiteral(scanner.getCurrentTokenSourceString(), scanner.startPosition, scanner.currentPosition - 1);
4643 pushOnExpressionStack(stringLiteral);
4644 scanner.commentPtr = -1;
4646 case TokenNamefalse :
4647 pushOnExpressionStack(new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1));
4648 scanner.commentPtr = -1;
4650 case TokenNametrue :
4651 pushOnExpressionStack(new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1));
4653 case TokenNamenull :
4654 pushOnExpressionStack(new NullLiteral(scanner.startPosition, scanner.currentPosition - 1));
4656 //============================
4657 // case TokenNamesuper :
4658 // case TokenNamethis :
4659 // endPosition = scanner.currentPosition - 1;
4660 // pushOnIntStack(scanner.startPosition);
4662 // case TokenNameassert :
4663 // case TokenNameimport :
4664 // case TokenNamepackage :
4665 // case TokenNamethrow :
4670 case TokenNameswitch :
4671 // case TokenNametry :
4672 case TokenNamewhile :
4673 case TokenNamebreak :
4674 case TokenNamecontinue :
4675 case TokenNamereturn :
4676 case TokenNamecase :
4677 pushOnIntStack(scanner.startPosition);
4679 case TokenNameclass :
4680 pushOnIntStack(scanner.currentPosition - 1);
4681 pushOnIntStack(scanner.startPosition);
4683 case TokenNamedefault :
4684 pushOnIntStack(scanner.startPosition);
4685 pushOnIntStack(scanner.currentPosition - 1);
4687 //let extra semantic action decide when to push
4688 case TokenNameRBRACKET :
4689 case TokenNamePLUS :
4690 case TokenNameMINUS :
4692 case TokenNameTWIDDLE :
4693 endPosition = scanner.startPosition;
4695 case TokenNamePLUS_PLUS :
4696 case TokenNameMINUS_MINUS :
4697 endPosition = scanner.startPosition;
4698 endStatementPosition = scanner.currentPosition - 1;
4700 case TokenNameRBRACE :
4701 case TokenNameSEMICOLON :
4702 endStatementPosition = scanner.currentPosition - 1;
4703 endPosition = scanner.startPosition - 1;
4704 //the item is not part of the potential futur expression/statement
4706 // in order to handle ( expression) ////// (cast)expression///// foo(x)
4707 case TokenNameRPAREN :
4708 rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4710 case TokenNameLPAREN :
4711 lParenPos = scanner.startPosition;
4713 // case TokenNameQUESTION :
4714 // case TokenNameCOMMA :
4715 // case TokenNameCOLON :
4716 // case TokenNameEQUAL :
4717 // case TokenNameLBRACKET :
4718 // case TokenNameDOT :
4719 // case TokenNameERROR :
4720 // case TokenNameEOF :
4721 // case TokenNamecase :
4722 // case TokenNamecatch :
4723 // case TokenNameelse :
4724 // case TokenNameextends :
4725 // case TokenNamefinally :
4726 // case TokenNameimplements :
4727 // case TokenNamethrows :
4728 // case TokenNameinstanceof :
4729 // case TokenNameEQUAL_EQUAL :
4730 // case TokenNameLESS_EQUAL :
4731 // case TokenNameGREATER_EQUAL :
4732 // case TokenNameNOT_EQUAL :
4733 // case TokenNameLEFT_SHIFT :
4734 // case TokenNameRIGHT_SHIFT :
4735 // case TokenNameUNSIGNED_RIGHT_SHIFT :
4736 // case TokenNamePLUS_EQUAL :
4737 // case TokenNameMINUS_EQUAL :
4738 // case TokenNameMULTIPLY_EQUAL :
4739 // case TokenNameDIVIDE_EQUAL :
4740 // case TokenNameAND_EQUAL :
4741 // case TokenNameOR_EQUAL :
4742 // case TokenNameXOR_EQUAL :
4743 // case TokenNameREMAINDER_EQUAL :
4744 // case TokenNameLEFT_SHIFT_EQUAL :
4745 // case TokenNameRIGHT_SHIFT_EQUAL :
4746 // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
4747 // case TokenNameOR_OR :
4748 // case TokenNameAND_AND :
4749 // case TokenNameREMAINDER :
4750 // case TokenNameXOR :
4751 // case TokenNameAND :
4752 // case TokenNameMULTIPLY :
4753 // case TokenNameOR :
4754 // case TokenNameDIVIDE :
4755 // case TokenNameGREATER :
4756 // case TokenNameLESS :
4759 protected void consumeTypeDeclarations() {
4760 // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4763 protected void consumeTypeDeclarationsopt() {
4764 // TypeDeclarationsopt ::= TypeDeclarations
4766 if ((length = astLengthStack[astLengthPtr--]) != 0) {
4768 System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length);
4771 protected void consumeTypeImportOnDemandDeclaration() {
4772 // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4774 ImportReference impt = (ImportReference) astStack[astPtr];
4775 // flush annotations defined prior to import statements
4776 impt.declarationEnd = endStatementPosition;
4777 impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
4780 if (currentElement != null) {
4781 lastCheckPoint = impt.declarationSourceEnd + 1;
4782 currentElement = currentElement.add(impt, 0);
4783 restartRecovery = true;
4784 lastIgnoredToken = -1;
4785 // used to avoid branching back into the regular automaton
4788 protected void consumeTypeImportOnDemandDeclarationName() {
4789 // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4790 /* push an ImportRef build from the last name
4791 stored in the identifier stack. */
4793 ImportReference impt;
4795 char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4796 identifierPtr -= length;
4797 long[] positions = new long[length];
4798 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4799 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4800 pushOnAstStack(impt = new ImportReference(tokens, positions, true));
4802 if (currentToken == TokenNameSEMICOLON) {
4803 impt.declarationSourceEnd = scanner.currentPosition - 1;
4805 impt.declarationSourceEnd = impt.sourceEnd;
4807 impt.declarationEnd = impt.declarationSourceEnd;
4808 //endPosition is just before the ;
4809 impt.declarationSourceStart = intStack[intPtr--];
4812 if (currentElement != null) {
4813 lastCheckPoint = impt.declarationSourceEnd + 1;
4814 currentElement = currentElement.add(impt, 0);
4815 lastIgnoredToken = -1;
4816 restartRecovery = true; // used to avoid branching back into the regular automaton
4819 protected void consumeUnaryExpression(int op) {
4820 // UnaryExpression ::= '+' PushPosition UnaryExpression
4821 // UnaryExpression ::= '-' PushPosition UnaryExpression
4822 // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4823 // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4825 //optimize the push/pop
4827 //handle manually the -2147483648 while it is not a real
4828 //computation of an - and 2147483648 (notice that 2147483648
4829 //is Integer.MAX_VALUE+1.....)
4830 //Same for -9223372036854775808L ............
4832 //intStack have the position of the operator
4834 Expression r, exp = expressionStack[expressionPtr];
4836 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4837 r = expressionStack[expressionPtr] = new IntLiteralMinValue();
4839 if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4840 r = expressionStack[expressionPtr] = new LongLiteralMinValue();
4842 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4846 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4848 r.sourceStart = intStack[intPtr--];
4849 r.sourceEnd = exp.sourceEnd;
4851 protected void consumeUnaryExpression(int op, boolean post) {
4852 // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4853 // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4855 // ++ and -- operators
4856 //optimize the push/pop
4858 //intStack has the position of the operator when prefix
4860 Expression leftHandSide = expressionStack[expressionPtr];
4861 if (leftHandSide instanceof Reference) {
4862 // ++foo()++ is unvalid
4864 expressionStack[expressionPtr] = new PostfixExpression(leftHandSide, IntLiteral.One, op, endStatementPosition);
4866 expressionStack[expressionPtr] = new PrefixExpression(leftHandSide, IntLiteral.One, op, intStack[intPtr--]);
4869 //the ++ or the -- is NOT taken into account if code gen proceeds
4873 problemReporter().invalidUnaryExpression(leftHandSide);
4876 protected void consumeVariableDeclarators() {
4877 // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4878 optimizedConcatNodeLists();
4880 protected void consumeVariableInitializers() {
4881 // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4882 concatExpressionLists();
4884 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4885 return typeRef.copyDims(dim);
4887 protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4888 return new FieldDeclaration(null, name, sourceStart, sourceEnd);
4891 protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4892 return new LocalDeclaration(null, name, sourceStart, sourceEnd);
4895 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4897 CompilationUnitDeclaration parsedUnit;
4901 parsedUnit = parse(sourceUnit, compilationResult);
4907 protected void dispatchDeclarationInto(int length) {
4908 /* they are length on astStack that should go into
4909 methods fields constructors lists of the typeDecl
4911 Return if there is a constructor declaration in the methods declaration */
4913 // Looks for the size of each array .
4917 int[] flag = new int[length + 1]; //plus one -- see <HERE>
4918 int size1 = 0, size2 = 0, size3 = 0;
4919 for (int i = length - 1; i >= 0; i--) {
4920 AstNode astNode = astStack[astPtr--];
4921 if (astNode instanceof AbstractMethodDeclaration) {
4922 //methods and constructors have been regrouped into one single list
4926 if (astNode instanceof TypeDeclaration) {
4938 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
4940 typeDecl.fields = new FieldDeclaration[size1];
4942 typeDecl.methods = new AbstractMethodDeclaration[size2];
4944 typeDecl.memberTypes = new MemberTypeDeclaration[size3];
4947 size1 = size2 = size3 = 0;
4948 int flagI = flag[0], start = 0;
4950 for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
4952 if (flagI != flag[end]) //treat the last element as a ended flag.....
4956 size1 += (length2 = end - start);
4957 System.arraycopy(astStack, astPtr + start + 1, typeDecl.fields, size1 - length2, length2);
4960 size2 += (length2 = end - start);
4961 System.arraycopy(astStack, astPtr + start + 1, typeDecl.methods, size2 - length2, length2);
4964 size3 += (length2 = end - start);
4965 System.arraycopy(astStack, astPtr + start + 1, typeDecl.memberTypes, size3 - length2, length2);
4968 flagI = flag[start = end];
4972 if (typeDecl.memberTypes != null) {
4973 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4974 typeDecl.memberTypes[i].enclosingType = typeDecl;
4978 protected CompilationUnitDeclaration endParse(int act) {
4982 if (currentElement != null) {
4983 currentElement.topElement().updateParseTree();
4984 if (VERBOSE_RECOVERY) {
4985 System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4986 System.out.println("--------------------------"); //$NON-NLS-1$
4987 System.out.println(compilationUnit);
4988 System.out.println("----------------------------------"); //$NON-NLS-1$
4991 if (diet & VERBOSE_RECOVERY) {
4992 System.out.print(Util.bind("parser.regularParse")); //$NON-NLS-1$
4993 System.out.println("--------------------------"); //$NON-NLS-1$
4994 System.out.println(compilationUnit);
4995 System.out.println("----------------------------------"); //$NON-NLS-1$
4998 if (scanner.recordLineSeparator) {
4999 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
5001 return compilationUnit;
5004 * Flush annotations defined prior to a given positions.
5006 * Note: annotations are stacked in syntactical order
5008 * Either answer given <position>, or the end position of a comment line
5009 * immediately following the <position> (same line)
5013 * } // end of method foo
5016 public int flushAnnotationsDefinedPriorTo(int position) {
5018 int lastAnnotationIndex = scanner.commentPtr;
5019 if (lastAnnotationIndex < 0)
5020 return position; // no comment
5022 // compute the index of the first obsolete comment
5023 int index = lastAnnotationIndex;
5025 while (index >= 0) {
5026 int commentEnd = scanner.commentStops[index];
5028 commentEnd = -commentEnd; // negative end position for non-javadoc comments
5029 if (commentEnd <= position) {
5035 // if the source at <position> is immediately followed by a line comment, then
5036 // flush this comment and shift <position> to the comment end.
5037 if (validCount > 0) {
5038 int immediateCommentEnd = -scanner.commentStops[index + 1]; //non-javadoc comment end positions are negative
5039 if (immediateCommentEnd > 0) { // only tolerating non-javadoc comments
5040 // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
5041 immediateCommentEnd--; // comment end in one char too far
5042 if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)) {
5043 position = immediateCommentEnd;
5044 validCount--; // flush this comment
5049 // position can be located in the middle of a line break
5050 // this is a bug on Windows platform only.
5051 // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557
5052 char[] source = scanner.source;
5054 if ((position < source.length)
5055 && (source[position] == '\r')
5056 && ((position + 1) < source.length)
5057 && (source[position + 1] == '\n')) {
5061 return position; // no obsolete comment
5063 if (validCount > 0) { // move valid comment infos, overriding obsolete comment infos
5064 System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount);
5065 System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount);
5067 scanner.commentPtr = validCount - 1;
5070 public final int getFirstToken() {
5071 // the first token is a virtual token that
5072 // allows the parser to parse several goals
5073 // even if they aren't LALR(1)....
5074 // Goal ::= '++' CompilationUnit
5075 // Goal ::= '--' MethodBody
5076 // Goal ::= '==' ConstructorBody
5078 // Goal ::= '>>' StaticInitializer
5079 // Goal ::= '>>' Block
5080 // -- error recovery
5081 // Goal ::= '>>>' Headers
5082 // Goal ::= '*' BlockStatements
5083 // Goal ::= '*' MethodPushModifiersHeader
5085 // Goal ::= '&&' FieldDeclaration
5086 // Goal ::= '||' ImportDeclaration
5087 // Goal ::= '?' PackageDeclaration
5088 // Goal ::= '+' TypeDeclaration
5089 // Goal ::= '/' GenericMethodDeclaration
5090 // Goal ::= '&' ClassBodyDeclaration
5092 // Goal ::= '%' Expression
5093 // -- completion parser
5094 // Goal ::= '!' ConstructorBlockStatementsopt
5095 // Goal ::= '~' BlockStatementsopt
5100 * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
5101 * The array is a flattened structure: 2*n entries with consecutives start and end positions.
5103 * If no JavaDoc is available, then null is answered instead of an empty array.
5105 * e.g. { 10, 20, 25, 45 } --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
5107 public int[] getJavaDocPositions() {
5109 int javadocCount = 0;
5110 for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
5111 // javadoc only (non javadoc comment have negative end positions.)
5112 if (scanner.commentStops[i] > 0) {
5116 if (javadocCount == 0)
5119 int[] positions = new int[2 * javadocCount];
5121 for (int i = 0, max = scanner.commentPtr; i <= max; i++) {
5122 // javadoc only (non javadoc comment have negative end positions.)
5123 if (scanner.commentStops[i] > 0) {
5124 positions[index++] = scanner.commentStarts[i];
5125 positions[index++] = scanner.commentStops[i] - 1; //stop is one over
5130 protected void getMethodBodies(CompilationUnitDeclaration unit) {
5131 //fill the methods bodies in order for the code to be generated
5136 if (unit.ignoreMethodBodies) {
5137 unit.ignoreFurtherInvestigation = true;
5139 // if initial diet parse did not work, no need to dig into method bodies.
5142 //real parse of the method....
5143 this.scanner.setSource(unit.compilationResult.compilationUnit.getContents());
5144 if (unit.types != null) {
5145 for (int i = unit.types.length; --i >= 0;)
5146 unit.types[i].parseMethod(this, unit);
5149 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
5150 This variable is a type reference and dim will be its dimensions*/
5154 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
5155 // single variable reference
5157 ref = new SingleTypeReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5159 ref = new ArrayTypeReference(identifierStack[identifierPtr], dim, identifierPositionStack[identifierPtr--]);
5160 ref.sourceEnd = endPosition;
5163 if (length < 0) { //flag for precompiled type reference on base types
5164 ref = TypeReference.baseTypeReference(-length, dim);
5165 ref.sourceStart = intStack[intPtr--];
5167 ref.sourceEnd = intStack[intPtr--];
5170 ref.sourceEnd = endPosition;
5172 } else { //Qualified variable reference
5173 char[][] tokens = new char[length][];
5174 identifierPtr -= length;
5175 long[] positions = new long[length];
5176 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5177 System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
5179 ref = new QualifiedTypeReference(tokens, positions);
5181 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
5182 ref.sourceEnd = endPosition;
5188 protected Expression getTypeReference(Expression exp) {
5190 exp.bits &= ~AstNode.RestrictiveFlagMASK;
5194 protected NameReference getUnspecifiedReference() {
5195 /* build a (unspecified) NameReference which may be qualified*/
5199 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1)
5200 // single variable reference
5201 ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5203 //Qualified variable reference
5205 char[][] tokens = new char[length][];
5206 identifierPtr -= length;
5207 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5208 ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5209 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5213 protected NameReference getUnspecifiedReferenceOptimized() {
5214 /* build a (unspecified) NameReference which may be qualified
5215 The optimization occurs for qualified reference while we are
5216 certain in this case the last item of the qualified name is
5217 a field access. This optimization is IMPORTANT while it results
5218 that when a NameReference is build, the type checker should always
5219 look for that it is not a type reference */
5223 if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
5224 // single variable reference
5225 ref = new SingleNameReference(identifierStack[identifierPtr], identifierPositionStack[identifierPtr--]);
5226 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5227 ref.bits |= LOCAL | FIELD;
5231 //Qualified-variable-reference
5232 //In fact it is variable-reference DOT field-ref , but it would result in a type
5233 //conflict tha can be only reduce by making a superclass (or inetrface ) between
5234 //nameReference and FiledReference or putting FieldReference under NameReference
5235 //or else..........This optimisation is not really relevant so just leave as it is
5237 char[][] tokens = new char[length][];
5238 identifierPtr -= length;
5239 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5240 ref = new QualifiedNameReference(tokens, (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5241 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5242 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5243 ref.bits |= LOCAL | FIELD;
5246 public void goForBlockStatementsOrMethodHeaders() {
5247 //tells the scanner to go for block statements or method headers parsing
5249 firstToken = TokenNameMULTIPLY;
5250 scanner.recordLineSeparator = false;
5252 public void goForClassBodyDeclarations() {
5253 //tells the scanner to go for any body declarations parsing
5255 firstToken = TokenNameAND;
5256 scanner.recordLineSeparator = true;
5258 public void goForCompilationUnit() {
5259 //tells the scanner to go for compilation unit parsing
5261 firstToken = TokenNamePLUS_PLUS;
5262 scanner.linePtr = -1;
5263 scanner.recordLineSeparator = true;
5264 scanner.currentLine = null;
5265 scanner.lines = new ArrayList();
5267 public void goForConstructorBody() {
5268 //tells the scanner to go for compilation unit parsing
5270 firstToken = TokenNameEQUAL_EQUAL;
5271 scanner.recordLineSeparator = false;
5273 public void goForExpression() {
5274 //tells the scanner to go for an expression parsing
5276 firstToken = TokenNameREMAINDER;
5277 scanner.recordLineSeparator = false;
5279 public void goForFieldDeclaration() {
5280 //tells the scanner to go for field declaration parsing
5282 firstToken = TokenNameAND_AND;
5283 scanner.recordLineSeparator = true;
5285 public void goForGenericMethodDeclaration() {
5286 //tells the scanner to go for generic method declarations parsing
5288 firstToken = TokenNameDIVIDE;
5289 scanner.recordLineSeparator = true;
5291 public void goForHeaders() {
5292 //tells the scanner to go for headers only parsing
5294 firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
5295 scanner.recordLineSeparator = true;
5297 public void goForImportDeclaration() {
5298 //tells the scanner to go for import declaration parsing
5300 firstToken = TokenNameOR_OR;
5301 scanner.recordLineSeparator = true;
5303 public void goForInitializer() {
5304 //tells the scanner to go for initializer parsing
5306 firstToken = TokenNameRIGHT_SHIFT;
5307 scanner.recordLineSeparator = false;
5309 public void goForMethodBody() {
5310 //tells the scanner to go for method body parsing
5312 firstToken = TokenNameMINUS_MINUS;
5313 scanner.recordLineSeparator = false;
5315 public void goForPackageDeclaration() {
5316 //tells the scanner to go for package declaration parsing
5318 firstToken = TokenNameQUESTION;
5319 scanner.recordLineSeparator = true;
5321 public void goForTypeDeclaration() {
5322 //tells the scanner to go for type (interface or class) declaration parsing
5324 firstToken = TokenNamePLUS;
5325 scanner.recordLineSeparator = true;
5327 public final static void grammar() {
5330 %options ACTION, AN=JavaAction.java, GP=java,
5331 %options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
5332 %options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME ,
5334 --error recovering options.....
5337 --grammar understanding options
5338 %options first follow
5339 %options TRACE=FULL ,
5342 --Usefull macros helping reading/writing semantic actions
5345 /. case $rule_number : // System.out.println("$rule_text");
5353 -- here it starts really ------------------------------------------
5358 abstract assert boolean break byte case catch char class
5359 continue default do double else extends false final finally float
5360 for if implements import instanceof int
5361 interface long native new null package private
5362 protected public return short static strictfp super switch
5363 synchronized this throw throws transient true try void
5368 FloatingPointLiteral
5381 UNSIGNED_RIGHT_SHIFT
5392 UNSIGNED_RIGHT_SHIFT_EQUAL
5425 '--' ::= MINUS_MINUS
5426 '==' ::= EQUAL_EQUAL
5428 '>=' ::= GREATER_EQUAL
5431 '>>' ::= RIGHT_SHIFT
5432 '>>>' ::= UNSIGNED_RIGHT_SHIFT
5434 '-=' ::= MINUS_EQUAL
5435 '*=' ::= MULTIPLY_EQUAL
5436 '/=' ::= DIVIDE_EQUAL
5440 '%=' ::= REMAINDER_EQUAL
5441 '<<=' ::= LEFT_SHIFT_EQUAL
5442 '>>=' ::= RIGHT_SHIFT_EQUAL
5443 '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
5477 /. // This method is part of an automatic generation : do NOT edit-modify
5478 protected void consumeRule(int act) {
5484 Goal ::= '++' CompilationUnit
5485 Goal ::= '--' MethodBody
5486 Goal ::= '==' ConstructorBody
5488 Goal ::= '>>' StaticInitializer
5489 Goal ::= '>>' Initializer
5491 Goal ::= '>>>' Headers
5492 Goal ::= '*' BlockStatements
5493 Goal ::= '*' MethodPushModifiersHeader
5494 Goal ::= '*' CatchHeader
5496 Goal ::= '&&' FieldDeclaration
5497 Goal ::= '||' ImportDeclaration
5498 Goal ::= '?' PackageDeclaration
5499 Goal ::= '+' TypeDeclaration
5500 Goal ::= '/' GenericMethodDeclaration
5501 Goal ::= '&' ClassBodyDeclaration
5503 Goal ::= '%' Expression
5504 -- completion parser
5505 Goal ::= '!' ConstructorBlockStatementsopt
5506 Goal ::= '~' BlockStatementsopt
5508 Literal -> IntegerLiteral
5509 Literal -> LongLiteral
5510 Literal -> FloatingPointLiteral
5511 Literal -> DoubleLiteral
5512 Literal -> CharacterLiteral
5513 Literal -> StringLiteral
5515 Literal -> BooleanLiteral
5516 BooleanLiteral -> true
5517 BooleanLiteral -> false
5519 -------------------------------------------------------------
5520 -------------------------------------------------------------
5521 --a Type results in both a push of its dimension(s) and its name(s).
5523 Type ::= PrimitiveType
5524 /.$putCase consumePrimitiveType(); $break ./
5525 Type -> ReferenceType
5527 PrimitiveType -> NumericType
5528 NumericType -> IntegralType
5529 NumericType -> FloatingPointType
5531 PrimitiveType -> 'boolean'
5532 PrimitiveType -> 'void'
5533 IntegralType -> 'byte'
5534 IntegralType -> 'short'
5535 IntegralType -> 'int'
5536 IntegralType -> 'long'
5537 IntegralType -> 'char'
5538 FloatingPointType -> 'float'
5539 FloatingPointType -> 'double'
5541 ReferenceType ::= ClassOrInterfaceType
5542 /.$putCase consumeReferenceType(); $break ./
5543 ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0
5545 ClassOrInterfaceType -> Name
5548 -- These rules have been rewritten to avoid some conflicts introduced
5549 -- by adding the 1.1 features
5551 -- ArrayType ::= PrimitiveType '[' ']'
5552 -- ArrayType ::= Name '[' ']'
5553 -- ArrayType ::= ArrayType '[' ']'
5556 ArrayType ::= PrimitiveType Dims
5557 ArrayType ::= Name Dims
5559 ClassType -> ClassOrInterfaceType
5562 --------------------------------------------------------------
5563 --------------------------------------------------------------
5566 Name -> QualifiedName
5568 SimpleName -> 'Identifier'
5570 QualifiedName ::= Name '.' SimpleName
5571 /.$putCase consumeQualifiedName(); $break ./
5573 CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
5574 /.$putCase consumeCompilationUnit(); $break ./
5576 EnterCompilationUnit ::= $empty
5577 /.$putCase consumeEnterCompilationUnit(); $break ./
5580 Headers ::= Headers Header
5582 Header -> ImportDeclaration
5583 Header -> PackageDeclaration
5584 Header -> ClassHeader
5585 Header -> InterfaceHeader
5586 Header -> StaticInitializer
5587 Header -> MethodHeader
5588 Header -> ConstructorHeader
5589 Header -> FieldDeclaration
5590 Header -> AllocationHeader
5592 CatchHeader ::= 'catch' '(' FormalParameter ')' '{'
5593 /.$putCase consumeCatchHeader(); $break ./
5595 ImportDeclarations -> ImportDeclaration
5596 ImportDeclarations ::= ImportDeclarations ImportDeclaration
5597 /.$putCase consumeImportDeclarations(); $break ./
5599 TypeDeclarations -> TypeDeclaration
5600 TypeDeclarations ::= TypeDeclarations TypeDeclaration
5601 /.$putCase consumeTypeDeclarations(); $break ./
5603 PackageDeclaration ::= PackageDeclarationName ';'
5604 /.$putCase consumePackageDeclaration(); $break ./
5606 PackageDeclarationName ::= 'package' Name
5607 /.$putCase consumePackageDeclarationName(); $break ./
5609 ImportDeclaration -> SingleTypeImportDeclaration
5610 ImportDeclaration -> TypeImportOnDemandDeclaration
5612 SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
5613 /.$putCase consumeSingleTypeImportDeclaration(); $break ./
5615 SingleTypeImportDeclarationName ::= 'import' Name
5616 /.$putCase consumeSingleTypeImportDeclarationName(); $break ./
5618 TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
5619 /.$putCase consumeTypeImportOnDemandDeclaration(); $break ./
5621 TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
5622 /.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
5624 TypeDeclaration -> ClassDeclaration
5625 TypeDeclaration -> InterfaceDeclaration
5626 -- this declaration in part of a list od declaration and we will
5627 -- use and optimized list length calculation process
5628 -- thus we decrement the number while it will be incremend.....
5629 TypeDeclaration ::= ';'
5630 /. $putCase consumeEmptyTypeDeclaration(); $break ./
5632 --18.7 Only in the LALR(1) Grammar
5634 Modifiers ::= Modifier
5635 Modifiers ::= Modifiers Modifier
5637 Modifier -> 'public'
5638 Modifier -> 'protected'
5639 Modifier -> 'private'
5640 Modifier -> 'static'
5641 Modifier -> 'abstract'
5643 Modifier -> 'native'
5644 Modifier -> 'synchronized'
5645 Modifier -> 'transient'
5646 Modifier -> 'volatile'
5647 Modifier -> 'strictfp'
5649 --18.8 Productions from 8: Class Declarations
5654 --18.8.1 Productions from 8.1: Class Declarations
5656 ClassDeclaration ::= ClassHeader ClassBody
5657 /.$putCase consumeClassDeclaration(); $break ./
5659 ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
5660 /.$putCase consumeClassHeader(); $break ./
5662 ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
5663 /.$putCase consumeClassHeaderName(); $break ./
5665 ClassHeaderExtends ::= 'extends' ClassType
5666 /.$putCase consumeClassHeaderExtends(); $break ./
5668 ClassHeaderImplements ::= 'implements' InterfaceTypeList
5669 /.$putCase consumeClassHeaderImplements(); $break ./
5671 InterfaceTypeList -> InterfaceType
5672 InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
5673 /.$putCase consumeInterfaceTypeList(); $break ./
5675 InterfaceType ::= ClassOrInterfaceType
5676 /.$putCase consumeInterfaceType(); $break ./
5678 ClassBody ::= '{' ClassBodyDeclarationsopt '}'
5680 ClassBodyDeclarations ::= ClassBodyDeclaration
5681 ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
5682 /.$putCase consumeClassBodyDeclarations(); $break ./
5684 ClassBodyDeclaration -> ClassMemberDeclaration
5685 ClassBodyDeclaration -> StaticInitializer
5686 ClassBodyDeclaration -> ConstructorDeclaration
5688 ClassBodyDeclaration ::= Diet NestedMethod Block
5689 /.$putCase consumeClassBodyDeclaration(); $break ./
5691 /.$putCase consumeDiet(); $break./
5693 Initializer ::= Diet NestedMethod Block
5694 /.$putCase consumeClassBodyDeclaration(); $break ./
5696 ClassMemberDeclaration -> FieldDeclaration
5697 ClassMemberDeclaration -> MethodDeclaration
5699 ClassMemberDeclaration -> ClassDeclaration
5701 ClassMemberDeclaration -> InterfaceDeclaration
5703 -- Empty declarations are not valid Java ClassMemberDeclarations.
5704 -- However, since the current (2/14/97) Java compiler accepts them
5705 -- (in fact, some of the official tests contain this erroneous
5708 GenericMethodDeclaration -> MethodDeclaration
5709 GenericMethodDeclaration -> ConstructorDeclaration
5711 ClassMemberDeclaration ::= ';'
5712 /.$putCase consumeEmptyClassMemberDeclaration(); $break./
5714 --18.8.2 Productions from 8.3: Field Declarations
5715 --VariableModifier ::=
5724 FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
5725 /.$putCase consumeFieldDeclaration(); $break ./
5727 VariableDeclarators -> VariableDeclarator
5728 VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
5729 /.$putCase consumeVariableDeclarators(); $break ./
5731 VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
5733 VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
5735 EnterVariable ::= $empty
5736 /.$putCase consumeEnterVariable(); $break ./
5738 ExitVariableWithInitialization ::= $empty
5739 /.$putCase consumeExitVariableWithInitialization(); $break ./
5741 ExitVariableWithoutInitialization ::= $empty
5742 /.$putCase consumeExitVariableWithoutInitialization(); $break ./
5744 ForceNoDiet ::= $empty
5745 /.$putCase consumeForceNoDiet(); $break ./
5746 RestoreDiet ::= $empty
5747 /.$putCase consumeRestoreDiet(); $break ./
5749 VariableDeclaratorId ::= 'Identifier' Dimsopt
5751 VariableInitializer -> Expression
5752 VariableInitializer -> ArrayInitializer
5754 --18.8.3 Productions from 8.4: Method Declarations
5755 --MethodModifier ::=
5766 MethodDeclaration -> AbstractMethodDeclaration
5767 MethodDeclaration ::= MethodHeader MethodBody
5768 /.$putCase // set to true to consume a method with a body
5769 consumeMethodDeclaration(true); $break ./
5771 AbstractMethodDeclaration ::= MethodHeader ';'
5772 /.$putCase // set to false to consume a method without body
5773 consumeMethodDeclaration(false); $break ./
5775 MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5776 /.$putCase consumeMethodHeader(); $break ./
5778 MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5779 /.$putCase consumeMethodHeader(); $break ./
5781 MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
5782 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5784 MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '('
5785 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5787 MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
5788 /.$putCase consumeMethodHeaderName(); $break ./
5790 MethodHeaderParameters ::= FormalParameterListopt ')'
5791 /.$putCase consumeMethodHeaderParameters(); $break ./
5793 MethodHeaderExtendedDims ::= Dimsopt
5794 /.$putCase consumeMethodHeaderExtendedDims(); $break ./
5796 MethodHeaderThrowsClause ::= 'throws' ClassTypeList
5797 /.$putCase consumeMethodHeaderThrowsClause(); $break ./
5799 ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
5800 /.$putCase consumeConstructorHeader(); $break ./
5802 ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
5803 /.$putCase consumeConstructorHeaderName(); $break ./
5805 FormalParameterList -> FormalParameter
5806 FormalParameterList ::= FormalParameterList ',' FormalParameter
5807 /.$putCase consumeFormalParameterList(); $break ./
5810 FormalParameter ::= Modifiersopt Type VariableDeclaratorId
5811 /.$putCase // the boolean is used to know if the modifiers should be reset
5812 consumeFormalParameter(); $break ./
5814 ClassTypeList -> ClassTypeElt
5815 ClassTypeList ::= ClassTypeList ',' ClassTypeElt
5816 /.$putCase consumeClassTypeList(); $break ./
5818 ClassTypeElt ::= ClassType
5819 /.$putCase consumeClassTypeElt(); $break ./
5822 MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
5823 /.$putCase consumeMethodBody(); $break ./
5825 NestedMethod ::= $empty
5826 /.$putCase consumeNestedMethod(); $break ./
5828 --18.8.4 Productions from 8.5: Static Initializers
5830 StaticInitializer ::= StaticOnly Block
5831 /.$putCase consumeStaticInitializer(); $break./
5833 StaticOnly ::= 'static'
5834 /.$putCase consumeStaticOnly(); $break ./
5836 --18.8.5 Productions from 8.6: Constructor Declarations
5837 --ConstructorModifier ::=
5843 ConstructorDeclaration ::= ConstructorHeader ConstructorBody
5844 /.$putCase consumeConstructorDeclaration() ; $break ./
5846 -- These rules are added to be able to parse constructors with no body
5847 ConstructorDeclaration ::= ConstructorHeader ';'
5848 /.$putCase consumeInvalidConstructorDeclaration() ; $break ./
5850 -- the rules ExplicitConstructorInvocationopt has been expanded
5851 -- in the rule below in order to make the grammar lalr(1).
5852 -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}'
5853 -- Other inlining has occured into the next rule too....
5855 ConstructorBody ::= NestedMethod '{' ConstructorBlockStatementsopt '}'
5856 /.$putCase consumeConstructorBody(); $break ./
5858 ConstructorBlockStatementsopt -> BlockStatementsopt
5860 ConstructorBlockStatementsopt -> ExplicitConstructorInvocation
5862 ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements
5863 /.$putCase consumeConstructorBlockStatements(); $break ./
5865 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
5866 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./
5868 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
5869 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./
5872 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
5873 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./
5876 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
5877 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./
5880 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
5881 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./
5884 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
5885 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./
5887 --18.9 Productions from 9: Interface Declarations
5889 --18.9.1 Productions from 9.1: Interface Declarations
5890 --InterfaceModifier ::=
5894 InterfaceDeclaration ::= InterfaceHeader InterfaceBody
5895 /.$putCase consumeInterfaceDeclaration(); $break ./
5897 InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
5898 /.$putCase consumeInterfaceHeader(); $break ./
5900 InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
5901 /.$putCase consumeInterfaceHeaderName(); $break ./
5903 -- This rule will be used to accept inner local interface and then report a relevant error message
5904 InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody
5906 InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
5907 /.$putCase consumeInterfaceHeaderExtends(); $break ./
5909 InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}'
5911 InterfaceMemberDeclarations -> InterfaceMemberDeclaration
5912 InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
5913 /.$putCase consumeInterfaceMemberDeclarations(); $break ./
5915 --same as for class members
5916 InterfaceMemberDeclaration ::= ';'
5917 /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./
5919 -- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message
5920 InvalidMethodDeclaration -> MethodHeader MethodBody
5922 InterfaceMemberDeclaration -> ConstantDeclaration
5923 InterfaceMemberDeclaration ::= InvalidMethodDeclaration
5924 /.$putCase ignoreMethodBody(); $break ./
5926 -- These rules are added to be able to parse constructors inside interface and then report a relevent error message
5927 InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody
5928 /.$putCase ignoreInvalidConstructorDeclaration(true); $break ./
5930 InvalidConstructorDeclaration ::= ConstructorHeader ';'
5931 /.$putCase ignoreInvalidConstructorDeclaration(false); $break ./
5933 InterfaceMemberDeclaration -> AbstractMethodDeclaration
5934 InterfaceMemberDeclaration -> InvalidConstructorDeclaration
5937 InterfaceMemberDeclaration -> ClassDeclaration
5939 InterfaceMemberDeclaration -> InterfaceDeclaration
5941 ConstantDeclaration -> FieldDeclaration
5943 ArrayInitializer ::= '{' ,opt '}'
5944 /.$putCase consumeEmptyArrayInitializer(); $break ./
5945 ArrayInitializer ::= '{' VariableInitializers '}'
5946 /.$putCase consumeArrayInitializer(); $break ./
5947 ArrayInitializer ::= '{' VariableInitializers , '}'
5948 /.$putCase consumeArrayInitializer(); $break ./
5950 VariableInitializers ::= VariableInitializer
5951 VariableInitializers ::= VariableInitializers ',' VariableInitializer
5952 /.$putCase consumeVariableInitializers(); $break ./
5954 Block ::= OpenBlock '{' BlockStatementsopt '}'
5955 /.$putCase consumeBlock(); $break ./
5956 OpenBlock ::= $empty
5957 /.$putCase consumeOpenBlock() ; $break ./
5959 BlockStatements -> BlockStatement
5960 BlockStatements ::= BlockStatements BlockStatement
5961 /.$putCase consumeBlockStatements() ; $break ./
5963 BlockStatement -> LocalVariableDeclarationStatement
5964 BlockStatement -> Statement
5966 BlockStatement -> ClassDeclaration
5967 BlockStatement ::= InvalidInterfaceDeclaration
5968 /.$putCase ignoreInterfaceDeclaration(); $break ./
5970 LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
5971 /.$putCase consumeLocalVariableDeclarationStatement(); $break ./
5973 LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
5974 /.$putCase consumeLocalVariableDeclaration(); $break ./
5977 -- The modifiers part of this rule makes the grammar more permissive.
5978 -- The only modifier here is final. We put Modifiers to allow multiple modifiers
5979 -- This will require to check the validity of the modifier
5981 LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators
5982 /.$putCase consumeLocalVariableDeclaration(); $break ./
5984 PushModifiers ::= $empty
5985 /.$putCase consumePushModifiers(); $break ./
5987 Statement -> StatementWithoutTrailingSubstatement
5988 Statement -> LabeledStatement
5989 Statement -> IfThenStatement
5990 Statement -> IfThenElseStatement
5991 Statement -> WhileStatement
5992 Statement -> ForStatement
5994 StatementNoShortIf -> StatementWithoutTrailingSubstatement
5995 StatementNoShortIf -> LabeledStatementNoShortIf
5996 StatementNoShortIf -> IfThenElseStatementNoShortIf
5997 StatementNoShortIf -> WhileStatementNoShortIf
5998 StatementNoShortIf -> ForStatementNoShortIf
6000 StatementWithoutTrailingSubstatement -> AssertStatement
6001 StatementWithoutTrailingSubstatement -> Block
6002 StatementWithoutTrailingSubstatement -> EmptyStatement
6003 StatementWithoutTrailingSubstatement -> ExpressionStatement
6004 StatementWithoutTrailingSubstatement -> SwitchStatement
6005 StatementWithoutTrailingSubstatement -> DoStatement
6006 StatementWithoutTrailingSubstatement -> BreakStatement
6007 StatementWithoutTrailingSubstatement -> ContinueStatement
6008 StatementWithoutTrailingSubstatement -> ReturnStatement
6009 StatementWithoutTrailingSubstatement -> SynchronizedStatement
6010 StatementWithoutTrailingSubstatement -> ThrowStatement
6011 StatementWithoutTrailingSubstatement -> TryStatement
6013 EmptyStatement ::= ';'
6014 /.$putCase consumeEmptyStatement(); $break ./
6016 LabeledStatement ::= 'Identifier' ':' Statement
6017 /.$putCase consumeStatementLabel() ; $break ./
6019 LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
6020 /.$putCase consumeStatementLabel() ; $break ./
6022 ExpressionStatement ::= StatementExpression ';'
6023 /. $putCase consumeExpressionStatement(); $break ./
6025 StatementExpression ::= Assignment
6026 StatementExpression ::= PreIncrementExpression
6027 StatementExpression ::= PreDecrementExpression
6028 StatementExpression ::= PostIncrementExpression
6029 StatementExpression ::= PostDecrementExpression
6030 StatementExpression ::= MethodInvocation
6031 StatementExpression ::= ClassInstanceCreationExpression
6033 IfThenStatement ::= 'if' '(' Expression ')' Statement
6034 /.$putCase consumeStatementIfNoElse(); $break ./
6036 IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
6037 /.$putCase consumeStatementIfWithElse(); $break ./
6039 IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
6040 /.$putCase consumeStatementIfWithElse(); $break ./
6042 SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
6043 /.$putCase consumeStatementSwitch() ; $break ./
6045 SwitchBlock ::= '{' '}'
6046 /.$putCase consumeEmptySwitchBlock() ; $break ./
6048 SwitchBlock ::= '{' SwitchBlockStatements '}'
6049 SwitchBlock ::= '{' SwitchLabels '}'
6050 SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
6051 /.$putCase consumeSwitchBlock() ; $break ./
6053 SwitchBlockStatements -> SwitchBlockStatement
6054 SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
6055 /.$putCase consumeSwitchBlockStatements() ; $break ./
6057 SwitchBlockStatement ::= SwitchLabels BlockStatements
6058 /.$putCase consumeSwitchBlockStatement() ; $break ./
6060 SwitchLabels -> SwitchLabel
6061 SwitchLabels ::= SwitchLabels SwitchLabel
6062 /.$putCase consumeSwitchLabels() ; $break ./
6064 SwitchLabel ::= 'case' ConstantExpression ':'
6065 /. $putCase consumeCaseLabel(); $break ./
6067 SwitchLabel ::= 'default' ':'
6068 /. $putCase consumeDefaultLabel(); $break ./
6070 WhileStatement ::= 'while' '(' Expression ')' Statement
6071 /.$putCase consumeStatementWhile() ; $break ./
6073 WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
6074 /.$putCase consumeStatementWhile() ; $break ./
6076 DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
6077 /.$putCase consumeStatementDo() ; $break ./
6079 ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
6080 /.$putCase consumeStatementFor() ; $break ./
6081 ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
6082 /.$putCase consumeStatementFor() ; $break ./
6084 --the minus one allows to avoid a stack-to-stack transfer
6085 ForInit ::= StatementExpressionList
6086 /.$putCase consumeForInit() ; $break ./
6087 ForInit -> LocalVariableDeclaration
6089 ForUpdate -> StatementExpressionList
6091 StatementExpressionList -> StatementExpression
6092 StatementExpressionList ::= StatementExpressionList ',' StatementExpression
6093 /.$putCase consumeStatementExpressionList() ; $break ./
6096 AssertStatement ::= 'assert' Expression ';'
6097 /.$putCase consumeSimpleAssertStatement() ; $break ./
6099 AssertStatement ::= 'assert' Expression ':' Expression ';'
6100 /.$putCase consumeAssertStatement() ; $break ./
6102 BreakStatement ::= 'break' ';'
6103 /.$putCase consumeStatementBreak() ; $break ./
6105 BreakStatement ::= 'break' Identifier ';'
6106 /.$putCase consumeStatementBreakWithLabel() ; $break ./
6108 ContinueStatement ::= 'continue' ';'
6109 /.$putCase consumeStatementContinue() ; $break ./
6111 ContinueStatement ::= 'continue' Identifier ';'
6112 /.$putCase consumeStatementContinueWithLabel() ; $break ./
6114 ReturnStatement ::= 'return' Expressionopt ';'
6115 /.$putCase consumeStatementReturn() ; $break ./
6117 ThrowStatement ::= 'throw' Expression ';'
6118 /.$putCase consumeStatementThrow();
6121 SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
6122 /.$putCase consumeStatementSynchronized(); $break ./
6123 OnlySynchronized ::= 'synchronized'
6124 /.$putCase consumeOnlySynchronized(); $break ./
6127 TryStatement ::= 'try' Block Catches
6128 /.$putCase consumeStatementTry(false); $break ./
6129 TryStatement ::= 'try' Block Catchesopt Finally
6130 /.$putCase consumeStatementTry(true); $break ./
6132 Catches -> CatchClause
6133 Catches ::= Catches CatchClause
6134 /.$putCase consumeCatches(); $break ./
6136 CatchClause ::= 'catch' '(' FormalParameter ')' Block
6137 /.$putCase consumeStatementCatch() ; $break ./
6139 Finally ::= 'finally' Block
6141 --18.12 Productions from 14: Expressions
6143 --for source positionning purpose
6145 /.$putCase consumeLeftParen(); $break ./
6147 /.$putCase consumeRightParen(); $break ./
6149 Primary -> PrimaryNoNewArray
6150 Primary -> ArrayCreationExpression
6152 PrimaryNoNewArray -> Literal
6153 PrimaryNoNewArray ::= 'this'
6154 /.$putCase consumePrimaryNoNewArrayThis(); $break ./
6156 PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN
6157 /.$putCase consumePrimaryNoNewArray(); $break ./
6159 PrimaryNoNewArray -> ClassInstanceCreationExpression
6160 PrimaryNoNewArray -> FieldAccess
6162 PrimaryNoNewArray ::= Name '.' 'this'
6163 /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
6164 PrimaryNoNewArray ::= Name '.' 'super'
6165 /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
6168 --PrimaryNoNewArray ::= Type '.' 'class'
6169 --inline Type in the previous rule in order to make the grammar LL1 instead
6170 -- of LL2. The result is the 3 next rules.
6171 PrimaryNoNewArray ::= Name '.' 'class'
6172 /.$putCase consumePrimaryNoNewArrayName(); $break ./
6174 PrimaryNoNewArray ::= ArrayType '.' 'class'
6175 /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
6177 PrimaryNoNewArray ::= PrimitiveType '.' 'class'
6178 /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
6180 PrimaryNoNewArray -> MethodInvocation
6181 PrimaryNoNewArray -> ArrayAccess
6185 -- In Java 1.0 a ClassBody could not appear at all in a
6186 -- ClassInstanceCreationExpression.
6189 AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
6190 /.$putCase consumeAllocationHeader(); $break ./
6192 ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
6193 /.$putCase consumeClassInstanceCreationExpression(); $break ./
6196 ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
6197 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
6200 ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
6201 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
6203 ClassInstanceCreationExpressionName ::= Name '.'
6204 /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
6206 ClassBodyopt ::= $empty --test made using null as contents
6207 /.$putCase consumeClassBodyopt(); $break ./
6208 ClassBodyopt ::= EnterAnonymousClassBody ClassBody
6210 EnterAnonymousClassBody ::= $empty
6211 /.$putCase consumeEnterAnonymousClassBody(); $break ./
6213 ArgumentList ::= Expression
6214 ArgumentList ::= ArgumentList ',' Expression
6215 /.$putCase consumeArgumentList(); $break ./
6217 --Thess rules are re-written in order to be ll1
6218 --ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer
6219 --ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt
6220 --ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt
6221 --DimExprs ::= DimExpr
6222 --DimExprs ::= DimExprs DimExpr
6224 ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
6225 /.$putCase consumeArrayCreationExpression(); $break ./
6226 ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
6227 /.$putCase consumeArrayCreationExpression(); $break ./
6229 DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
6230 DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
6231 /.$putCase consumeDimWithOrWithOutExprs(); $break ./
6233 DimWithOrWithOutExpr ::= '[' Expression ']'
6234 DimWithOrWithOutExpr ::= '[' ']'
6235 /. $putCase consumeDimWithOrWithOutExpr(); $break ./
6236 -- -----------------------------------------------
6239 /. $putCase consumeDims(); $break ./
6240 DimsLoop -> OneDimLoop
6241 DimsLoop ::= DimsLoop OneDimLoop
6242 OneDimLoop ::= '[' ']'
6243 /. $putCase consumeOneDimLoop(); $break ./
6245 FieldAccess ::= Primary '.' 'Identifier'
6246 /.$putCase consumeFieldAccess(false); $break ./
6248 FieldAccess ::= 'super' '.' 'Identifier'
6249 /.$putCase consumeFieldAccess(true); $break ./
6251 MethodInvocation ::= Name '(' ArgumentListopt ')'
6252 /.$putCase consumeMethodInvocationName(); $break ./
6254 MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
6255 /.$putCase consumeMethodInvocationPrimary(); $break ./
6257 MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
6258 /.$putCase consumeMethodInvocationSuper(); $break ./
6260 ArrayAccess ::= Name '[' Expression ']'
6261 /.$putCase consumeArrayAccess(true); $break ./
6262 ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
6263 /.$putCase consumeArrayAccess(false); $break ./
6265 PostfixExpression -> Primary
6266 PostfixExpression ::= Name
6267 /.$putCase consumePostfixExpression(); $break ./
6268 PostfixExpression -> PostIncrementExpression
6269 PostfixExpression -> PostDecrementExpression
6271 PostIncrementExpression ::= PostfixExpression '++'
6272 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./
6274 PostDecrementExpression ::= PostfixExpression '--'
6275 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./
6277 --for source managment purpose
6278 PushPosition ::= $empty
6279 /.$putCase consumePushPosition(); $break ./
6281 UnaryExpression -> PreIncrementExpression
6282 UnaryExpression -> PreDecrementExpression
6283 UnaryExpression ::= '+' PushPosition UnaryExpression
6284 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./
6285 UnaryExpression ::= '-' PushPosition UnaryExpression
6286 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./
6287 UnaryExpression -> UnaryExpressionNotPlusMinus
6289 PreIncrementExpression ::= '++' PushPosition UnaryExpression
6290 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./
6292 PreDecrementExpression ::= '--' PushPosition UnaryExpression
6293 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./
6295 UnaryExpressionNotPlusMinus -> PostfixExpression
6296 UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
6297 /.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./
6298 UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
6299 /.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./
6300 UnaryExpressionNotPlusMinus -> CastExpression
6302 CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
6303 /.$putCase consumeCastExpression(); $break ./
6304 CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
6305 /.$putCase consumeCastExpression(); $break ./
6306 -- Expression is here only in order to make the grammar LL1
6307 CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus
6308 /.$putCase consumeCastExpressionLL1(); $break ./
6310 MultiplicativeExpression -> UnaryExpression
6311 MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
6312 /.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./
6313 MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
6314 /.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./
6315 MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
6316 /.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./
6318 AdditiveExpression -> MultiplicativeExpression
6319 AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
6320 /.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./
6321 AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
6322 /.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./
6324 ShiftExpression -> AdditiveExpression
6325 ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
6326 /.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./
6327 ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
6328 /.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./
6329 ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
6330 /.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./
6332 RelationalExpression -> ShiftExpression
6333 RelationalExpression ::= RelationalExpression '<' ShiftExpression
6334 /.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./
6335 RelationalExpression ::= RelationalExpression '>' ShiftExpression
6336 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./
6337 RelationalExpression ::= RelationalExpression '<=' ShiftExpression
6338 /.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./
6339 RelationalExpression ::= RelationalExpression '>=' ShiftExpression
6340 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./
6341 RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
6342 /.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./
6344 EqualityExpression -> RelationalExpression
6345 EqualityExpression ::= EqualityExpression '==' RelationalExpression
6346 /.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./
6347 EqualityExpression ::= EqualityExpression '!=' RelationalExpression
6348 /.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./
6350 AndExpression -> EqualityExpression
6351 AndExpression ::= AndExpression '&' EqualityExpression
6352 /.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./
6354 ExclusiveOrExpression -> AndExpression
6355 ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
6356 /.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./
6358 InclusiveOrExpression -> ExclusiveOrExpression
6359 InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
6360 /.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./
6362 ConditionalAndExpression -> InclusiveOrExpression
6363 ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
6364 /.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./
6366 ConditionalOrExpression -> ConditionalAndExpression
6367 ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
6368 /.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./
6370 ConditionalExpression -> ConditionalOrExpression
6371 ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
6372 /.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./
6374 AssignmentExpression -> ConditionalExpression
6375 AssignmentExpression -> Assignment
6377 Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
6378 /.$putCase consumeAssignment(); $break ./
6380 -- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
6381 InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer
6382 Assignment ::= InvalidArrayInitializerAssignement
6383 /.$putcase ignoreExpressionAssignment();$break ./
6385 LeftHandSide ::= Name
6386 /.$putCase consumeLeftHandSide(); $break ./
6387 LeftHandSide -> FieldAccess
6388 LeftHandSide -> ArrayAccess
6390 AssignmentOperator ::= '='
6391 /.$putCase consumeAssignmentOperator(EQUAL); $break ./
6392 AssignmentOperator ::= '*='
6393 /.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
6394 AssignmentOperator ::= '/='
6395 /.$putCase consumeAssignmentOperator(DIVIDE); $break ./
6396 AssignmentOperator ::= '%='
6397 /.$putCase consumeAssignmentOperator(REMAINDER); $break ./
6398 AssignmentOperator ::= '+='
6399 /.$putCase consumeAssignmentOperator(PLUS); $break ./
6400 AssignmentOperator ::= '-='
6401 /.$putCase consumeAssignmentOperator(MINUS); $break ./
6402 AssignmentOperator ::= '<<='
6403 /.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
6404 AssignmentOperator ::= '>>='
6405 /.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
6406 AssignmentOperator ::= '>>>='
6407 /.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
6408 AssignmentOperator ::= '&='
6409 /.$putCase consumeAssignmentOperator(AND); $break ./
6410 AssignmentOperator ::= '^='
6411 /.$putCase consumeAssignmentOperator(XOR); $break ./
6412 AssignmentOperator ::= '|='
6413 /.$putCase consumeAssignmentOperator(OR); $break ./
6415 Expression -> AssignmentExpression
6417 ConstantExpression -> Expression
6419 -- The following rules are for optional nonterminals.
6422 PackageDeclarationopt -> $empty
6423 PackageDeclarationopt -> PackageDeclaration
6425 ClassHeaderExtendsopt ::= $empty
6426 ClassHeaderExtendsopt -> ClassHeaderExtends
6428 Expressionopt ::= $empty
6429 /.$putCase consumeEmptyExpression(); $break ./
6430 Expressionopt -> Expression
6433 ---------------------------------------------------------------------------------------
6435 -- The rules below are for optional terminal symbols. An optional comma,
6436 -- is only used in the context of an array initializer - It is a
6437 -- "syntactic sugar" that otherwise serves no other purpose. By contrast,
6438 -- an optional identifier is used in the definition of a break and
6439 -- continue statement. When the identifier does not appear, a NULL
6440 -- is produced. When the identifier is present, the user should use the
6441 -- corresponding TOKEN(i) method. See break statement as an example.
6443 ---------------------------------------------------------------------------------------
6448 ImportDeclarationsopt ::= $empty
6449 /.$putCase consumeEmptyImportDeclarationsopt(); $break ./
6450 ImportDeclarationsopt ::= ImportDeclarations
6451 /.$putCase consumeImportDeclarationsopt(); $break ./
6454 TypeDeclarationsopt ::= $empty
6455 /.$putCase consumeEmptyTypeDeclarationsopt(); $break ./
6456 TypeDeclarationsopt ::= TypeDeclarations
6457 /.$putCase consumeTypeDeclarationsopt(); $break ./
6459 ClassBodyDeclarationsopt ::= $empty
6460 /.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
6461 ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
6462 /.$putCase consumeClassBodyDeclarationsopt(); $break ./
6464 Modifiersopt ::= $empty
6465 /. $putCase consumeDefaultModifiers(); $break ./
6466 Modifiersopt ::= Modifiers
6467 /.$putCase consumeModifiers(); $break ./
6469 BlockStatementsopt ::= $empty
6470 /.$putCase consumeEmptyBlockStatementsopt(); $break ./
6471 BlockStatementsopt -> BlockStatements
6474 /. $putCase consumeEmptyDimsopt(); $break ./
6477 ArgumentListopt ::= $empty
6478 /. $putCase consumeEmptyArgumentListopt(); $break ./
6479 ArgumentListopt -> ArgumentList
6481 MethodHeaderThrowsClauseopt ::= $empty
6482 MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
6484 FormalParameterListopt ::= $empty
6485 /.$putcase consumeFormalParameterListopt(); $break ./
6486 FormalParameterListopt -> FormalParameterList
6488 ClassHeaderImplementsopt ::= $empty
6489 ClassHeaderImplementsopt -> ClassHeaderImplements
6491 InterfaceMemberDeclarationsopt ::= $empty
6492 /. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
6493 InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
6494 /. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
6496 NestedType ::= $empty
6497 /.$putCase consumeNestedType(); $break./
6499 ForInitopt ::= $empty
6500 /. $putCase consumeEmptyForInitopt(); $break ./
6501 ForInitopt -> ForInit
6503 ForUpdateopt ::= $empty
6504 /. $putCase consumeEmptyForUpdateopt(); $break ./
6505 ForUpdateopt -> ForUpdate
6507 InterfaceHeaderExtendsopt ::= $empty
6508 InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
6510 Catchesopt ::= $empty
6511 /. $putCase consumeEmptyCatchesopt(); $break ./
6512 Catchesopt -> Catches
6514 ArrayInitializeropt ::= $empty
6515 /. $putCase consumeEmptyArrayInitializeropt(); $break ./
6516 ArrayInitializeropt -> ArrayInitializer
6521 ---------------------------------------------------------------------------------------
6525 -- BodyMarker ::= '"class Identifier { ... MethodHeader "'
6530 MINUS_MINUS ::= '--'
6531 EQUAL_EQUAL ::= '=='
6533 GREATER_EQUAL ::= '>='
6536 RIGHT_SHIFT ::= '>>'
6537 UNSIGNED_RIGHT_SHIFT ::= '>>>'
6539 MINUS_EQUAL ::= '-='
6540 MULTIPLY_EQUAL ::= '*='
6541 DIVIDE_EQUAL ::= '/='
6545 REMAINDER_EQUAL ::= '%='
6546 LEFT_SHIFT_EQUAL ::= '<<='
6547 RIGHT_SHIFT_EQUAL ::= '>>='
6548 UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>='
6578 -- need a carriage return after the $end
6581 protected void ignoreExpressionAssignment() {
6582 // Assignment ::= InvalidArrayInitializerAssignement
6583 // encoded operator would be: intStack[intPtr]
6585 ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--];
6586 expressionLengthPtr--;
6587 // report a syntax error and abort parsing
6588 problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
6590 protected void ignoreInterfaceDeclaration() {
6591 // BlockStatement ::= InvalidInterfaceDeclaration
6592 //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
6594 // length declarations
6596 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6597 //there are length declarations
6598 //dispatch according to the type of the declarations
6599 dispatchDeclarationInto(length);
6602 flushAnnotationsDefinedPriorTo(endStatementPosition);
6604 // report the problem and continue parsing
6605 TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
6606 typeDecl.bodyEnd = endStatementPosition;
6607 problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
6609 // mark fields and initializer with local type mark if needed
6610 markFieldsWithLocalType(typeDecl);
6612 // remove the ast node created in interface header
6614 // Don't create an astnode for this inner interface, but have to push
6615 // a 0 on the astLengthStack to be consistent with the reduction made
6616 // at the end of the method:
6617 // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit)
6618 pushOnAstLengthStack(0);
6620 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
6621 // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
6622 // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
6625 astStack : modifiers arguments throws statements
6626 identifierStack : name
6628 astStack : MethodDeclaration
6632 //must provide a default constructor call when needed
6635 // pop the position of the { (body of the method) pushed in block decl
6645 if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) {
6649 protected void ignoreMethodBody() {
6650 // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
6653 astStack : modifiers arguments throws statements
6654 identifierStack : type name
6655 intStack : dim dim dim
6657 astStack : MethodDeclaration
6662 // pop the position of the { (body of the method) pushed in block decl
6664 // retrieve end position of method declarator
6669 if ((length = astLengthStack[astLengthPtr--]) != 0) {
6673 //watch for } that could be given as a unicode ! ( u007D is '}' )
6674 MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
6675 md.bodyEnd = endPosition;
6676 md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
6678 // report the problem and continue the parsing - narrowing the problem onto the method
6679 problemReporter().abstractMethodNeedingNoBody(md);
6681 public void initialize() {
6682 //positionning the parser for a new compilation unit
6683 //avoiding stack reallocation and all that....
6687 expressionLengthPtr = -1;
6689 identifierLengthPtr = -1;
6691 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
6692 variablesCounter[nestedType] = 0;
6695 compilationUnit = null;
6696 referenceContext = null;
6697 endStatementPosition = 0;
6699 //remove objects from stack too, while the same parser/compiler couple is
6700 //re-used between two compilations ....
6702 int astLength = astStack.length;
6703 if (noAstNodes.length < astLength) {
6704 noAstNodes = new AstNode[astLength];
6705 //System.out.println("Resized AST stacks : "+ astLength);
6708 System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
6710 int expressionLength = expressionStack.length;
6711 if (noExpressions.length < expressionLength) {
6712 noExpressions = new Expression[expressionLength];
6713 //System.out.println("Resized EXPR stacks : "+ expressionLength);
6715 System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
6717 // reset scanner state
6718 scanner.commentPtr = -1;
6719 scanner.eofPosition = Integer.MAX_VALUE;
6724 lastCheckPoint = -1;
6725 currentElement = null;
6726 restartRecovery = false;
6727 hasReportedError = false;
6728 recoveredStaticInitializerStart = 0;
6729 lastIgnoredToken = -1;
6730 lastErrorEndPosition = -1;
6733 public void initializeScanner() {
6738 this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore,
6741 public final static void initTables() throws java.io.IOException {
6743 final String prefix = FILEPREFIX;
6745 lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6746 char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6747 check_table = new short[chars.length];
6748 for (int c = chars.length; c-- > 0;) {
6749 check_table[c] = (short) (chars[c] - 32768);
6751 asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6752 asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6753 symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6756 public final void jumpOverMethodBody() {
6757 //on diet parsing.....do not buffer method statements
6759 //the scanner.diet is reinitialized to false
6760 //automatically by the scanner once it has jumped over
6763 if (diet && (dietInt == 0))
6764 scanner.diet = true;
6766 protected void markCurrentMethodWithLocalType() {
6767 if (this.currentElement != null)
6768 return; // this is already done in the recovery code
6769 for (int i = this.astPtr; i >= 0; i--) {
6770 AstNode node = this.astStack[i];
6771 if (node instanceof AbstractMethodDeclaration
6772 || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type
6773 node.bits |= AstNode.HasLocalTypeMASK;
6777 // default to reference context (case of parse method body)
6778 if (this.referenceContext instanceof AbstractMethodDeclaration || this.referenceContext instanceof TypeDeclaration) {
6779 ((AstNode) this.referenceContext).bits |= AstNode.HasLocalTypeMASK;
6782 protected void markFieldsWithLocalType(TypeDeclaration type) {
6783 if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0)
6785 for (int i = 0, length = type.fields.length; i < length; i++) {
6786 type.fields[i].bits |= AstNode.HasLocalTypeMASK;
6790 * Move checkpoint location (current implementation is moving it by one token)
6792 * Answers true if successfully moved checkpoint (i.e. did not attempt to move it
6793 * beyond end of file).
6795 protected boolean moveRecoveryCheckpoint() {
6797 int pos = lastCheckPoint;
6798 /* reset scanner, and move checkpoint by one token */
6799 scanner.startPosition = pos;
6800 scanner.currentPosition = pos;
6801 scanner.diet = false; // quit jumping over method bodies
6803 /* if about to restart, then no need to shift token */
6804 if (restartRecovery) {
6805 lastIgnoredToken = -1;
6809 /* protect against shifting on an invalid token */
6810 lastIgnoredToken = nextIgnoredToken;
6811 nextIgnoredToken = -1;
6814 nextIgnoredToken = scanner.getNextToken();
6815 if (scanner.currentPosition == scanner.startPosition) {
6816 scanner.currentPosition++; // on fake completion identifier
6817 nextIgnoredToken = -1;
6820 } catch (InvalidInputException e) {
6821 pos = scanner.currentPosition;
6823 } while (nextIgnoredToken < 0);
6825 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6826 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6830 lastCheckPoint = scanner.currentPosition;
6832 /* reset scanner again to previous checkpoint location*/
6833 scanner.startPosition = pos;
6834 scanner.currentPosition = pos;
6835 scanner.commentPtr = -1;
6840 The following implementation moves the checkpoint location by one line:
6842 int pos = lastCheckPoint;
6843 // reset scanner, and move checkpoint by one token
6844 scanner.startPosition = pos;
6845 scanner.currentPosition = pos;
6846 scanner.diet = false; // quit jumping over method bodies
6848 // if about to restart, then no need to shift token
6849 if (restartRecovery){
6850 lastIgnoredToken = -1;
6854 // protect against shifting on an invalid token
6855 lastIgnoredToken = nextIgnoredToken;
6856 nextIgnoredToken = -1;
6858 boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace;
6859 scanner.tokenizeWhiteSpace = true;
6863 nextIgnoredToken = scanner.getNextToken();
6864 switch(nextIgnoredToken){
6865 case Scanner.TokenNameWHITESPACE :
6866 if(scanner.getLineNumber(scanner.startPosition)
6867 == scanner.getLineNumber(scanner.currentPosition)){
6868 nextIgnoredToken = -1;
6871 case TokenNameSEMICOLON :
6872 case TokenNameLBRACE :
6873 case TokenNameRBRACE :
6875 case TokenNameIdentifier :
6876 if(scanner.currentPosition == scanner.startPosition){
6877 scanner.currentPosition++; // on fake completion identifier
6880 nextIgnoredToken = -1;
6883 break checkpointMove;
6885 } catch(InvalidInputException e){
6886 pos = scanner.currentPosition;
6888 } while (nextIgnoredToken < 0);
6889 scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
6891 if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6892 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6896 lastCheckPoint = scanner.currentPosition;
6898 // reset scanner again to previous checkpoint location
6899 scanner.startPosition = pos;
6900 scanner.currentPosition = pos;
6901 scanner.commentPtr = -1;
6906 protected MessageSend newMessageSend() {
6907 // '(' ArgumentListopt ')'
6908 // the arguments are on the expression stack
6910 MessageSend m = new MessageSend();
6912 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
6913 expressionPtr -= length;
6914 System.arraycopy(expressionStack, expressionPtr + 1, m.arguments = new Expression[length], 0, length);
6918 protected static int ntAction(int state, int sym) {
6919 return action[state + sym];
6921 private final void optimizedConcatNodeLists() {
6922 /*back from a recursive loop. Virtualy group the
6923 astNode into an array using astLengthStack*/
6926 * This is a case where you have two sublists into the astStack that you want
6927 * to merge in one list. There is no action required on the astStack. The only
6928 * thing you need to do is merge the two lengths specified on the astStackLength.
6929 * The top two length are for example:
6931 * and you want to result in a list like:
6933 * This means that the p could be equals to 0 in case there is no astNode pushed
6935 * Look at the InterfaceMemberDeclarations for an example.
6936 * This case optimizes the fact that p == 1.
6939 astLengthStack[--astLengthPtr]++;
6941 protected static int original_state(int state) {
6942 return -check(state);
6944 /*main loop of the automat
6945 When a rule is reduced, the method consumeRule(int) is called with the number
6946 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
6947 called in order to remember (when needed) the consumed token */
6948 // (int)asr[asi(act)]
6949 // name[symbol_index[currentKind]]
6950 protected void parse() {
6952 hasReportedError = false;
6953 int act = START_STATE;
6955 currentToken = getFirstToken();
6956 ProcessTerminals : for (;;) {
6958 stack[++stateStackTop] = act;
6959 } catch (IndexOutOfBoundsException e) {
6960 int oldStackLength = stack.length;
6961 int oldStack[] = stack;
6962 stack = new int[oldStackLength + StackIncrement];
6963 System.arraycopy(oldStack, 0, stack, 0, oldStackLength);
6964 stack[stateStackTop] = act;
6967 act = tAction(act, currentToken);
6969 if (act == ERROR_ACTION || restartRecovery) {
6970 int errorPos = scanner.currentPosition;
6971 if (!hasReportedError) {
6972 this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop);
6973 hasReportedError = true;
6975 if (resumeOnSyntaxError()) {
6976 if (act == ERROR_ACTION)
6977 lastErrorEndPosition = errorPos;
6980 currentToken = getFirstToken();
6981 continue ProcessTerminals;
6985 break ProcessTerminals;
6987 if (act <= NUM_RULES)
6989 else if (act > ERROR_ACTION) { /* shift-reduce */
6990 consumeToken(currentToken);
6991 if (currentElement != null)
6992 this.recoveryTokenCheck();
6994 currentToken = scanner.getNextToken();
6995 } catch (InvalidInputException e) {
6996 if (!hasReportedError) {
6997 this.problemReporter().scannerError(this, e.getMessage());
6998 hasReportedError = true;
7000 lastCheckPoint = scanner.currentPosition;
7001 restartRecovery = true;
7003 act -= ERROR_ACTION;
7004 } else if (act < ACCEPT_ACTION) { /* shift */
7005 consumeToken(currentToken);
7006 if (currentElement != null)
7007 this.recoveryTokenCheck();
7009 currentToken = scanner.getNextToken();
7010 } catch (InvalidInputException e) {
7011 if (!hasReportedError) {
7012 this.problemReporter().scannerError(this, e.getMessage());
7013 hasReportedError = true;
7015 lastCheckPoint = scanner.currentPosition;
7016 restartRecovery = true;
7018 continue ProcessTerminals;
7020 break ProcessTerminals;
7022 ProcessNonTerminals : do { /* reduce */
7024 stateStackTop -= (rhs[act] - 1);
7025 act = ntAction(stack[stateStackTop], lhs[act]);
7026 } while (act <= NUM_RULES);
7032 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
7033 //only parse the method body of cd
7034 //fill out its statements
7036 //convert bugs into parse error
7039 goForConstructorBody();
7040 nestedMethod[nestedType]++;
7042 referenceContext = cd;
7043 compilationUnit = unit;
7045 scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
7048 } catch (AbortCompilation ex) {
7049 lastAct = ERROR_ACTION;
7051 nestedMethod[nestedType]--;
7054 if (lastAct == ERROR_ACTION) {
7060 cd.explicitDeclarations = realBlockStack[realBlockPtr--];
7062 if ((length = astLengthStack[astLengthPtr--]) != 0) {
7064 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
7065 //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
7067 System.arraycopy(astStack, astPtr + 2, cd.statements = new Statement[length - 1], 0, length - 1);
7068 cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
7069 } else { //need to add explicitly the super();
7070 System.arraycopy(astStack, astPtr + 1, cd.statements = new Statement[length], 0, length);
7071 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
7074 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
7077 if (cd.constructorCall.sourceEnd == 0) {
7078 cd.constructorCall.sourceEnd = cd.sourceEnd;
7079 cd.constructorCall.sourceStart = cd.sourceStart;
7084 public void parse(Initializer ini, TypeDeclaration type, CompilationUnitDeclaration unit) {
7085 //only parse the method body of md
7086 //fill out method statements
7088 //convert bugs into parse error
7092 nestedMethod[nestedType]++;
7094 referenceContext = type;
7095 compilationUnit = unit;
7097 scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
7100 } catch (AbortCompilation ex) {
7101 lastAct = ERROR_ACTION;
7103 nestedMethod[nestedType]--;
7106 if (lastAct == ERROR_ACTION) {
7110 ini.block = ((Initializer) astStack[astPtr]).block;
7112 // mark initializer with local type if one was found during parsing
7113 if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
7114 ini.bits |= AstNode.HasLocalTypeMASK;
7119 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
7120 //only parse the method body of md
7121 //fill out method statements
7123 //convert bugs into parse error
7125 if (md.isAbstract())
7129 if ((md.modifiers & AccSemicolonBody) != 0)
7134 nestedMethod[nestedType]++;
7136 referenceContext = md;
7137 compilationUnit = unit;
7139 scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd);
7140 // reset the scanner to parser from { down to }
7143 } catch (AbortCompilation ex) {
7144 lastAct = ERROR_ACTION;
7146 nestedMethod[nestedType]--;
7149 if (lastAct == ERROR_ACTION) {
7154 md.explicitDeclarations = realBlockStack[realBlockPtr--];
7156 if ((length = astLengthStack[astLengthPtr--]) != 0)
7157 System.arraycopy(astStack, (astPtr -= length) + 1, md.statements = new Statement[length], 0, length);
7161 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
7162 // parses a compilation unit and manages error handling (even bugs....)
7164 CompilationUnitDeclaration unit;
7166 /* automaton initialization */
7168 goForCompilationUnit();
7170 /* scanner initialization */
7171 scanner.setSource(sourceUnit.getContents());
7175 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
7179 unit = compilationUnit;
7180 compilationUnit = null; // reset parser
7186 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
7187 // parses a compilation unit and manages error handling (even bugs....)
7189 CompilationUnitDeclaration unit;
7191 /* automaton initialization */
7193 goForCompilationUnit();
7195 /* scanner initialization */
7196 scanner.setSource(sourceUnit.getContents());
7197 scanner.resetTo(start, end);
7200 compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, scanner.source.length);
7204 unit = compilationUnit;
7205 compilationUnit = null; // reset parser
7210 * Returns this parser's problem reporter initialized with its reference context.
7211 * Also it is assumed that a problem is going to be reported, so initializes
7212 * the compilation result's line positions.
7214 public ProblemReporter problemReporter() {
7215 if (scanner.recordLineSeparator) {
7216 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
7218 problemReporter.referenceContext = referenceContext;
7219 return problemReporter;
7221 protected void pushIdentifier() {
7222 /*push the consumeToken on the identifier stack.
7223 Increase the total number of identifier in the stack.
7224 identifierPtr points on the next top */
7227 identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource();
7228 identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7229 } catch (IndexOutOfBoundsException e) {
7230 /*---stack reallaocation (identifierPtr is correct)---*/
7231 int oldStackLength = identifierStack.length;
7232 char[][] oldStack = identifierStack;
7233 identifierStack = new char[oldStackLength + 20][];
7234 System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength);
7235 identifierStack[identifierPtr] = scanner.getCurrentTokenSource();
7236 /*identifier position stack*/
7237 long[] oldPos = identifierPositionStack;
7238 identifierPositionStack = new long[oldStackLength + 20];
7239 System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength);
7240 identifierPositionStack[identifierPtr] = (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1);
7244 identifierLengthStack[++identifierLengthPtr] = 1;
7245 } catch (IndexOutOfBoundsException e) {
7246 /*---stack reallocation (identifierLengthPtr is correct)---*/
7247 int oldStackLength = identifierLengthStack.length;
7248 int oldStack[] = identifierLengthStack;
7249 identifierLengthStack = new int[oldStackLength + 10];
7250 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7251 identifierLengthStack[identifierLengthPtr] = 1;
7255 protected void pushIdentifier(int flag) {
7256 /*push a special flag on the stack :
7257 -zero stands for optional Name
7258 -negative number for direct ref to base types.
7259 identifierLengthPtr points on the top */
7262 identifierLengthStack[++identifierLengthPtr] = flag;
7263 } catch (IndexOutOfBoundsException e) {
7264 /*---stack reallaocation (identifierLengthPtr is correct)---*/
7265 int oldStackLength = identifierLengthStack.length;
7266 int oldStack[] = identifierLengthStack;
7267 identifierLengthStack = new int[oldStackLength + 10];
7268 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7269 identifierLengthStack[identifierLengthPtr] = flag;
7273 protected void pushOnAstLengthStack(int pos) {
7275 astLengthStack[++astLengthPtr] = pos;
7276 } catch (IndexOutOfBoundsException e) {
7277 int oldStackLength = astLengthStack.length;
7278 int[] oldPos = astLengthStack;
7279 astLengthStack = new int[oldStackLength + StackIncrement];
7280 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7281 astLengthStack[astLengthPtr] = pos;
7284 protected void pushOnAstStack(AstNode node) {
7285 /*add a new obj on top of the ast stack
7286 astPtr points on the top*/
7289 astStack[++astPtr] = node;
7290 } catch (IndexOutOfBoundsException e) {
7291 int oldStackLength = astStack.length;
7292 AstNode[] oldStack = astStack;
7293 astStack = new AstNode[oldStackLength + AstStackIncrement];
7294 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
7295 astPtr = oldStackLength;
7296 astStack[astPtr] = node;
7300 astLengthStack[++astLengthPtr] = 1;
7301 } catch (IndexOutOfBoundsException e) {
7302 int oldStackLength = astLengthStack.length;
7303 int[] oldPos = astLengthStack;
7304 astLengthStack = new int[oldStackLength + AstStackIncrement];
7305 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7306 astLengthStack[astLengthPtr] = 1;
7309 protected void pushOnExpressionStack(Expression expr) {
7312 expressionStack[++expressionPtr] = expr;
7313 } catch (IndexOutOfBoundsException e) {
7314 //expressionPtr is correct
7315 int oldStackLength = expressionStack.length;
7316 Expression[] oldStack = expressionStack;
7317 expressionStack = new Expression[oldStackLength + ExpressionStackIncrement];
7318 System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength);
7319 expressionStack[expressionPtr] = expr;
7323 expressionLengthStack[++expressionLengthPtr] = 1;
7324 } catch (IndexOutOfBoundsException e) {
7325 int oldStackLength = expressionLengthStack.length;
7326 int[] oldPos = expressionLengthStack;
7327 expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement];
7328 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7329 expressionLengthStack[expressionLengthPtr] = 1;
7332 protected void pushOnExpressionStackLengthStack(int pos) {
7334 expressionLengthStack[++expressionLengthPtr] = pos;
7335 } catch (IndexOutOfBoundsException e) {
7336 int oldStackLength = expressionLengthStack.length;
7337 int[] oldPos = expressionLengthStack;
7338 expressionLengthStack = new int[oldStackLength + StackIncrement];
7339 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7340 expressionLengthStack[expressionLengthPtr] = pos;
7343 protected void pushOnIntStack(int pos) {
7346 intStack[++intPtr] = pos;
7347 } catch (IndexOutOfBoundsException e) {
7349 int oldStackLength = intStack.length;
7350 int oldStack[] = intStack;
7351 intStack = new int[oldStackLength + StackIncrement];
7352 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
7353 intStack[intPtr] = pos;
7356 protected static char[] readTable(String filename) throws java.io.IOException {
7358 //files are located at Parser.class directory
7360 InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename));
7361 if (stream == null) {
7362 throw new java.io.IOException(Util.bind("parser.missingFile", filename)); //$NON-NLS-1$
7364 byte[] bytes = null;
7366 bytes = Util.getInputStreamAsByteArray(stream, -1);
7370 } catch (IOException e) {
7374 //minimal integrity check (even size expected)
7375 int length = bytes.length;
7376 if (length % 2 != 0)
7377 throw new java.io.IOException(Util.bind("parser.corruptedFile", filename)); //$NON-NLS-1$
7379 // convert bytes into chars
7380 char[] chars = new char[length / 2];
7385 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
7391 /* Token check performed on every token shift once having entered
7394 public void recoveryTokenCheck() {
7395 switch (currentToken) {
7396 case TokenNameLBRACE :
7398 RecoveredElement newElement = currentElement.updateOnOpeningBrace(scanner.currentPosition - 1);
7399 lastCheckPoint = scanner.currentPosition;
7400 if (newElement != null) { // null means nothing happened
7401 restartRecovery = true; // opening brace detected
7402 currentElement = newElement;
7406 case TokenNameRBRACE :
7408 endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1);
7409 RecoveredElement newElement = currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition - 1);
7410 lastCheckPoint = scanner.currentPosition;
7411 if (newElement != currentElement) {
7412 currentElement = newElement;
7417 protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
7419 /* remember current scanner position */
7420 int startPos = scanner.startPosition;
7421 int currentPos = scanner.currentPosition;
7423 String[] expectings;
7424 String tokenName = name[symbol_index[currentKind]];
7426 //fetch all "accurate" possible terminals that could recover the error
7427 int start, end = start = asi(stack[stateStackTop]);
7428 while (asr[end] != 0)
7430 int length = end - start;
7431 expectings = new String[length];
7433 char[] indexes = new char[length];
7434 System.arraycopy(asr, start, indexes, 0, length);
7435 for (int i = 0; i < length; i++) {
7436 expectings[i] = name[symbol_index[indexes[i]]];
7440 //if the pb is an EOF, try to tell the user that they are some
7441 if (tokenName.equals(UNEXPECTED_EOF)) {
7442 if (!this.checkAndReportBracketAnomalies(problemReporter())) {
7445 tokenSource = this.scanner.getCurrentTokenSource();
7446 } catch (Exception e) {
7447 tokenSource = new char[] {
7450 problemReporter().parseError(
7451 this.scanner.startPosition,
7452 this.scanner.currentPosition - 1,
7457 } else { //the next test is HEAVILY grammar DEPENDENT.
7458 if ((length == 2) && (tokenName.equals(";")) //$NON-NLS-1$
7459 && (expectings[0] == "++") //$NON-NLS-1$
7460 && (expectings[1] == "--") //$NON-NLS-1$
7461 && (expressionPtr > -1)) {
7462 // the ; is not the expected token ==> it ends a statement when an expression is not ended
7463 problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
7467 tokenSource = this.scanner.getCurrentTokenSource();
7468 } catch (Exception e) {
7469 tokenSource = new char[] {
7472 problemReporter().parseError(
7473 this.scanner.startPosition,
7474 this.scanner.currentPosition - 1,
7478 this.checkAndReportBracketAnomalies(problemReporter());
7481 /* reset scanner where it was */
7482 scanner.startPosition = startPos;
7483 scanner.currentPosition = currentPos;
7485 protected void resetModifiers() {
7486 modifiers = AccDefault;
7487 modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
7488 scanner.commentPtr = -1;
7491 * Reset context so as to resume to regular parse loop
7493 protected void resetStacks() {
7498 expressionLengthPtr = -1;
7500 identifierLengthPtr = -1;
7502 nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
7503 variablesCounter[nestedType] = 0;
7505 realBlockStack[realBlockPtr = 0] = 0;
7506 recoveredStaticInitializerStart = 0;
7510 * Reset context so as to resume to regular parse loop
7511 * If unable to reset for resuming, answers false.
7513 * Move checkpoint location, reset internal stacks and
7514 * decide which grammar goal is activated.
7516 protected boolean resumeAfterRecovery() {
7518 // reset internal stacks
7521 /* attempt to move checkpoint location */
7522 if (!this.moveRecoveryCheckpoint())
7525 // only look for headers
7526 if (referenceContext instanceof CompilationUnitDeclaration) {
7528 diet = true; // passed this point, will not consider method bodies
7531 // does not know how to restart
7535 * Syntax error was detected. Will attempt to perform some recovery action in order
7536 * to resume to the regular parse loop.
7538 protected boolean resumeOnSyntaxError() {
7540 /* request recovery initialization */
7541 if (currentElement == null) {
7542 currentElement = this.buildInitialRecoveryState(); // build some recovered elements
7544 /* do not investigate deeper in recovery when no recovered element */
7545 if (currentElement == null)
7548 /* manual forced recovery restart - after headers */
7549 if (restartRecovery) {
7550 restartRecovery = false;
7552 /* update recovery state with current error state of the parser */
7553 this.updateRecoveryState();
7555 /* attempt to reset state in order to resume to parse loop */
7556 return this.resumeAfterRecovery();
7558 protected static int tAction(int state, int sym) {
7559 return action[check(state + sym) == sym ? state + sym : state];
7561 public String toString() {
7563 String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
7564 for (int i = 0; i <= identifierPtr; i++) {
7565 s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
7567 s = s + "}\n"; //$NON-NLS-1$
7569 s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
7570 for (int i = 0; i <= identifierLengthPtr; i++) {
7571 s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$
7573 s = s + "}\n"; //$NON-NLS-1$
7575 s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
7576 for (int i = 0; i <= astLengthPtr; i++) {
7577 s = s + astLengthStack[i] + ","; //$NON-NLS-1$
7579 s = s + "}\n"; //$NON-NLS-1$
7580 s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7582 s = s + "intStack : int[] = {"; //$NON-NLS-1$
7583 for (int i = 0; i <= intPtr; i++) {
7584 s = s + intStack[i] + ","; //$NON-NLS-1$
7586 s = s + "}\n"; //$NON-NLS-1$
7588 s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
7589 for (int i = 0; i <= expressionLengthPtr; i++) {
7590 s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$
7592 s = s + "}\n"; //$NON-NLS-1$
7594 s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7596 s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$
7601 * Update recovery state based on current parser/scanner state
7603 protected void updateRecoveryState() {
7605 /* expose parser state to recovery state */
7606 currentElement.updateFromParserState();
7608 /* check and update recovered state based on current token,
7609 this action is also performed when shifting token after recovery
7612 this.recoveryTokenCheck();
7614 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
7615 //fields is a definition of fields that are grouped together like in
7616 //public int[] a, b[], c
7617 //which results into 3 fields.
7619 FieldDeclaration field;
7620 int endTypeDeclarationPosition = -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart;
7621 for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
7622 //last one is special(see below)
7623 field = (FieldDeclaration) astStack[astPtr - i - 1];
7624 field.endPart1Position = endTypeDeclarationPosition;
7625 field.endPart2Position = -1 + astStack[astPtr - i].sourceStart;
7628 (field = (FieldDeclaration) astStack[astPtr]).endPart1Position = endTypeDeclarationPosition;
7629 field.endPart2Position = field.declarationSourceEnd;
7632 protected void updateSourcePosition(Expression exp) {
7633 //update the source Position of the expression
7635 //intStack : int int
7639 exp.sourceEnd = intStack[intPtr--];
7640 exp.sourceStart = intStack[intPtr--];