It's now possible to assign a value to a variable
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.parser;
12
13 import net.sourceforge.phpdt.core.compiler.*;
14 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
15 import net.sourceforge.phpdt.internal.compiler.*;
16 import net.sourceforge.phpdt.internal.compiler.env.*; 
17 import net.sourceforge.phpdt.internal.compiler.impl.*;
18 import net.sourceforge.phpdt.internal.compiler.ast.*; 
19 import net.sourceforge.phpdt.internal.compiler.lookup.*;
20 import net.sourceforge.phpdt.internal.compiler.problem.*;
21 import net.sourceforge.phpdt.internal.compiler.util.*;
22
23 import java.io.*;
24 import java.util.ArrayList;
25
26 public class Parser implements BindingIds, ParserBasicInformation, ITerminalSymbols, CompilerModifiers, OperatorIds, TypeIds {
27         protected ProblemReporter problemReporter;
28         public int firstToken ; // handle for multiple parsing goals
29         public int lastAct ; //handle for multiple parsing goals
30         protected ReferenceContext referenceContext;
31         public int currentToken;
32         private int synchronizedBlockSourceStart;
33
34         //error recovery management
35         protected int lastCheckPoint;
36         protected RecoveredElement currentElement;
37         public static boolean VERBOSE_RECOVERY = false;
38         protected boolean restartRecovery;
39         protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
40         protected boolean hasReportedError;
41         protected int recoveredStaticInitializerStart;
42         protected int lastIgnoredToken, nextIgnoredToken;
43         protected int lastErrorEndPosition;
44                 
45         // 1.4 feature
46         protected boolean assertMode = false;
47         
48         //internal data for the automat 
49         protected final static int StackIncrement = 255;
50         protected int stateStackTop;
51         protected int[] stack = new int[StackIncrement];
52         //scanner token 
53         public Scanner scanner;
54         //ast stack
55         final static int AstStackIncrement = 100;
56         protected int astPtr;
57         protected AstNode[] astStack = new AstNode[AstStackIncrement];
58         protected int astLengthPtr;
59         protected int[] astLengthStack;
60         public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
61         AstNode [] noAstNodes = new AstNode[AstStackIncrement];
62         //expression stack
63         final static int ExpressionStackIncrement = 100;
64         protected int expressionPtr;
65         protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
66         protected int expressionLengthPtr;
67         protected int[] expressionLengthStack;
68         Expression [] noExpressions = new Expression[ExpressionStackIncrement];
69         //identifiers stacks 
70         protected int identifierPtr;
71         protected char[][] identifierStack;
72         protected int identifierLengthPtr;
73         protected int[] identifierLengthStack;
74         protected long[] identifierPositionStack;
75         //positions , dimensions , .... (what ever is int) ..... stack
76         protected int intPtr;
77         protected int[] intStack;
78         protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
79         protected int endStatementPosition;
80         protected int lParenPos,rParenPos; //accurate only when used !
81         //modifiers dimensions nestedType etc.......
82         protected boolean optimizeStringLiterals =true;
83         protected int modifiers;
84         protected int modifiersSourceStart;
85         protected int nestedType, dimensions;
86         protected int[] nestedMethod; //the ptr is nestedType
87         protected int[] realBlockStack;
88         protected int realBlockPtr;
89         protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
90         protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
91         protected int[] variablesCounter;
92         //===DATA===DATA===DATA===DATA===DATA===DATA===//
93     public final static byte rhs[] = {0,
94             2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
95             2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
96             1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
97             2,2,1,1,1,1,3,4,0,1,2,1,1,1,1,
98             1,1,1,1,1,5,1,2,1,2,2,2,1,1,2,
99             2,2,4,1,1,1,1,2,1,1,1,1,1,1,1,
100             1,1,1,1,2,3,3,2,2,1,3,1,3,1,2,
101             1,1,1,3,0,3,1,1,1,1,1,1,1,4,1,
102             3,3,7,0,0,0,0,0,2,1,1,1,2,2,4,
103             4,5,4,4,2,1,2,3,3,1,3,3,1,3,1,
104             4,0,2,1,2,2,4,1,1,2,5,5,7,7,7,
105             7,2,2,3,2,2,3,1,2,1,2,1,1,2,2,
106             1,1,1,1,1,3,3,4,1,3,4,0,1,2,1,
107             1,1,1,2,3,4,0,1,1,1,1,1,1,1,1,
108             1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
109             1,3,3,2,1,1,1,1,1,1,1,5,7,7,6,
110             2,3,3,4,1,2,2,1,2,3,2,5,5,7,9,
111             9,1,1,1,1,3,3,5,2,3,2,3,3,3,5,
112             1,3,4,1,2,5,2,1,1,1,1,1,1,3,1,
113             1,3,3,3,3,3,1,1,5,6,8,7,2,0,2,
114             0,1,3,4,4,1,2,3,2,1,1,2,2,3,3,
115             4,6,6,4,4,1,1,1,1,2,2,0,1,1,3,
116             3,1,3,3,1,3,3,1,5,5,4,1,3,3,3,
117             1,3,3,1,3,3,3,1,3,3,3,3,3,1,3,
118             3,1,3,1,3,1,3,1,3,1,3,1,5,1,1,
119             3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,
120             1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,
121             0,1,0,2,0,1,0,1,0,1,0,1,0,1,0,
122             1,0,1,0,2,0,0,1,0,1,0,1,0,1,0,
123             1
124     };
125
126                 
127         public  static char asb[] = null;
128         public  static char asr[] = null;
129         public  static char symbol_index[] = null;
130         private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
131
132         public final static String name[] = { null,
133             "++",//$NON-NLS-1$
134             "--",//$NON-NLS-1$
135             "==",//$NON-NLS-1$
136             "<=",//$NON-NLS-1$
137             ">=",//$NON-NLS-1$
138             "!=",//$NON-NLS-1$
139             "<<",//$NON-NLS-1$
140             ">>",//$NON-NLS-1$
141             ">>>",//$NON-NLS-1$
142             "+=",//$NON-NLS-1$
143             "-=",//$NON-NLS-1$
144             "*=",//$NON-NLS-1$
145             "/=",//$NON-NLS-1$
146             "&=",//$NON-NLS-1$
147             "|=",//$NON-NLS-1$
148             "^=",//$NON-NLS-1$
149             "%=",//$NON-NLS-1$
150             "<<=",//$NON-NLS-1$
151             ">>=",//$NON-NLS-1$
152             ">>>=",//$NON-NLS-1$
153             "||",//$NON-NLS-1$
154             "&&",//$NON-NLS-1$
155             "+",//$NON-NLS-1$
156             "-",//$NON-NLS-1$
157             "!",//$NON-NLS-1$
158             "%",//$NON-NLS-1$
159             "^",//$NON-NLS-1$
160             "&",//$NON-NLS-1$
161             "*",//$NON-NLS-1$
162             "|",//$NON-NLS-1$
163             "~",//$NON-NLS-1$
164             "/",//$NON-NLS-1$
165             ">",//$NON-NLS-1$
166             "<",//$NON-NLS-1$
167             "(",//$NON-NLS-1$
168             ")",//$NON-NLS-1$
169             "{",//$NON-NLS-1$
170             "}",//$NON-NLS-1$
171             "[",//$NON-NLS-1$
172             "]",//$NON-NLS-1$
173             ";",//$NON-NLS-1$
174             "?",//$NON-NLS-1$
175             ":",//$NON-NLS-1$
176             ",",//$NON-NLS-1$
177             ".",//$NON-NLS-1$
178             "=",//$NON-NLS-1$
179             "",//$NON-NLS-1$
180             "$empty",//$NON-NLS-1$
181             "Identifier",//$NON-NLS-1$
182             "abstract",//$NON-NLS-1$
183             "assert",//$NON-NLS-1$
184             "boolean",//$NON-NLS-1$
185             "break",//$NON-NLS-1$
186             "byte",//$NON-NLS-1$
187             "case",//$NON-NLS-1$
188             "catch",//$NON-NLS-1$
189             "char",//$NON-NLS-1$
190             "class",//$NON-NLS-1$
191             "continue",//$NON-NLS-1$
192             "default",//$NON-NLS-1$
193             "do",//$NON-NLS-1$
194             "double",//$NON-NLS-1$
195             "else",//$NON-NLS-1$
196             "extends",//$NON-NLS-1$
197             "false",//$NON-NLS-1$
198             "final",//$NON-NLS-1$
199             "finally",//$NON-NLS-1$
200             "float",//$NON-NLS-1$
201             "for",//$NON-NLS-1$
202             "if",//$NON-NLS-1$
203             "implements",//$NON-NLS-1$
204             "import",//$NON-NLS-1$
205             "instanceof",//$NON-NLS-1$
206             "int",//$NON-NLS-1$
207             "interface",//$NON-NLS-1$
208             "long",//$NON-NLS-1$
209             "native",//$NON-NLS-1$
210             "new",//$NON-NLS-1$
211             "null",//$NON-NLS-1$
212             "package",//$NON-NLS-1$
213             "private",//$NON-NLS-1$
214             "protected",//$NON-NLS-1$
215             "public",//$NON-NLS-1$
216             "return",//$NON-NLS-1$
217             "short",//$NON-NLS-1$
218             "static",//$NON-NLS-1$
219             "strictfp",//$NON-NLS-1$
220             "super",//$NON-NLS-1$
221             "switch",//$NON-NLS-1$
222             "synchronized",//$NON-NLS-1$
223             "this",//$NON-NLS-1$
224             "throw",//$NON-NLS-1$
225             "throws",//$NON-NLS-1$
226             "transient",//$NON-NLS-1$
227             "true",//$NON-NLS-1$
228             "try",//$NON-NLS-1$
229             "void",//$NON-NLS-1$
230             "volatile",//$NON-NLS-1$
231             "while",//$NON-NLS-1$
232             "IntegerLiteral",//$NON-NLS-1$
233             "LongLiteral",//$NON-NLS-1$
234             "FloatingPointLiteral",//$NON-NLS-1$
235             "DoubleLiteral",//$NON-NLS-1$
236             "CharacterLiteral",//$NON-NLS-1$
237             "StringLiteral",//$NON-NLS-1$
238             UNEXPECTED_EOF,
239             "Invalid Character",//$NON-NLS-1$            
240             "Goal",//$NON-NLS-1$
241             "MethodBody",//$NON-NLS-1$
242             "ConstructorBody",//$NON-NLS-1$
243             "StaticInitializer",//$NON-NLS-1$
244             "Initializer",//$NON-NLS-1$
245             "Headers",//$NON-NLS-1$
246             "BlockStatements",//$NON-NLS-1$
247             "MethodPushModifiersHeader",//$NON-NLS-1$
248             "CatchHeader",//$NON-NLS-1$
249             "FieldDeclaration",//$NON-NLS-1$
250             "ImportDeclaration",//$NON-NLS-1$
251             "PackageDeclaration",//$NON-NLS-1$
252             "TypeDeclaration",//$NON-NLS-1$
253             "GenericMethodDeclaration",//$NON-NLS-1$
254             "ClassBodyDeclaration",//$NON-NLS-1$
255             "Expression",//$NON-NLS-1$
256             "Type",//$NON-NLS-1$
257             "PrimitiveType",//$NON-NLS-1$
258             "ReferenceType",//$NON-NLS-1$
259             "ClassOrInterfaceType",//$NON-NLS-1$
260             "ArrayType",//$NON-NLS-1$
261             "Name",//$NON-NLS-1$
262             "Dims",//$NON-NLS-1$
263             "ClassType",//$NON-NLS-1$
264             "SimpleName",//$NON-NLS-1$
265             "Header",//$NON-NLS-1$
266             "ClassHeader",//$NON-NLS-1$
267             "InterfaceHeader",//$NON-NLS-1$
268             "MethodHeader",//$NON-NLS-1$
269             "ConstructorHeader",//$NON-NLS-1$
270             "FormalParameter",//$NON-NLS-1$
271             "ImportDeclarations",//$NON-NLS-1$
272             "TypeDeclarations",//$NON-NLS-1$
273             "PackageDeclarationName",//$NON-NLS-1$
274             "SingleTypeImportDeclarationName",//$NON-NLS-1$
275             "TypeImportOnDemandDeclarationName",//$NON-NLS-1$
276             "Modifiers",//$NON-NLS-1$
277             "Modifier",//$NON-NLS-1$
278             "ClassBody",//$NON-NLS-1$
279             "ClassHeaderName",//$NON-NLS-1$
280             "InterfaceTypeList",//$NON-NLS-1$
281             "InterfaceType",//$NON-NLS-1$
282             "ClassBodyDeclarations",//$NON-NLS-1$
283             "Block",//$NON-NLS-1$
284             "VariableDeclarators",//$NON-NLS-1$
285             "VariableDeclarator",//$NON-NLS-1$
286             "VariableDeclaratorId",//$NON-NLS-1$
287             "VariableInitializer",//$NON-NLS-1$
288             "ArrayInitializer",//$NON-NLS-1$
289             "MethodHeaderName",//$NON-NLS-1$
290             "MethodHeaderParameters",//$NON-NLS-1$
291             "MethodPushModifiersHeaderName",//$NON-NLS-1$
292             "ClassTypeList",//$NON-NLS-1$
293             "ConstructorHeaderName",//$NON-NLS-1$
294             "FormalParameterList",//$NON-NLS-1$
295             "ClassTypeElt",//$NON-NLS-1$
296             "StaticOnly",//$NON-NLS-1$
297             "ExplicitConstructorInvocation",//$NON-NLS-1$
298             "Primary",//$NON-NLS-1$
299             "InterfaceBody",//$NON-NLS-1$
300             "InterfaceHeaderName",//$NON-NLS-1$
301             "InterfaceMemberDeclarations",//$NON-NLS-1$
302             "InterfaceMemberDeclaration",//$NON-NLS-1$
303             "VariableInitializers",//$NON-NLS-1$
304             "BlockStatement",//$NON-NLS-1$
305             "Statement",//$NON-NLS-1$
306             "LocalVariableDeclaration",//$NON-NLS-1$
307             "StatementWithoutTrailingSubstatement",//$NON-NLS-1$
308             "StatementNoShortIf",//$NON-NLS-1$
309             "StatementExpression",//$NON-NLS-1$
310             "PostIncrementExpression",//$NON-NLS-1$
311             "PostDecrementExpression",//$NON-NLS-1$
312             "MethodInvocation",//$NON-NLS-1$
313             "ClassInstanceCreationExpression",//$NON-NLS-1$
314             "SwitchBlock",//$NON-NLS-1$
315             "SwitchBlockStatements",//$NON-NLS-1$
316             "SwitchLabels",//$NON-NLS-1$
317             "SwitchBlockStatement",//$NON-NLS-1$
318             "SwitchLabel",//$NON-NLS-1$
319             "ConstantExpression",//$NON-NLS-1$
320             "StatementExpressionList",//$NON-NLS-1$
321             "OnlySynchronized",//$NON-NLS-1$
322             "Catches",//$NON-NLS-1$
323             "Finally",//$NON-NLS-1$
324             "CatchClause",//$NON-NLS-1$
325             "PushLPAREN",//$NON-NLS-1$
326             "PushRPAREN",//$NON-NLS-1$
327             "PrimaryNoNewArray",//$NON-NLS-1$
328             "FieldAccess",//$NON-NLS-1$
329             "ArrayAccess",//$NON-NLS-1$
330             "ClassInstanceCreationExpressionName",//$NON-NLS-1$
331             "ArgumentList",//$NON-NLS-1$
332             "DimWithOrWithOutExprs",//$NON-NLS-1$
333             "DimWithOrWithOutExpr",//$NON-NLS-1$
334             "DimsLoop",//$NON-NLS-1$
335             "OneDimLoop",//$NON-NLS-1$
336             "PostfixExpression",//$NON-NLS-1$
337             "UnaryExpression",//$NON-NLS-1$
338             "UnaryExpressionNotPlusMinus",//$NON-NLS-1$
339             "MultiplicativeExpression",//$NON-NLS-1$
340             "AdditiveExpression",//$NON-NLS-1$
341             "ShiftExpression",//$NON-NLS-1$
342             "RelationalExpression",//$NON-NLS-1$
343             "EqualityExpression",//$NON-NLS-1$
344             "AndExpression",//$NON-NLS-1$
345             "ExclusiveOrExpression",//$NON-NLS-1$
346             "InclusiveOrExpression",//$NON-NLS-1$
347             "ConditionalAndExpression",//$NON-NLS-1$
348             "ConditionalOrExpression",//$NON-NLS-1$
349             "ConditionalExpression",//$NON-NLS-1$
350             "AssignmentExpression",//$NON-NLS-1$
351             "LeftHandSide",//$NON-NLS-1$
352             "AssignmentOperator"//$NON-NLS-1$
353     };
354     
355         public  static short check_table[] = null;
356         public  static char lhs[] =  null;
357         public  static char action[] = lhs;
358         private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
359
360         static {
361                 try{
362                         initTables();
363                 } catch(java.io.IOException ex){
364                         throw new ExceptionInInitializerError(ex.getMessage());
365                 }
366         }
367
368         public static final int RoundBracket = 0;
369         public static final int SquareBracket = 1;
370         public static final int CurlyBracket = 2;
371         public static final int BracketKinds = 3;
372
373 public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals, boolean assertMode) {
374                 
375         this.problemReporter = problemReporter;
376         this.optimizeStringLiterals = optimizeStringLiterals;
377         this.assertMode = assertMode;
378         this.initializeScanner();
379         astLengthStack = new int[50];
380         expressionLengthStack = new int[30];
381         intStack = new int[50];
382         identifierStack = new char[30][];
383         identifierLengthStack = new int[30];
384         nestedMethod = new int[30];
385         realBlockStack = new int[30];
386         identifierPositionStack = new long[30];
387         variablesCounter = new int[30];
388 }
389 /**
390  *
391  * INTERNAL USE-ONLY
392  */
393 protected void adjustInterfaceModifiers() {
394         intStack[intPtr - 1] |= AccInterface;
395 }
396 public final void arrayInitializer(int length) {
397         //length is the size of the array Initializer
398         //expressionPtr points on the last elt of the arrayInitializer
399         //i.e. it has not been decremented yet.
400
401         ArrayInitializer ai = new ArrayInitializer();
402         if (length != 0) {
403                 expressionPtr -= length;
404                 System.arraycopy(expressionStack, expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
405         }
406         pushOnExpressionStack(ai);
407         //positionning
408         ai.sourceEnd = endStatementPosition;
409         int searchPosition = length == 0 ? endPosition : ai.expressions[0].sourceStart;
410         try {
411                 //does not work with comments(that contain '{') nor '{' describes as a unicode....              
412                 while (scanner.source[--searchPosition] != '{') {
413                 }
414         } catch (IndexOutOfBoundsException ex) {
415                 //should never occur (except for strange cases like whose describe above)
416                 searchPosition = (length == 0 ? endPosition : ai.expressions[0].sourceStart) - 1;
417         }
418         ai.sourceStart = searchPosition;
419 }
420 protected static int asi(int state) {
421
422         return asb[original_state(state)];
423 }
424 protected void blockReal() {
425         // See consumeLocalVariableDeclarationStatement in case of change: duplicated code
426         // increment the amount of declared variables for this block
427         realBlockStack[realBlockPtr]++;
428 }
429 private final static void buildFileFor(String filename, String tag, String[] tokens, boolean isShort) throws java.io.IOException {
430
431         //transform the String tokens into chars before dumping then into file
432
433         int i = 0;
434         //read upto the tag
435         while (!tokens[i++].equals(tag)) {}
436         //read upto the }
437         char[] chars = new char[tokens.length]; //can't be bigger
438         int ic = 0;
439         String token;
440         while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
441                 int c = Integer.parseInt(token);
442                 if (isShort)
443                         c += 32768;
444                 chars[ic++] = (char) c;
445         }
446
447         //resize
448         System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
449
450         buildFileForTable(filename, chars);
451 }
452 private final static void buildFileForTable(String filename, char[] chars) throws java.io.IOException {
453
454         byte[] bytes = new byte[chars.length * 2];
455         for (int i = 0; i < chars.length; i++) {
456                 bytes[2 * i] = (byte) (chars[i] >>> 8);
457                 bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
458         }
459
460         java.io.FileOutputStream stream = new java.io.FileOutputStream(filename);
461         stream.write(bytes);
462         stream.close();
463         System.out.println(filename + " creation complete"); //$NON-NLS-1$
464 }
465 public final static void buildFilesFromLPG(String dataFilename) throws java.io.IOException {
466
467         //RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
468
469         //build from the lpg javadcl.java files that represents the parser tables
470         //lhs check_table asb asr symbol_index
471
472         //[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
473
474         char[] contents = new char[] {};
475         try {
476                 contents = Util.getFileCharContent(new File(dataFilename), null);
477         } catch (IOException ex) {
478                 System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
479                 return;
480         }
481         java.util.StringTokenizer st = 
482                 new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;");  //$NON-NLS-1$
483         String[] tokens = new String[st.countTokens()];
484         int i = 0;
485         while (st.hasMoreTokens()) {
486                 tokens[i++] = st.nextToken();
487         }
488         final String prefix = FILEPREFIX;
489         i = 0;
490         buildFileFor(prefix + (++i) + ".rsc", "lhs", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
491         buildFileFor(prefix + (++i) + ".rsc", "check_table", tokens, true); //$NON-NLS-2$ //$NON-NLS-1$
492         buildFileFor(prefix + (++i) + ".rsc", "asb", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
493         buildFileFor(prefix + (++i) + ".rsc", "asr", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
494         buildFileFor(prefix + (++i) + ".rsc", "symbol_index", tokens, false); //$NON-NLS-2$ //$NON-NLS-1$
495         System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
496 }
497 /*
498  * Build initial recovery state.
499  * Recovery state is inferred from the current state of the parser (reduced node stack).
500  */
501 public RecoveredElement buildInitialRecoveryState(){
502
503         /* initialize recovery by retrieving available reduced nodes 
504          * also rebuild bracket balance 
505          */
506         lastCheckPoint = 0;
507
508         RecoveredElement element = null;
509         if (referenceContext instanceof CompilationUnitDeclaration){
510                 element = new RecoveredUnit(compilationUnit, 0, this);
511                 
512                 /* ignore current stack state, since restarting from the beginnning 
513                    since could not trust simple brace count */
514                 if (true){ // experimenting restart recovery from scratch
515                         compilationUnit.currentPackage = null;
516                         compilationUnit.imports = null;
517                         compilationUnit.types = null;
518                         currentToken = 0;
519                         listLength = 0;
520                         return element;
521                 }
522                 if (compilationUnit.currentPackage != null){
523                         lastCheckPoint = compilationUnit.currentPackage.declarationSourceEnd+1;
524                 }
525                 if (compilationUnit.imports != null){
526                         lastCheckPoint = compilationUnit.imports[compilationUnit.imports.length -1].declarationSourceEnd+1;             
527                 }
528         } else {
529                 if (referenceContext instanceof AbstractMethodDeclaration){
530                         element = new RecoveredMethod((AbstractMethodDeclaration) referenceContext, null, 0, this);
531                         lastCheckPoint = ((AbstractMethodDeclaration) referenceContext).bodyStart;
532                 } else {
533                         /* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
534                         if (referenceContext instanceof TypeDeclaration){
535                                 TypeDeclaration type = (TypeDeclaration) referenceContext;
536                                 for (int i = 0; i < type.fields.length; i++){
537                                         FieldDeclaration field = type.fields[i];                                        
538                                         if (!field.isField()
539                                                 && field.declarationSourceStart <= scanner.initialPosition
540                                                 && scanner.initialPosition <= field.declarationSourceEnd
541                                                 && scanner.eofPosition <= field.declarationSourceEnd+1){
542                                                 element = new RecoveredInitializer((Initializer) field, null, 1, this);
543                                                 lastCheckPoint = field.declarationSourceStart;                                  
544                                                 break;
545                                         }
546                                 }
547                         } 
548                 }
549         }
550
551         if (element == null) return element;
552         
553         for(int i = 0; i <= astPtr; i++){
554                 AstNode node = astStack[i];
555                 if (node instanceof AbstractMethodDeclaration){
556                         AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
557                         if (method.declarationSourceEnd == 0){
558                                 element = element.add(method, 0);
559                                 lastCheckPoint = method.bodyStart;
560                         } else {
561                                 element = element.add(method, 0);
562                                 lastCheckPoint = method.declarationSourceEnd + 1;
563                         }
564                         continue;
565                 }
566                 if (node instanceof Initializer){
567                         Initializer initializer = (Initializer) node;
568                         if (initializer.declarationSourceEnd == 0){
569                                 element = element.add(initializer, 1);
570                                 lastCheckPoint = initializer.bodyStart;                         
571                         } else {
572                                 element = element.add(initializer, 0);
573                                 lastCheckPoint = initializer.declarationSourceEnd + 1;
574                         }
575                         continue;
576                 }               
577                 if (node instanceof FieldDeclaration){
578                         FieldDeclaration field = (FieldDeclaration) node;
579                         if (field.declarationSourceEnd == 0){
580                                 element = element.add(field, 0);
581                                 if (field.initialization == null){
582                                         lastCheckPoint = field.sourceEnd + 1;
583                                 } else {
584                                         lastCheckPoint = field.initialization.sourceEnd + 1;
585                                 }
586                         } else {
587                                 element = element.add(field, 0);
588                                 lastCheckPoint = field.declarationSourceEnd + 1;
589                         }
590                         continue;
591                 }
592                 if (node instanceof TypeDeclaration){
593                         TypeDeclaration type = (TypeDeclaration) node;
594                         if (type.declarationSourceEnd == 0){
595                                 element = element.add(type, 0); 
596                                 lastCheckPoint = type.bodyStart;
597                         } else {
598                                 element = element.add(type, 0);                         
599                                 lastCheckPoint = type.declarationSourceEnd + 1;
600                         }
601                         continue;
602                 }
603                 if (node instanceof ImportReference){
604                         ImportReference importRef = (ImportReference) node;
605                         element = element.add(importRef, 0);
606                         lastCheckPoint = importRef.declarationSourceEnd + 1;
607                 }
608         }
609         return element;
610 }
611 protected static short check(int i) {
612         return check_table[i - (NUM_RULES + 1)];
613 }
614 /*
615  * Reconsider the entire source looking for inconsistencies in {} () []
616  */
617 public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
618
619         scanner.wasAcr = false;
620         boolean anomaliesDetected = false;      
621         try {
622                 char[] source = scanner.source;
623                 int[] leftCount = {0, 0, 0};
624                 int[] rightCount = {0, 0, 0};
625                 int[] depths = {0, 0, 0};
626                 int[][] leftPositions = new int[][] {new int[10], new int[10], new int[10]};
627                 int[][] leftDepths = new int[][] {new int[10], new int[10], new int[10]};
628                 int[][] rightPositions = new int[][] {new int[10], new int[10], new int[10]};
629                 int[][] rightDepths = new int[][] {new int[10], new int[10], new int[10]};
630                 scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
631                 while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
632                         try {
633                                 // ---------Consume white space and handles startPosition---------
634                                 boolean isWhiteSpace;
635                                 do {
636                                         scanner.startPosition = scanner.currentPosition;
637                                         if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
638                                                 isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
639                                         } else {
640                                                 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
641                                                         if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
642                                                                 // only record line positions we have not recorded yet
643                                                                 scanner.pushLineSeparator();
644                                                         }
645                                                 }
646                                                 isWhiteSpace = Character.isWhitespace(scanner.currentCharacter);
647                                         }
648                                 } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
649
650                                 // -------consume token until } is found---------
651
652                                 switch (scanner.currentCharacter) {
653                                         case '{' :
654                                                 {
655                                                         int index = leftCount[CurlyBracket] ++;
656                                                         if (index == leftPositions[CurlyBracket].length) {
657                                                                 System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
658                                                                 System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
659                                                         }
660                                                         leftPositions[CurlyBracket][index] = scanner.startPosition;
661                                                         leftDepths[CurlyBracket][index] = depths[CurlyBracket] ++;
662                                                 }
663                                                 break;
664                                         case '}' :
665                                                 {
666                                                         int index = rightCount[CurlyBracket] ++;
667                                                         if (index == rightPositions[CurlyBracket].length) {
668                                                                 System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
669                                                                 System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
670                                                         }
671                                                         rightPositions[CurlyBracket][index] = scanner.startPosition;
672                                                         rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
673                                                 }
674                                                 break;
675                                         case '(' :
676                                                 {
677                                                         int index = leftCount[RoundBracket] ++;
678                                                         if (index == leftPositions[RoundBracket].length) {
679                                                                 System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
680                                                                 System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
681                                                         }
682                                                         leftPositions[RoundBracket][index] = scanner.startPosition;
683                                                         leftDepths[RoundBracket][index] = depths[RoundBracket] ++;
684                                                 }
685                                                 break;
686                                         case ')' :
687                                                 {
688                                                         int index = rightCount[RoundBracket] ++;
689                                                         if (index == rightPositions[RoundBracket].length) {
690                                                                 System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
691                                                                 System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
692                                                         }
693                                                         rightPositions[RoundBracket][index] = scanner.startPosition;
694                                                         rightDepths[RoundBracket][index] = --depths[RoundBracket];
695                                                 }
696                                                 break;
697                                         case '[' :
698                                                 {
699                                                         int index = leftCount[SquareBracket] ++;
700                                                         if (index == leftPositions[SquareBracket].length) {
701                                                                 System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
702                                                                 System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
703                                                         }
704                                                         leftPositions[SquareBracket][index] = scanner.startPosition;
705                                                         leftDepths[SquareBracket][index] = depths[SquareBracket] ++;
706                                                 }
707                                                 break;
708                                         case ']' :
709                                                 {
710                                                         int index = rightCount[SquareBracket] ++;
711                                                         if (index == rightPositions[SquareBracket].length) {
712                                                                 System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
713                                                                 System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
714                                                         }
715                                                         rightPositions[SquareBracket][index] = scanner.startPosition;
716                                                         rightDepths[SquareBracket][index] = --depths[SquareBracket];
717                                                 }
718                                                 break;
719                                         case '\'' :
720                                                 {
721                                                         if (scanner.getNextChar('\\')) {
722                                                                 scanner.scanEscapeCharacter();
723                                                         } else { // consume next character
724                                                                 scanner.unicodeAsBackSlash = false;
725                                                                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
726                                                                         scanner.getNextUnicodeChar();
727                                                                 } else {
728                                                                         if (scanner.withoutUnicodePtr != 0) {
729                                                                                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
730                                                                         }
731                                                                 }
732                                                         }
733                                                         scanner.getNextChar('\'');
734                                                         break;
735                                                 }
736                                         case '"' : // consume next character
737                                                 scanner.unicodeAsBackSlash = false;
738                                                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
739                                                         scanner.getNextUnicodeChar();
740                                                 } else {
741                                                         if (scanner.withoutUnicodePtr != 0) {
742                                                                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
743                                                         }
744                                                 }
745                                                 while (scanner.currentCharacter != '"') {
746                                                         if (scanner.currentCharacter == '\r') {
747                                                                 if (source[scanner.currentPosition] == '\n')
748                                                                         scanner.currentPosition++;
749                                                                 break; // the string cannot go further that the line
750                                                         }
751                                                         if (scanner.currentCharacter == '\n') {
752                                                                 break; // the string cannot go further that the line
753                                                         }
754                                                         if (scanner.currentCharacter == '\\') {
755                                                                 scanner.scanEscapeCharacter();
756                                                         }
757                                                         // consume next character
758                                                         scanner.unicodeAsBackSlash = false;
759                                                         if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
760                                                                 scanner.getNextUnicodeChar();
761                                                         } else {
762                                                                 if (scanner.withoutUnicodePtr != 0) {
763                                                                         scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
764                                                                 }
765                                                         }
766                                                 }
767                                                 break;
768                                         case '/' :
769                                                 {
770                                                         int test;
771                                                         if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment 
772                                                                 //get the next char 
773                                                                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
774                                                                         //-------------unicode traitement ------------
775                                                                         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
776                                                                         scanner.currentPosition++;
777                                                                         while (source[scanner.currentPosition] == 'u') {
778                                                                                 scanner.currentPosition++;
779                                                                         }
780                                                                         if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
781                                                                                 scanner.currentCharacter = 'A';
782                                                                         } //something different from \n and \r
783                                                                         else {
784                                                                                 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
785                                                                         }
786                                                                 }
787                                                                 while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
788                                                                         //get the next char
789                                                                         scanner.startPosition = scanner.currentPosition;
790                                                                         if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
791                                                                                 //-------------unicode traitement ------------
792                                                                                 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
793                                                                                 scanner.currentPosition++;
794                                                                                 while (source[scanner.currentPosition] == 'u') {
795                                                                                         scanner.currentPosition++;
796                                                                                 }
797                                                                                 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
798                                                                                         scanner.currentCharacter = 'A';
799                                                                                 } //something different from \n and \r
800                                                                                 else {
801                                                                                         scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
802                                                                                 }
803                                                                         }
804                                                                 }
805                                                                 if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
806                                                                         if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
807                                                                                 // only record line positions we have not recorded yet
808                                                                                 scanner.pushLineSeparator();
809                                                                         }
810                                                                 }
811                                                                 break;
812                                                         }
813                                                         if (test > 0) { //traditional and annotation comment
814                                                                 boolean star = false;
815                                                                 // consume next character
816                                                                 scanner.unicodeAsBackSlash = false;
817                                                                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
818                                                                         scanner.getNextUnicodeChar();
819                                                                 } else {
820                                                                         if (scanner.withoutUnicodePtr != 0) {
821                                                                                 scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
822                                                                         }
823                                                                 }
824                                                                 if (scanner.currentCharacter == '*') {
825                                                                         star = true;
826                                                                 }
827                                                                 //get the next char 
828                                                                 if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
829                                                                         //-------------unicode traitement ------------
830                                                                         int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
831                                                                         scanner.currentPosition++;
832                                                                         while (source[scanner.currentPosition] == 'u') {
833                                                                                 scanner.currentPosition++;
834                                                                         }
835                                                                         if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
836                                                                                 scanner.currentCharacter = 'A';
837                                                                         } //something different from * and /
838                                                                         else {
839                                                                                 scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
840                                                                         }
841                                                                 }
842                                                                 //loop until end of comment */ 
843                                                                 while ((scanner.currentCharacter != '/') || (!star)) {
844                                                                         star = scanner.currentCharacter == '*';
845                                                                         //get next char
846                                                                         if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
847                                                                                 //-------------unicode traitement ------------
848                                                                                 int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
849                                                                                 scanner.currentPosition++;
850                                                                                 while (source[scanner.currentPosition] == 'u') {
851                                                                                         scanner.currentPosition++;
852                                                                                 }
853                                                                                 if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c1 < 0 || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c2 < 0 || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c3 < 0 || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15 || c4 < 0) { //error don't care of the value
854                                                                                         scanner.currentCharacter = 'A';
855                                                                                 } //something different from * and /
856                                                                                 else {
857                                                                                         scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
858                                                                                 }
859                                                                         }
860                                                                 }
861                                                                 break;
862                                                         }
863                                                         break;
864                                                 }
865                                         default :
866                                                 if (Character.isJavaIdentifierStart(scanner.currentCharacter)) {
867                                                         scanner.scanIdentifierOrKeyword();
868                                                         break;
869                                                 }
870                                                 if (Character.isDigit(scanner.currentCharacter)) {
871                                                         scanner.scanNumber(false);
872                                                         break;
873                                                 }
874                                 }
875                                 //-----------------end switch while try--------------------
876                         } catch (IndexOutOfBoundsException e) {
877                                         break; // read until EOF
878                         } catch (InvalidInputException e) {
879                                 return false; // no clue
880                         }
881                 }
882                 if (scanner.recordLineSeparator) {
883                         compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
884                 }
885
886                 // check placement anomalies against other kinds of brackets
887                 for (int kind = 0; kind < BracketKinds; kind++) {
888                         for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
889                                 int start = leftPositions[kind][leftIndex]; // deepest first
890                                 // find matching closing bracket
891                                 int depth = leftDepths[kind][leftIndex];
892                                 int end = -1;
893                                 for (int i = 0; i < rightCount[kind]; i++) {
894                                         int pos = rightPositions[kind][i];
895                                         // want matching bracket further in source with same depth
896                                         if ((pos > start) && (depth == rightDepths[kind][i])) {
897                                                 end = pos;
898                                                 break;
899                                         }
900                                 }
901                                 if (end < 0) { // did not find a good closing match
902                                         problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
903                                         return true;
904                                 }
905                                 // check if even number of opening/closing other brackets in between this pair of brackets
906                                 int balance = 0;
907                                 for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
908                                         for (int i = 0; i < leftCount[otherKind]; i++) {
909                                                 int pos = leftPositions[otherKind][i];
910                                                 if ((pos > start) && (pos < end))
911                                                         balance++;
912                                         }
913                                         for (int i = 0; i < rightCount[otherKind]; i++) {
914                                                 int pos = rightPositions[otherKind][i];
915                                                 if ((pos > start) && (pos < end))
916                                                         balance--;
917                                         }
918                                         if (balance != 0) {
919                                                 problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
920                                                 return true;
921                                         }
922                                 }
923                         }
924                         // too many opening brackets ?
925                         for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
926                                 anomaliesDetected = true;
927                                 problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, compilationUnit.compilationResult);
928                         }
929                         // too many closing brackets ?
930                         for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
931                                 anomaliesDetected = true;
932                                 problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
933                         }
934                         if (anomaliesDetected) return true;
935                 }
936                 
937                 return anomaliesDetected;
938         } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
939                 return anomaliesDetected;
940         } catch (NullPointerException e) { // jdk1.2.2 jit bug
941                 return anomaliesDetected;
942         }
943 }
944 public final void checkAndSetModifiers(int flag){
945         /*modify the current modifiers buffer.
946         When the startPosition of the modifiers is 0
947         it means that the modifier being parsed is the first
948         of a list of several modifiers. The startPosition
949         is zeroed when a copy of modifiers-buffer is push
950         onto the astStack. */
951
952         if ((modifiers & flag) != 0){ // duplicate modifier
953                 modifiers |= AccAlternateModifierProblem;
954         }
955         modifiers |= flag;
956                         
957         if (modifiersSourceStart < 0) modifiersSourceStart = scanner.startPosition;
958 }
959 public void checkAnnotation() {
960
961         boolean deprecated = false;
962         boolean checkDeprecated = false;
963         int lastAnnotationIndex = -1;
964
965         //since jdk1.2 look only in the last java doc comment...
966         found : for (lastAnnotationIndex = scanner.commentPtr; lastAnnotationIndex >= 0; lastAnnotationIndex--){
967                 //look for @deprecated into the first javadoc comment preceeding the declaration
968                 int commentSourceStart = scanner.commentStarts[lastAnnotationIndex];
969                 // javadoc only (non javadoc comment have negative end positions.)
970                 if (modifiersSourceStart != -1 && modifiersSourceStart < commentSourceStart) {
971                         continue;
972                 }
973                 if (scanner.commentStops[lastAnnotationIndex] < 0) {
974                         break found;
975                 }
976                 checkDeprecated = true;
977                 int commentSourceEnd = scanner.commentStops[lastAnnotationIndex] - 1; //stop is one over
978                 char[] comment = scanner.source;
979
980                 for (int i = commentSourceStart + 3; i < commentSourceEnd - 10; i++) {
981                         if ((comment[i] == '@') 
982                                 && (comment[i + 1] == 'd')
983                                 && (comment[i + 2] == 'e')
984                                 && (comment[i + 3] == 'p')
985                                 && (comment[i + 4] == 'r')
986                                 && (comment[i + 5] == 'e')
987                                 && (comment[i + 6] == 'c')
988                                 && (comment[i + 7] == 'a')
989                                 && (comment[i + 8] == 't')
990                                 && (comment[i + 9] == 'e')
991                                 && (comment[i + 10] == 'd')) {
992                                 // ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
993                                 int nextPos = i+11;
994                                 deprecated = (comment[nextPos] == ' ') || (comment[nextPos] == '\t') || (comment[nextPos] == '\n') || (comment[nextPos] == '\r') || (comment[nextPos] == '*');
995                                 break found;
996                         }
997                 }
998                 break found;
999         }
1000         if (deprecated) {
1001                 checkAndSetModifiers(AccDeprecated);
1002         }
1003         // modify the modifier source start to point at the first comment
1004         if (lastAnnotationIndex >= 0 && checkDeprecated) {
1005                 modifiersSourceStart = scanner.commentStarts[lastAnnotationIndex]; 
1006         }
1007 }
1008 protected void classInstanceCreation(boolean alwaysQualified) {
1009         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1010
1011         // ClassBodyopt produces a null item on the astStak if it produces NO class body
1012         // An empty class body produces a 0 on the length stack.....
1013
1014         AllocationExpression alloc;
1015         int length;
1016         if (((length = astLengthStack[astLengthPtr--]) == 1)
1017                 && (astStack[astPtr] == null)) {
1018                 //NO ClassBody
1019                 astPtr--;
1020                 if (alwaysQualified) {
1021                         alloc = new QualifiedAllocationExpression();
1022                 } else {
1023                         alloc = new AllocationExpression();
1024                 }
1025                 alloc.sourceEnd = endPosition; //the position has been stored explicitly
1026
1027                 if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
1028                         expressionPtr -= length;
1029                         System.arraycopy(
1030                                 expressionStack, 
1031                                 expressionPtr + 1, 
1032                                 alloc.arguments = new Expression[length], 
1033                                 0, 
1034                                 length); 
1035                 }
1036                 alloc.type = getTypeReference(0);
1037                 //the default constructor with the correct number of argument
1038                 //will be created and added by the TC (see createsInternalConstructorWithBinding)
1039                 alloc.sourceStart = intStack[intPtr--];
1040                 pushOnExpressionStack(alloc);
1041         } else {
1042                 dispatchDeclarationInto(length);
1043                 AnonymousLocalTypeDeclaration anonymousTypeDeclaration = (AnonymousLocalTypeDeclaration) astStack[astPtr];
1044                 anonymousTypeDeclaration.declarationSourceEnd = endStatementPosition;
1045                 anonymousTypeDeclaration.bodyEnd = endStatementPosition;
1046                 if (anonymousTypeDeclaration.allocation != null) {
1047                         anonymousTypeDeclaration.allocation.sourceEnd = endStatementPosition;
1048                 }
1049                 astPtr--;
1050                 astLengthPtr--;
1051                 
1052                 // mark fields and initializer with local type mark if needed
1053                 markFieldsWithLocalType(anonymousTypeDeclaration);
1054         }
1055 }
1056 protected final void concatExpressionLists() {
1057         expressionLengthStack[--expressionLengthPtr]++;
1058 }
1059 private final void concatNodeLists() {
1060         /*
1061          * This is a case where you have two sublists into the astStack that you want
1062          * to merge in one list. There is no action required on the astStack. The only
1063          * thing you need to do is merge the two lengths specified on the astStackLength.
1064          * The top two length are for example:
1065          * ... p   n
1066          * and you want to result in a list like:
1067          * ... n+p 
1068          * This means that the p could be equals to 0 in case there is no astNode pushed
1069          * on the astStack.
1070          * Look at the InterfaceMemberDeclarations for an example.
1071          */
1072
1073         astLengthStack[astLengthPtr - 1] += astLengthStack[astLengthPtr--];
1074 }
1075 protected void consumeAllocationHeader() {
1076         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1077
1078         // ClassBodyopt produces a null item on the astStak if it produces NO class body
1079         // An empty class body produces a 0 on the length stack.....
1080
1081         if (currentElement == null){
1082                 return; // should never occur, this consumeRule is only used in recovery mode
1083         }
1084         if (currentToken == TokenNameLBRACE){
1085                 // beginning of an anonymous type
1086                 AnonymousLocalTypeDeclaration anonymousType = new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult);
1087                 anonymousType.sourceStart = intStack[intPtr--];
1088                 anonymousType.sourceEnd = rParenPos; // closing parenthesis
1089                 lastCheckPoint = anonymousType.bodyStart = scanner.currentPosition;
1090                 currentElement = currentElement.add(anonymousType, 0);
1091                 lastIgnoredToken = -1;
1092                 currentToken = 0; // opening brace already taken into account
1093                 return;
1094         }
1095         lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1096         restartRecovery = true; // request to restart from here on
1097 }
1098 protected void consumeArgumentList() {
1099         // ArgumentList ::= ArgumentList ',' Expression
1100         concatExpressionLists();
1101 }
1102 protected void consumeArrayAccess(boolean unspecifiedReference) {
1103         // ArrayAccess ::= Name '[' Expression ']' ==> true
1104         // ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
1105
1106
1107         //optimize push/pop
1108         Expression exp;
1109         if (unspecifiedReference) {
1110                 exp = 
1111                         expressionStack[expressionPtr] = 
1112                                 new ArrayReference(
1113                                         getUnspecifiedReferenceOptimized(),
1114                                         expressionStack[expressionPtr]);
1115         } else {
1116                 expressionPtr--;
1117                 expressionLengthPtr--;
1118                 exp = 
1119                         expressionStack[expressionPtr] = 
1120                                 new ArrayReference(
1121                                         expressionStack[expressionPtr],
1122                                         expressionStack[expressionPtr + 1]);
1123         }
1124         exp.sourceEnd = endPosition;
1125 }
1126 protected void consumeArrayCreationExpression() {
1127         // ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
1128         // ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
1129
1130         int length;
1131         ArrayAllocationExpression aae = new ArrayAllocationExpression();
1132         if (expressionLengthStack[expressionLengthPtr] != 0) {
1133                 expressionLengthPtr -- ;
1134                 aae.initializer = (ArrayInitializer) expressionStack[expressionPtr--];
1135         } else {
1136                 expressionLengthPtr--;
1137         }
1138                 
1139         aae.type = getTypeReference(0);
1140         length = (expressionLengthStack[expressionLengthPtr--]);
1141         expressionPtr -= length ;
1142         System.arraycopy(
1143                 expressionStack,
1144                 expressionPtr+1,
1145                 aae.dimensions = new Expression[length],
1146                 0,
1147                 length);
1148         aae.sourceStart = intStack[intPtr--];
1149         if (aae.initializer == null) {
1150                 aae.sourceEnd = endPosition;
1151         } else {
1152                 aae.sourceEnd = aae.initializer.sourceEnd ;
1153         }
1154         pushOnExpressionStack(aae);
1155 }
1156 protected void consumeArrayInitializer() {
1157         // ArrayInitializer ::= '{' VariableInitializers '}'
1158         // ArrayInitializer ::= '{' VariableInitializers , '}'
1159
1160         arrayInitializer(expressionLengthStack[expressionLengthPtr--]);
1161 }
1162
1163 protected void consumeAssertStatement() {
1164         // AssertStatement ::= 'assert' Expression ':' Expression ';'
1165         expressionLengthPtr-=2;
1166         pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], expressionStack[expressionPtr--], intStack[intPtr--]));
1167 }
1168
1169 protected void consumeAssignment() {
1170         // Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
1171         //optimize the push/pop
1172
1173         int op = intStack[intPtr--] ; //<--the encoded operator
1174         
1175         expressionPtr -- ; expressionLengthPtr -- ;
1176         expressionStack[expressionPtr] =
1177                 (op != EQUAL ) ?
1178                         new CompoundAssignment(
1179                                 expressionStack[expressionPtr] ,
1180                                 expressionStack[expressionPtr+1], 
1181                                 op,
1182                                 scanner.startPosition - 1)      :
1183                         new Assignment(
1184                                 expressionStack[expressionPtr] ,
1185                                 expressionStack[expressionPtr+1],
1186                                 scanner.startPosition - 1);
1187 }
1188 protected void consumeAssignmentOperator(int pos) {
1189         // AssignmentOperator ::= '='
1190         // AssignmentOperator ::= '*='
1191         // AssignmentOperator ::= '/='
1192         // AssignmentOperator ::= '%='
1193         // AssignmentOperator ::= '+='
1194         // AssignmentOperator ::= '-='
1195         // AssignmentOperator ::= '<<='
1196         // AssignmentOperator ::= '>>='
1197         // AssignmentOperator ::= '>>>='
1198         // AssignmentOperator ::= '&='
1199         // AssignmentOperator ::= '^='
1200         // AssignmentOperator ::= '|='
1201
1202         try {
1203                 intStack[++intPtr] = pos;
1204         } catch (IndexOutOfBoundsException e) {
1205                 //intPtr is correct 
1206                 int oldStackLength = intStack.length;
1207                 int oldStack[] = intStack;
1208                 intStack = new int[oldStackLength + StackIncrement];
1209                 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
1210                 intStack[intPtr] = pos;
1211         }
1212 }
1213 protected void consumeBinaryExpression(int op) {
1214         // MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
1215         // MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
1216         // MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
1217         // AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
1218         // AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
1219         // ShiftExpression ::= ShiftExpression '<<'  AdditiveExpression
1220         // ShiftExpression ::= ShiftExpression '>>'  AdditiveExpression
1221         // ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
1222         // RelationalExpression ::= RelationalExpression '<'  ShiftExpression
1223         // RelationalExpression ::= RelationalExpression '>'  ShiftExpression
1224         // RelationalExpression ::= RelationalExpression '<=' ShiftExpression
1225         // RelationalExpression ::= RelationalExpression '>=' ShiftExpression
1226         // AndExpression ::= AndExpression '&' EqualityExpression
1227         // ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
1228         // InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
1229         // ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
1230         // ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
1231
1232         //optimize the push/pop
1233
1234         expressionPtr--;
1235         expressionLengthPtr--;
1236         if (op == OR_OR) {
1237                 expressionStack[expressionPtr] = 
1238                         new OR_OR_Expression(
1239                                 expressionStack[expressionPtr], 
1240                                 expressionStack[expressionPtr + 1], 
1241                                 op); 
1242         } else {
1243                 if (op == AND_AND) {
1244                         expressionStack[expressionPtr] = 
1245                                 new AND_AND_Expression(
1246                                         expressionStack[expressionPtr], 
1247                                         expressionStack[expressionPtr + 1], 
1248                                         op);
1249                 } else {
1250                         // look for "string1" + "string2"
1251                         if ((op == PLUS) && optimizeStringLiterals) {
1252                                 Expression expr1, expr2;
1253                                 expr1 = expressionStack[expressionPtr];
1254                                 expr2 = expressionStack[expressionPtr + 1];
1255                                 if (expr1 instanceof StringLiteral) {
1256                                         if (expr2 instanceof CharLiteral) { // string+char
1257                                                 expressionStack[expressionPtr] = 
1258                                                         ((StringLiteral) expr1).extendWith((CharLiteral) expr2); 
1259                                         } else if (expr2 instanceof StringLiteral) { //string+string
1260                                                 expressionStack[expressionPtr] = 
1261                                                         ((StringLiteral) expr1).extendWith((StringLiteral) expr2); 
1262                                         } else {
1263                                                 expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1264                                         }
1265                                 } else {
1266                                         expressionStack[expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
1267                                 }
1268                         } else {
1269                                 expressionStack[expressionPtr] = 
1270                                         new BinaryExpression(
1271                                                 expressionStack[expressionPtr], 
1272                                                 expressionStack[expressionPtr + 1], 
1273                                                 op);
1274                         }
1275                 }
1276         }
1277 }
1278 protected void consumeBlock() {
1279         // Block ::= OpenBlock '{' BlockStatementsopt '}'
1280         // simpler action for empty blocks
1281
1282         int length;
1283         if ((length = astLengthStack[astLengthPtr--]) == 0) { // empty block 
1284                 pushOnAstStack(Block.EmptyWith(intStack[intPtr--], endStatementPosition));
1285                 realBlockPtr--; // still need to pop the block variable counter
1286         } else {
1287                 Block bk = new Block(realBlockStack[realBlockPtr--]);
1288                 astPtr -= length;
1289                 System.arraycopy(
1290                         astStack, 
1291                         astPtr + 1, 
1292                         bk.statements = new Statement[length], 
1293                         0, 
1294                         length); 
1295                 pushOnAstStack(bk);
1296                 bk.sourceStart = intStack[intPtr--];
1297                 bk.sourceEnd = endStatementPosition;
1298         }
1299 }
1300 protected void consumeBlockStatements() {
1301         // BlockStatements ::= BlockStatements BlockStatement
1302         concatNodeLists();
1303 }
1304 protected void consumeCaseLabel() {
1305         // SwitchLabel ::= 'case' ConstantExpression ':'
1306         expressionLengthPtr--;
1307         pushOnAstStack(new Case(intStack[intPtr--], expressionStack[expressionPtr--]));
1308 }
1309 protected void consumeCastExpression() {
1310         // CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
1311         // CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
1312
1313         //intStack : posOfLeftParen dim posOfRightParen
1314
1315         //optimize the push/pop
1316
1317         Expression exp, cast, castType;
1318         int end = intStack[intPtr--];
1319         expressionStack[expressionPtr] = cast = new CastExpression(exp = expressionStack[expressionPtr], castType = getTypeReference(intStack[intPtr--]));
1320         castType.sourceEnd = end - 1;
1321         castType.sourceStart = (cast.sourceStart = intStack[intPtr--]) + 1;
1322         cast.sourceEnd = exp.sourceEnd;
1323 }
1324 protected void consumeCastExpressionLL1() {
1325         //CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus
1326         // Expression is used in order to make the grammar LL1
1327
1328         //optimize push/pop
1329
1330         Expression castType,cast,exp;
1331         expressionPtr--;
1332         expressionStack[expressionPtr] = 
1333                         cast = new CastExpression(      exp=expressionStack[expressionPtr+1] ,
1334                                                                 castType = getTypeReference(expressionStack[expressionPtr]));
1335         expressionLengthPtr -- ;
1336         updateSourcePosition(castType);
1337         cast.sourceStart=castType.sourceStart;
1338         cast.sourceEnd=exp.sourceEnd;
1339         castType.sourceStart++;
1340         castType.sourceEnd--;
1341         }
1342 protected void consumeCatches() {
1343         // Catches ::= Catches CatchClause
1344         optimizedConcatNodeLists();
1345 }
1346 protected void consumeCatchHeader() {
1347         // CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
1348
1349         if (currentElement == null){
1350                 return; // should never occur, this consumeRule is only used in recovery mode
1351         }
1352         // current element should be a block due to the presence of the opening brace
1353         if (!(currentElement instanceof RecoveredBlock)){
1354                 return;
1355         }
1356         // exception argument is already on astStack
1357         ((RecoveredBlock)currentElement).attach(
1358                 new RecoveredLocalVariable((Argument)astStack[astPtr--], currentElement, 0)); // insert catch variable in catch block
1359         lastCheckPoint = scanner.startPosition; // force to restart at this exact position
1360         restartRecovery = true; // request to restart from here on
1361         lastIgnoredToken = -1;
1362 }
1363 protected void consumeClassBodyDeclaration() {
1364         // ClassBodyDeclaration ::= Diet Block
1365         //push an Initializer
1366         //optimize the push/pop
1367         nestedMethod[nestedType]--;
1368         Initializer initializer = new Initializer((Block) astStack[astPtr], 0);
1369         intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
1370         realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
1371         int javadocCommentStart = intStack[intPtr--];
1372         if (javadocCommentStart != -1) {
1373                 initializer.declarationSourceStart = javadocCommentStart;
1374         }
1375         astStack[astPtr] = initializer;
1376         initializer.sourceEnd = endStatementPosition;
1377         initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
1378 }
1379 protected void consumeClassBodyDeclarations() {
1380         // ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
1381         concatNodeLists();
1382 }
1383 protected void consumeClassBodyDeclarationsopt() {
1384         // ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
1385         nestedType-- ;
1386 }
1387 protected void consumeClassBodyopt() {
1388         // ClassBodyopt ::= $empty
1389         pushOnAstStack(null);
1390         endPosition = scanner.startPosition - 1;
1391 }
1392 protected void consumeClassDeclaration() {
1393         // ClassDeclaration ::= ClassHeader ClassBody
1394
1395         int length;
1396         if ((length = astLengthStack[astLengthPtr--]) != 0) {
1397                 //there are length declarations
1398                 //dispatch according to the type of the declarations
1399                 dispatchDeclarationInto(length);
1400         }
1401
1402         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1403
1404         // mark fields and initializer with local type mark if needed
1405         markFieldsWithLocalType(typeDecl);
1406
1407         //convert constructor that do not have the type's name into methods
1408         boolean hasConstructor = typeDecl.checkConstructors(this);
1409         
1410         //add the default constructor when needed (interface don't have it)
1411         if (!hasConstructor) {
1412                 boolean insideFieldInitializer = false;
1413                 if (diet) {
1414                         for (int i = nestedType; i > 0; i--){
1415                                 if (variablesCounter[i] > 0) {
1416                                         insideFieldInitializer = true;
1417                                         break;
1418                                 }
1419                         }
1420                 }
1421                 typeDecl.createsInternalConstructor(!diet || insideFieldInitializer, true);
1422         }
1423
1424         //always add <clinit> (will be remove at code gen time if empty)
1425         if (this.scanner.containsAssertKeyword) {
1426                 typeDecl.bits |= AstNode.AddAssertionMASK;
1427         }
1428         typeDecl.addClinit();
1429         typeDecl.bodyEnd = endStatementPosition;
1430         typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 
1431 }
1432 protected void consumeClassHeader() {
1433         // ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
1434
1435         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];  
1436         if (currentToken == TokenNameLBRACE) { 
1437                 typeDecl.bodyStart = scanner.currentPosition;
1438         }
1439         if (currentElement != null) {
1440                 restartRecovery = true; // used to avoid branching back into the regular automaton              
1441         }
1442         // flush the comments related to the class header
1443         scanner.commentPtr = -1;
1444 }
1445 protected void consumeClassHeaderExtends() {
1446         // ClassHeaderExtends ::= 'extends' ClassType
1447         // There is a class declaration on the top of stack
1448         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1449         //superclass
1450         typeDecl.superclass = getTypeReference(0);
1451         typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
1452         // recovery
1453         if (currentElement != null){
1454                 lastCheckPoint = typeDecl.bodyStart;
1455         }
1456 }
1457 protected void consumeClassHeaderImplements() {
1458         // ClassHeaderImplements ::= 'implements' InterfaceTypeList
1459         int length = astLengthStack[astLengthPtr--];
1460         //super interfaces
1461         astPtr -= length;
1462         // There is a class declaration on the top of stack
1463         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
1464         System.arraycopy(
1465                 astStack, 
1466                 astPtr + 1, 
1467                 typeDecl.superInterfaces = new TypeReference[length], 
1468                 0, 
1469                 length); 
1470         typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
1471         listLength = 0; // reset after having read super-interfaces
1472         // recovery
1473         if (currentElement != null) { // is recovering
1474                 lastCheckPoint = typeDecl.bodyStart;
1475         }
1476 }
1477 protected void consumeClassHeaderName() {
1478         // ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
1479         TypeDeclaration typeDecl;
1480         if (nestedMethod[nestedType] == 0) {
1481                 if (nestedType != 0) {
1482                         typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
1483                 } else {
1484                         typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
1485                 }
1486         } else {
1487                 // Record that the block has a declaration for local types
1488                 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
1489                 markCurrentMethodWithLocalType();
1490                 blockReal();
1491         }
1492
1493         //highlight the name of the type
1494         long pos = identifierPositionStack[identifierPtr];
1495         typeDecl.sourceEnd = (int) pos;
1496         typeDecl.sourceStart = (int) (pos >>> 32);
1497         typeDecl.name = identifierStack[identifierPtr--];
1498         identifierLengthPtr--;
1499
1500         //compute the declaration source too
1501         // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
1502         // we want to keep the beginning position but get rid of the end position
1503         // it is only used for the ClassLiteralAccess positions.
1504         typeDecl.declarationSourceStart = intStack[intPtr--]; 
1505         intPtr--; // remove the end position of the class token
1506
1507         typeDecl.modifiersSourceStart = intStack[intPtr--];
1508         typeDecl.modifiers = intStack[intPtr--];
1509         if (typeDecl.modifiersSourceStart >= 0) {
1510                 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
1511         }
1512         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
1513         pushOnAstStack(typeDecl);
1514
1515         listLength = 0; // will be updated when reading super-interfaces
1516         // recovery
1517         if (currentElement != null){ 
1518                 lastCheckPoint = typeDecl.bodyStart;
1519                 currentElement = currentElement.add(typeDecl, 0);
1520                 lastIgnoredToken = -1;
1521         }
1522 }
1523 protected void consumeClassInstanceCreationExpression() {
1524         // ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
1525         classInstanceCreation(false);
1526 }
1527 protected void consumeClassInstanceCreationExpressionName() {
1528         // ClassInstanceCreationExpressionName ::= Name '.'
1529         pushOnExpressionStack(getUnspecifiedReferenceOptimized());
1530 }
1531 protected void consumeClassInstanceCreationExpressionQualified() {
1532         // ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1533         // ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
1534
1535         classInstanceCreation(true); //  <-- push the Qualifed....
1536
1537         expressionLengthPtr--;
1538         QualifiedAllocationExpression qae = 
1539                 (QualifiedAllocationExpression) expressionStack[expressionPtr--]; 
1540         qae.enclosingInstance = expressionStack[expressionPtr];
1541         expressionStack[expressionPtr] = qae;
1542         qae.sourceStart = qae.enclosingInstance.sourceStart;
1543 }
1544 protected void consumeClassTypeElt() {
1545         // ClassTypeElt ::= ClassType
1546         pushOnAstStack(getTypeReference(0));
1547         /* if incomplete thrown exception list, listLength counter will not have been reset,
1548                 indicating that some items are available on the stack */
1549         listLength++;   
1550 }
1551 protected void consumeClassTypeList() {
1552         // ClassTypeList ::= ClassTypeList ',' ClassTypeElt
1553         optimizedConcatNodeLists();
1554 }
1555 protected void consumeCompilationUnit() {
1556         // CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
1557         // do nothing by default
1558 }
1559 protected void consumeConditionalExpression(int op) {
1560         // ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
1561         //optimize the push/pop
1562
1563         expressionPtr -= 2;
1564         expressionLengthPtr -= 2;
1565         expressionStack[expressionPtr] =
1566                 new ConditionalExpression(
1567                         expressionStack[expressionPtr],
1568                         expressionStack[expressionPtr + 1],
1569                         expressionStack[expressionPtr + 2]);
1570 }
1571 protected void consumeConstructorBlockStatements() {
1572         // ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
1573         concatNodeLists(); // explictly add the first statement into the list of statements 
1574 }
1575 protected void consumeConstructorBody() {
1576         // ConstructorBody ::= NestedMethod  '{' BlockStatementsopt '}'
1577         // ConstructorBody ::= NestedMethod  '{' ExplicitConstructorInvocation '}'
1578         nestedMethod[nestedType] --;
1579 }
1580 protected void consumeConstructorDeclaration() {
1581         // ConstructorDeclaration ::= ConstructorHeader ConstructorBody
1582
1583         /*
1584         astStack : MethodDeclaration statements
1585         identifierStack : name
1586          ==>
1587         astStack : MethodDeclaration
1588         identifierStack :
1589         */
1590
1591         //must provide a default constructor call when needed
1592
1593         int length;
1594
1595         // pop the position of the {  (body of the method) pushed in block decl
1596         intPtr--;
1597
1598         //statements
1599         realBlockPtr--;
1600         ExplicitConstructorCall constructorCall = null;
1601         Statement[] statements = null;
1602         if ((length = astLengthStack[astLengthPtr--]) != 0) {
1603                 astPtr -= length;
1604                 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall) {
1605                         //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
1606                         System.arraycopy(
1607                                 astStack, 
1608                                 astPtr + 2, 
1609                                 statements = new Statement[length - 1], 
1610                                 0, 
1611                                 length - 1); 
1612                         constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
1613                 } else { //need to add explicitly the super();
1614                         System.arraycopy(
1615                                 astStack, 
1616                                 astPtr + 1, 
1617                                 statements = new Statement[length], 
1618                                 0, 
1619                                 length); 
1620                         constructorCall = SuperReference.implicitSuperConstructorCall();
1621                 }
1622         } else {
1623                 if (!diet){
1624                         // add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
1625                         constructorCall = SuperReference.implicitSuperConstructorCall();
1626                 }
1627         }
1628
1629         // now we know that the top of stack is a constructorDeclaration
1630         ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
1631         cd.constructorCall = constructorCall;
1632         cd.statements = statements;
1633
1634         //highlight of the implicit call on the method name
1635         if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
1636                 cd.constructorCall.sourceEnd = cd.sourceEnd;
1637                 cd.constructorCall.sourceStart = cd.sourceStart;
1638         }
1639
1640         //watch for } that could be given as a unicode ! ( u007D is '}' )
1641         // store the endPosition (position just before the '}') in case there is
1642         // a trailing comment behind the end of the method
1643         cd.bodyEnd = endPosition;
1644         cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 
1645 }
1646
1647 protected void consumeInvalidConstructorDeclaration() {
1648         // ConstructorDeclaration ::= ConstructorHeader ';'
1649         // now we know that the top of stack is a constructorDeclaration
1650         ConstructorDeclaration cd = (ConstructorDeclaration) astStack[astPtr];
1651
1652         cd.bodyEnd = endPosition; // position just before the trailing semi-colon
1653         cd.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 
1654         // report the problem and continue the parsing - narrowing the problem onto the method
1655 }
1656 protected void consumeConstructorHeader() {
1657         // ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
1658
1659         AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr];
1660
1661         if (currentToken == TokenNameLBRACE){ 
1662                 method.bodyStart = scanner.currentPosition;
1663         }
1664         // recovery
1665         if (currentElement != null){
1666                 restartRecovery = true; // used to avoid branching back into the regular automaton
1667         }               
1668 }
1669 protected void consumeConstructorHeaderName() {
1670
1671         /* recovering - might be an empty message send */
1672         if (currentElement != null){
1673                 if (lastIgnoredToken == TokenNamenew){ // was an allocation expression
1674                         lastCheckPoint = scanner.startPosition; // force to restart at this exact position                              
1675                         restartRecovery = true;
1676                         return;
1677                 }
1678         }
1679         
1680         // ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
1681         ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
1682
1683         //name -- this is not really revelant but we do .....
1684         cd.selector = identifierStack[identifierPtr];
1685         long selectorSource = identifierPositionStack[identifierPtr--];
1686         identifierLengthPtr--;
1687
1688         //modifiers
1689         cd.declarationSourceStart = intStack[intPtr--];
1690         cd.modifiers = intStack[intPtr--];
1691
1692         //highlight starts at the selector starts
1693         cd.sourceStart = (int) (selectorSource >>> 32);
1694         pushOnAstStack(cd);
1695         cd.sourceEnd = lParenPos;
1696         cd.bodyStart = lParenPos+1;
1697         listLength = 0; // initialize listLength before reading parameters/throws
1698
1699         // recovery
1700         if (currentElement != null){
1701                 lastCheckPoint = cd.bodyStart;
1702                 if ((currentElement instanceof RecoveredType && lastIgnoredToken != TokenNameDOT)
1703                         || cd.modifiers != 0){
1704                         currentElement = currentElement.add(cd, 0);
1705                         lastIgnoredToken = -1;
1706                 }
1707         }       
1708 }
1709 protected void consumeDefaultLabel() {
1710         // SwitchLabel ::= 'default' ':'
1711         pushOnAstStack(new DefaultCase(intStack[intPtr--], intStack[intPtr--]));
1712 }
1713 protected void consumeDefaultModifiers() {
1714         checkAnnotation(); // might update modifiers with AccDeprecated
1715         pushOnIntStack(modifiers); // modifiers
1716         pushOnIntStack(
1717                 modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition); 
1718         resetModifiers();
1719 }
1720 protected void consumeDiet() {
1721         // Diet ::= $empty
1722         checkAnnotation();
1723         pushOnIntStack(modifiersSourceStart); // push the start position of a javadoc comment if there is one
1724         jumpOverMethodBody();
1725 }
1726 protected void consumeDims() {
1727         // Dims ::= DimsLoop
1728         pushOnIntStack(dimensions);
1729         dimensions = 0;
1730 }
1731 protected void consumeDimWithOrWithOutExpr() {
1732         // DimWithOrWithOutExpr ::= '[' ']'
1733         pushOnExpressionStack(null);
1734 }
1735 protected void consumeDimWithOrWithOutExprs() {
1736         // DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
1737         concatExpressionLists();
1738 }
1739 protected void consumeEmptyArgumentListopt() {
1740         // ArgumentListopt ::= $empty
1741         pushOnExpressionStackLengthStack(0);
1742 }
1743 protected void consumeEmptyArrayInitializer() {
1744         // ArrayInitializer ::= '{' ,opt '}'
1745         arrayInitializer(0);
1746 }
1747 protected void consumeEmptyArrayInitializeropt() {
1748         // ArrayInitializeropt ::= $empty
1749         pushOnExpressionStackLengthStack(0);
1750 }
1751 protected void consumeEmptyBlockStatementsopt() {
1752         // BlockStatementsopt ::= $empty
1753         pushOnAstLengthStack(0);
1754 }
1755 protected void consumeEmptyCatchesopt() {
1756         // Catchesopt ::= $empty
1757         pushOnAstLengthStack(0);
1758 }
1759 protected void consumeEmptyClassBodyDeclarationsopt() {
1760         // ClassBodyDeclarationsopt ::= $empty
1761         pushOnAstLengthStack(0);
1762 }
1763 protected void consumeEmptyClassMemberDeclaration() {
1764         // ClassMemberDeclaration ::= ';'
1765         pushOnAstLengthStack(0);
1766 }
1767 protected void consumeEmptyDimsopt() {
1768         // Dimsopt ::= $empty
1769         pushOnIntStack(0);
1770 }
1771 protected void consumeEmptyExpression() {
1772         // Expressionopt ::= $empty
1773         pushOnExpressionStackLengthStack(0);
1774 }
1775 protected void consumeEmptyForInitopt() {
1776         // ForInitopt ::= $empty
1777         pushOnAstLengthStack(0);
1778 }
1779 protected void consumeEmptyForUpdateopt() {
1780         // ForUpdateopt ::= $empty
1781         pushOnExpressionStackLengthStack(0);
1782 }
1783 protected void consumeEmptyImportDeclarationsopt() {
1784         // ImportDeclarationsopt ::= $empty
1785         pushOnAstLengthStack(0);
1786 }
1787 protected void consumeEmptyInterfaceMemberDeclaration() {
1788         // InterfaceMemberDeclaration ::= ';'
1789         pushOnAstLengthStack(0);
1790 }
1791 protected void consumeEmptyInterfaceMemberDeclarationsopt() {
1792         // InterfaceMemberDeclarationsopt ::= $empty
1793         pushOnAstLengthStack(0);
1794 }
1795 protected void consumeEmptyStatement() {
1796         // EmptyStatement ::= ';'
1797         if (this.scanner.source[endStatementPosition] == ';') {
1798                 pushOnAstStack(new EmptyStatement(endStatementPosition, endStatementPosition));
1799         } else {
1800                 // we have a Unicode for the ';' (/u003B)
1801                 pushOnAstStack(new EmptyStatement(endStatementPosition - 5, endStatementPosition));
1802         }
1803 }
1804 protected void consumeEmptySwitchBlock() {
1805         // SwitchBlock ::= '{' '}'
1806         pushOnAstLengthStack(0);
1807 }
1808 protected void consumeEmptyTypeDeclaration() {
1809         // TypeDeclaration ::= ';' 
1810         pushOnAstLengthStack(0);
1811 }
1812 protected void consumeEmptyTypeDeclarationsopt() {
1813         // TypeDeclarationsopt ::= $empty
1814         pushOnAstLengthStack(0); 
1815 }
1816 protected void consumeEnterAnonymousClassBody() {
1817         // EnterAnonymousClassBody ::= $empty
1818         QualifiedAllocationExpression alloc;
1819         AnonymousLocalTypeDeclaration anonymousType = 
1820                 new AnonymousLocalTypeDeclaration(this.compilationUnit.compilationResult); 
1821         alloc = 
1822                 anonymousType.allocation = new QualifiedAllocationExpression(anonymousType); 
1823         markCurrentMethodWithLocalType();
1824         pushOnAstStack(anonymousType);
1825
1826         alloc.sourceEnd = rParenPos; //the position has been stored explicitly
1827         int argumentLength;
1828         if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
1829                 expressionPtr -= argumentLength;
1830                 System.arraycopy(
1831                         expressionStack, 
1832                         expressionPtr + 1, 
1833                         alloc.arguments = new Expression[argumentLength], 
1834                         0, 
1835                         argumentLength); 
1836         }
1837         alloc.type = getTypeReference(0);
1838
1839         anonymousType.sourceEnd = alloc.sourceEnd;
1840         //position at the type while it impacts the anonymous declaration
1841         anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
1842         alloc.sourceStart = intStack[intPtr--];
1843         pushOnExpressionStack(alloc);
1844
1845         anonymousType.bodyStart = scanner.currentPosition;      
1846         listLength = 0; // will be updated when reading super-interfaces
1847         // recovery
1848         if (currentElement != null){ 
1849                 lastCheckPoint = anonymousType.bodyStart;
1850                 // the recoveryTokenCheck will deal with the open brace         
1851                 currentElement = currentElement.add(anonymousType, 0);
1852                 currentToken = 0; // opening brace already taken into account
1853                 lastIgnoredToken = -1;
1854         }       
1855 }
1856 protected void consumeEnterCompilationUnit() {
1857         // EnterCompilationUnit ::= $empty
1858         // do nothing by default
1859 }
1860 protected void consumeEnterVariable() {
1861         // EnterVariable ::= $empty
1862         // do nothing by default
1863
1864         char[] name = identifierStack[identifierPtr];
1865         long namePosition = identifierPositionStack[identifierPtr];
1866         int extendedDimension = intStack[intPtr--];
1867         AbstractVariableDeclaration declaration;
1868         // create the ast node
1869         boolean isLocalDeclaration = nestedMethod[nestedType] != 0; 
1870         if (isLocalDeclaration) {
1871                 // create the local variable declarations
1872                 declaration = 
1873                         this.createLocalDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition);
1874         } else {
1875                 // create the field declaration
1876                 declaration = 
1877                         this.createFieldDeclaration(null, name, (int) (namePosition >>> 32), (int) namePosition); 
1878         }
1879         
1880         identifierPtr--;
1881         identifierLengthPtr--;
1882         TypeReference type;
1883         int variableIndex = variablesCounter[nestedType];
1884         int typeDim = 0;
1885         if (variableIndex == 0) {
1886                 // first variable of the declaration (FieldDeclaration or LocalDeclaration)
1887                 if (isLocalDeclaration) {
1888                         declaration.declarationSourceStart = intStack[intPtr--];
1889                         declaration.modifiers = intStack[intPtr--];
1890                         type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
1891                         if (declaration.declarationSourceStart == -1) {
1892                                 // this is true if there is no modifiers for the local variable declaration
1893                                 declaration.declarationSourceStart = type.sourceStart;
1894                         }
1895                         pushOnAstStack(type);
1896                 } else {
1897                         type = getTypeReference(typeDim = intStack[intPtr--]); // type dimension
1898                         pushOnAstStack(type);
1899                         declaration.declarationSourceStart = intStack[intPtr--];
1900                         declaration.modifiers = intStack[intPtr--];
1901                 }
1902         } else {
1903                 type = (TypeReference) astStack[astPtr - variableIndex];
1904                 typeDim = type.dimensions();
1905                 AbstractVariableDeclaration previousVariable = 
1906                         (AbstractVariableDeclaration) astStack[astPtr]; 
1907                 declaration.declarationSourceStart = previousVariable.declarationSourceStart;
1908                 declaration.modifiers = previousVariable.modifiers;
1909         }
1910
1911         if (extendedDimension == 0) {
1912                 declaration.type = type;
1913         } else {
1914                 int dimension = typeDim + extendedDimension;
1915                 //on the identifierLengthStack there is the information about the type....
1916                 int baseType;
1917                 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
1918                         //it was a baseType
1919                         int typeSourceStart = type.sourceStart;
1920                         int typeSourceEnd = type.sourceEnd;
1921                         type = TypeReference.baseTypeReference(-baseType, dimension);
1922                         type.sourceStart = typeSourceStart;
1923                         type.sourceEnd = typeSourceEnd;
1924                         declaration.type = type;
1925                 } else {
1926                         declaration.type = this.copyDims(type, dimension);
1927                 }
1928         }
1929         variablesCounter[nestedType]++;
1930         pushOnAstStack(declaration);
1931         // recovery
1932         if (currentElement != null) {
1933                 if (!(currentElement instanceof RecoveredType)
1934                         && (currentToken == TokenNameDOT
1935                                 //|| declaration.modifiers != 0
1936                                 || (scanner.getLineNumber(declaration.type.sourceStart)
1937                                                 != scanner.getLineNumber((int) (namePosition >>> 32))))){
1938                         lastCheckPoint = (int) (namePosition >>> 32);
1939                         restartRecovery = true;
1940                         return;
1941                 }
1942                 if (isLocalDeclaration){
1943                         LocalDeclaration localDecl = (LocalDeclaration) astStack[astPtr];
1944                         lastCheckPoint = localDecl.sourceEnd + 1;
1945                         currentElement = currentElement.add(localDecl, 0);
1946                 } else {
1947                         FieldDeclaration fieldDecl = (FieldDeclaration) astStack[astPtr];
1948                         lastCheckPoint = fieldDecl.sourceEnd + 1;
1949                         currentElement = currentElement.add(fieldDecl, 0);
1950                 }
1951                 lastIgnoredToken = -1;
1952         }
1953 }
1954 protected void consumeEqualityExpression(int op) {
1955         // EqualityExpression ::= EqualityExpression '==' RelationalExpression
1956         // EqualityExpression ::= EqualityExpression '!=' RelationalExpression
1957
1958         //optimize the push/pop
1959
1960         expressionPtr--;
1961         expressionLengthPtr--;
1962         expressionStack[expressionPtr] =
1963                 new EqualExpression(
1964                         expressionStack[expressionPtr],
1965                         expressionStack[expressionPtr + 1],
1966                         op);
1967 }
1968 protected void consumeExitVariableWithInitialization() {
1969         // ExitVariableWithInitialization ::= $empty
1970         // do nothing by default
1971         expressionLengthPtr--;
1972         AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) astStack[astPtr];
1973         variableDecl.initialization = expressionStack[expressionPtr--];
1974         // we need to update the declarationSourceEnd of the local variable declaration to the
1975         // source end position of the initialization expression
1976         variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
1977         variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
1978 }
1979 protected void consumeExitVariableWithoutInitialization() {
1980         // ExitVariableWithoutInitialization ::= $empty
1981         // do nothing by default
1982 }
1983 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
1984
1985         /* flag allows to distinguish 3 cases :
1986         (0) :   
1987         ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
1988         ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
1989         (1) :
1990         ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
1991         ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
1992         (2) :
1993         ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
1994         ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
1995         */
1996         int startPosition = intStack[intPtr--];
1997         ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
1998         int length;
1999         if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
2000                 expressionPtr -= length;
2001                 System.arraycopy(expressionStack, expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
2002         }
2003         switch (flag) {
2004                 case 0 :
2005                         ecc.sourceStart = startPosition;
2006                         break;
2007                 case 1 :
2008                         expressionLengthPtr--;
2009                         ecc.sourceStart = (ecc.qualification = expressionStack[expressionPtr--]).sourceStart;
2010                         break;
2011                 case 2 :
2012                         ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
2013                         break;
2014         };
2015         pushOnAstStack(ecc);
2016         ecc.sourceEnd = endPosition;
2017 }
2018 protected void consumeExpressionStatement() {
2019         // ExpressionStatement ::= StatementExpression ';'
2020         expressionLengthPtr--;
2021         pushOnAstStack(expressionStack[expressionPtr--]);
2022 }
2023 protected void consumeFieldAccess(boolean isSuperAccess) {
2024         // FieldAccess ::= Primary '.' 'Identifier'
2025         // FieldAccess ::= 'super' '.' 'Identifier'
2026
2027         FieldReference fr =
2028                 new FieldReference(
2029                         identifierStack[identifierPtr],
2030                         identifierPositionStack[identifierPtr--]);
2031         identifierLengthPtr--;
2032         if (isSuperAccess) {
2033                 //considerates the fieldReference beginning at the 'super' .... 
2034                 fr.sourceStart = intStack[intPtr--];
2035                 fr.receiver = new SuperReference(fr.sourceStart, endPosition);
2036                 pushOnExpressionStack(fr);
2037         } else {
2038                 //optimize push/pop
2039                 if ((fr.receiver = expressionStack[expressionPtr]).isThis()) {
2040                         //fieldreference begins at the this
2041                         fr.sourceStart = fr.receiver.sourceStart;
2042                 }
2043                 expressionStack[expressionPtr] = fr;
2044         }
2045 }
2046 protected void consumeFieldDeclaration() {
2047         // See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
2048         // FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
2049
2050         /*
2051         astStack : 
2052         expressionStack: Expression Expression ...... Expression
2053         identifierStack : type  identifier identifier ...... identifier
2054         intStack : typeDim      dim        dim               dim
2055          ==>
2056         astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2057         expressionStack :
2058         identifierStack : 
2059         intStack : 
2060           
2061         */
2062         int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2063
2064         for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
2065                 FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2066                 fieldDeclaration.declarationSourceEnd = endStatementPosition; 
2067                 fieldDeclaration.declarationEnd = endStatementPosition; // semi-colon included
2068         }
2069         updateSourceDeclarationParts(variableDeclaratorsCounter);
2070         int endPos = flushAnnotationsDefinedPriorTo(endStatementPosition);
2071         if (endPos != endStatementPosition) {
2072                 for (int i = 0; i < variableDeclaratorsCounter; i++) {
2073                         FieldDeclaration fieldDeclaration = (FieldDeclaration) astStack[astPtr - i];
2074                         fieldDeclaration.declarationSourceEnd = endPos;
2075                 }
2076         }
2077         // update the astStack, astPtr and astLengthStack
2078         int startIndex = astPtr - variablesCounter[nestedType] + 1;
2079         System.arraycopy(
2080                 astStack, 
2081                 startIndex, 
2082                 astStack, 
2083                 startIndex - 1, 
2084                 variableDeclaratorsCounter); 
2085         astPtr--; // remove the type reference
2086         astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2087
2088         // recovery
2089         if (currentElement != null) {
2090                 lastCheckPoint = endPos + 1;
2091                 if (currentElement.parent != null && currentElement instanceof RecoveredField){
2092                         currentElement = currentElement.parent;
2093                 }
2094                 restartRecovery = true;
2095         }
2096         variablesCounter[nestedType] = 0;
2097 }
2098 protected void consumeForceNoDiet() {
2099         // ForceNoDiet ::= $empty
2100         dietInt++;
2101 }
2102 protected void consumeForInit() {
2103         // ForInit ::= StatementExpressionList
2104         pushOnAstLengthStack(-1);
2105 }
2106 protected void consumeFormalParameter() {
2107         // FormalParameter ::= Type VariableDeclaratorId ==> false
2108         // FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
2109         /*
2110         astStack : 
2111         identifierStack : type identifier
2112         intStack : dim dim
2113          ==>
2114         astStack : Argument
2115         identifierStack :  
2116         intStack :  
2117         */
2118
2119         identifierLengthPtr--;
2120         char[] name = identifierStack[identifierPtr];
2121         long namePositions = identifierPositionStack[identifierPtr--];
2122         TypeReference type = getTypeReference(intStack[intPtr--] + intStack[intPtr--]);
2123         int modifierPositions = intStack[intPtr--];
2124         intPtr--;
2125         Argument arg = 
2126                 new Argument(
2127                         name, 
2128                         namePositions, 
2129                         type, 
2130                         intStack[intPtr + 1] & ~AccDeprecated); // modifiers
2131         arg.declarationSourceStart = modifierPositions;
2132         pushOnAstStack(arg);
2133
2134         /* if incomplete method header, listLength counter will not have been reset,
2135                 indicating that some arguments are available on the stack */
2136         listLength++;   
2137 }
2138 protected void consumeFormalParameterList() {
2139         // FormalParameterList ::= FormalParameterList ',' FormalParameter
2140         optimizedConcatNodeLists();
2141 }
2142 protected void consumeFormalParameterListopt() {
2143         // FormalParameterListopt ::= $empty
2144         pushOnAstLengthStack(0);
2145 }
2146 protected void consumeImportDeclarations() {
2147         // ImportDeclarations ::= ImportDeclarations ImportDeclaration 
2148         optimizedConcatNodeLists();
2149 }
2150 protected void consumeImportDeclarationsopt() {
2151         // ImportDeclarationsopt ::= ImportDeclarations
2152         int length;
2153         if ((length = astLengthStack[astLengthPtr--]) != 0) {
2154                 astPtr -= length;
2155                 System.arraycopy(
2156                         astStack,
2157                         astPtr + 1,
2158                         compilationUnit.imports = new ImportReference[length],
2159                         0,
2160                         length);
2161         }
2162 }
2163 protected void consumeInstanceOfExpression(int op) {
2164         // RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
2165         //optimize the push/pop
2166
2167         //by construction, no base type may be used in getTypeReference
2168         Expression exp;
2169         expressionStack[expressionPtr] = exp =
2170                 new InstanceOfExpression(
2171                         expressionStack[expressionPtr],
2172                         getTypeReference(intStack[intPtr--]),
2173                         op);
2174         if (exp.sourceEnd == 0) {
2175                 //array on base type....
2176                 exp.sourceEnd = scanner.startPosition - 1;
2177         }
2178         //the scanner is on the next token already....
2179 }
2180 protected void consumeInterfaceDeclaration() {
2181         // see consumeClassDeclaration in case of changes: duplicated code
2182         // InterfaceDeclaration ::= InterfaceHeader InterfaceBody
2183         int length;
2184         if ((length = astLengthStack[astLengthPtr--]) != 0) {
2185                 //there are length declarations
2186                 //dispatch.....according to the type of the declarations
2187                 dispatchDeclarationInto(length);
2188         }
2189
2190         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2191         
2192         // mark fields and initializer with local type mark if needed
2193         markFieldsWithLocalType(typeDecl);
2194
2195         //convert constructor that do not have the type's name into methods
2196         typeDecl.checkConstructors(this);
2197         
2198         //always add <clinit> (will be remove at code gen time if empty)
2199         if (this.scanner.containsAssertKeyword) {
2200                 typeDecl.bits |= AstNode.AddAssertionMASK;
2201         }
2202         typeDecl.addClinit();
2203         typeDecl.bodyEnd = endStatementPosition;
2204         typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 
2205 }
2206 protected void consumeInterfaceHeader() {
2207         // InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
2208
2209         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];  
2210         if (currentToken == TokenNameLBRACE){ 
2211                 typeDecl.bodyStart = scanner.currentPosition;
2212         }
2213         if (currentElement != null){
2214                 restartRecovery = true; // used to avoid branching back into the regular automaton              
2215         }
2216         // flush the comments related to the interface header
2217         scanner.commentPtr = -1;        
2218 }
2219 protected void consumeInterfaceHeaderExtends() {
2220         // InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
2221         int length = astLengthStack[astLengthPtr--];
2222         //super interfaces
2223         astPtr -= length;
2224         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
2225         System.arraycopy(
2226                 astStack, 
2227                 astPtr + 1, 
2228                 typeDecl.superInterfaces = new TypeReference[length], 
2229                 0, 
2230                 length); 
2231         typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;          
2232         listLength = 0; // reset after having read super-interfaces             
2233         // recovery
2234         if (currentElement != null) { 
2235                 lastCheckPoint = typeDecl.bodyStart;
2236         }
2237 }
2238 protected void consumeInterfaceHeaderName() {
2239         // InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
2240         TypeDeclaration typeDecl;
2241         if (nestedMethod[nestedType] == 0) {
2242                 if (nestedType != 0) {
2243                         typeDecl = new MemberTypeDeclaration(this.compilationUnit.compilationResult);
2244                 } else {
2245                         typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
2246                 }
2247         } else {
2248                 // Record that the block has a declaration for local types
2249                 typeDecl = new LocalTypeDeclaration(this.compilationUnit.compilationResult);
2250                 markCurrentMethodWithLocalType();
2251                 blockReal();
2252         }
2253
2254         //highlight the name of the type
2255         long pos = identifierPositionStack[identifierPtr];
2256         typeDecl.sourceEnd = (int) pos;
2257         typeDecl.sourceStart = (int) (pos >>> 32);
2258         typeDecl.name = identifierStack[identifierPtr--];
2259         identifierLengthPtr--;
2260
2261         //compute the declaration source too
2262         // 'class' and 'interface' push two int positions: the beginning of the class token and its end.
2263         // we want to keep the beginning position but get rid of the end position
2264         // it is only used for the ClassLiteralAccess positions.
2265         typeDecl.declarationSourceStart = intStack[intPtr--];
2266         intPtr--; // remove the end position of the class token
2267         typeDecl.modifiersSourceStart = intStack[intPtr--];
2268         typeDecl.modifiers = intStack[intPtr--];
2269         if (typeDecl.modifiersSourceStart >= 0) {
2270                 typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
2271         }
2272         typeDecl.bodyStart = typeDecl.sourceEnd + 1;
2273         pushOnAstStack(typeDecl);
2274         listLength = 0; // will be updated when reading super-interfaces
2275         // recovery
2276         if (currentElement != null){ // is recovering
2277                 lastCheckPoint = typeDecl.bodyStart;
2278                 currentElement = currentElement.add(typeDecl, 0);
2279                 lastIgnoredToken = -1;          
2280         }
2281 }
2282 protected void consumeInterfaceMemberDeclarations() {
2283         // InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
2284         concatNodeLists();
2285 }
2286 protected void consumeInterfaceMemberDeclarationsopt() {
2287         // InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
2288         nestedType--;
2289 }
2290 protected void consumeInterfaceType() {
2291         // InterfaceType ::= ClassOrInterfaceType
2292         pushOnAstStack(getTypeReference(0));
2293         /* if incomplete type header, listLength counter will not have been reset,
2294                 indicating that some interfaces are available on the stack */
2295         listLength++;   
2296 }
2297 protected void consumeInterfaceTypeList() {
2298         // InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
2299         optimizedConcatNodeLists();
2300 }
2301 protected void consumeLeftHandSide() {
2302         // LeftHandSide ::= Name
2303
2304         pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2305 }
2306 protected void consumeLeftParen() {
2307         // PushLPAREN ::= '('
2308         pushOnIntStack(lParenPos);
2309 }
2310 protected void consumeLocalVariableDeclaration() {
2311         // LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
2312
2313         /*
2314         astStack : 
2315         expressionStack: Expression Expression ...... Expression
2316         identifierStack : type  identifier identifier ...... identifier
2317         intStack : typeDim      dim        dim               dim
2318          ==>
2319         astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
2320         expressionStack :
2321         identifierStack : 
2322         intStack : 
2323           
2324         */
2325         int variableDeclaratorsCounter = astLengthStack[astLengthPtr];
2326
2327         // update the astStack, astPtr and astLengthStack
2328         int startIndex = astPtr - variablesCounter[nestedType] + 1;
2329         System.arraycopy(
2330                 astStack, 
2331                 startIndex, 
2332                 astStack, 
2333                 startIndex - 1, 
2334                 variableDeclaratorsCounter); 
2335         astPtr--; // remove the type reference
2336         astLengthStack[--astLengthPtr] = variableDeclaratorsCounter;
2337         variablesCounter[nestedType] = 0;
2338 }
2339 protected void consumeLocalVariableDeclarationStatement() {
2340         // LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
2341         // see blockReal in case of change: duplicated code
2342         // increment the amount of declared variables for this block
2343         realBlockStack[realBlockPtr]++;
2344 }
2345 protected void consumeMethodBody() {
2346         // MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
2347         nestedMethod[nestedType] --;
2348 }
2349 protected void consumeMethodDeclaration(boolean isNotAbstract) {
2350         // MethodDeclaration ::= MethodHeader MethodBody
2351         // AbstractMethodDeclaration ::= MethodHeader ';'
2352
2353         /*
2354         astStack : modifiers arguments throws statements
2355         identifierStack : type name
2356         intStack : dim dim dim
2357          ==>
2358         astStack : MethodDeclaration
2359         identifierStack :
2360         intStack : 
2361         */
2362
2363         int length;
2364         if (isNotAbstract) {
2365                 // pop the position of the {  (body of the method) pushed in block decl
2366                 intPtr--;
2367         }
2368
2369         int explicitDeclarations = 0;
2370         Statement[] statements = null;
2371         if (isNotAbstract) {
2372                 //statements
2373                 explicitDeclarations = realBlockStack[realBlockPtr--];
2374                 if ((length = astLengthStack[astLengthPtr--]) != 0)
2375                         System.arraycopy(
2376                                 astStack, 
2377                                 (astPtr -= length) + 1, 
2378                                 statements = new Statement[length], 
2379                                 0, 
2380                                 length); 
2381         }
2382
2383         // now we know that we have a method declaration at the top of the ast stack
2384         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2385         md.statements = statements;
2386         md.explicitDeclarations = explicitDeclarations;
2387
2388         // cannot be done in consumeMethodHeader because we have no idea whether or not there
2389         // is a body when we reduce the method header
2390         if (!isNotAbstract) { //remember the fact that the method has a semicolon body
2391                 md.modifiers |= AccSemicolonBody;
2392         }
2393         // store the endPosition (position just before the '}') in case there is
2394         // a trailing comment behind the end of the method
2395         md.bodyEnd = endPosition;
2396         md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
2397 }
2398 protected void consumeMethodHeader() {
2399         // MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
2400         // retrieve end position of method declarator
2401         AbstractMethodDeclaration method = (AbstractMethodDeclaration)astStack[astPtr];
2402
2403         if (currentToken == TokenNameLBRACE){ 
2404                 method.bodyStart = scanner.currentPosition;
2405         }
2406         // recovery
2407         if (currentElement != null){
2408                 if (currentToken == TokenNameSEMICOLON){
2409                         method.modifiers |= AccSemicolonBody;                   
2410                         method.declarationSourceEnd = scanner.currentPosition-1;
2411                         method.bodyEnd = scanner.currentPosition-1;
2412                         if (currentElement.parent != null){
2413                                 currentElement = currentElement.parent;
2414                         }
2415                 }               
2416                 restartRecovery = true; // used to avoid branching back into the regular automaton
2417         }               
2418 }
2419 protected void consumeMethodHeaderExtendedDims() {
2420         // MethodHeaderExtendedDims ::= Dimsopt
2421         // now we update the returnType of the method
2422         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
2423         int extendedDims = intStack[intPtr--];
2424         if (extendedDims != 0) {
2425                 TypeReference returnType = md.returnType;
2426                 md.sourceEnd = endPosition;
2427                 int dims = returnType.dimensions() + extendedDims;
2428                 int baseType;
2429                 if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
2430                         //it was a baseType
2431                         int sourceStart = returnType.sourceStart;
2432                         int sourceEnd =  returnType.sourceEnd;
2433                         returnType = TypeReference.baseTypeReference(-baseType, dims);
2434                         returnType.sourceStart = sourceStart;
2435                         returnType.sourceEnd = sourceEnd;
2436                         md.returnType = returnType;
2437                 } else {
2438                         md.returnType = this.copyDims(md.returnType, dims);
2439                 }
2440                 if (currentToken == TokenNameLBRACE){ 
2441                         md.bodyStart = endPosition + 1;
2442                 }
2443                 // recovery
2444                 if (currentElement != null){
2445                         lastCheckPoint = md.bodyStart;
2446                 }               
2447         }
2448 }
2449 protected void consumeMethodHeaderName() {
2450         // MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
2451         MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2452
2453         //name
2454         md.selector = identifierStack[identifierPtr];
2455         long selectorSource = identifierPositionStack[identifierPtr--];
2456         identifierLengthPtr--;
2457         //type
2458         md.returnType = getTypeReference(intStack[intPtr--]);
2459         //modifiers
2460         md.declarationSourceStart = intStack[intPtr--];
2461         md.modifiers = intStack[intPtr--];
2462
2463         //highlight starts at selector start
2464         md.sourceStart = (int) (selectorSource >>> 32);
2465         pushOnAstStack(md);
2466         md.sourceEnd = lParenPos;
2467         md.bodyStart = lParenPos+1;
2468         listLength = 0; // initialize listLength before reading parameters/throws
2469         
2470         // recovery
2471         if (currentElement != null){
2472                 if (currentElement instanceof RecoveredType 
2473                         //|| md.modifiers != 0
2474                         || (scanner.getLineNumber(md.returnType.sourceStart)
2475                                         == scanner.getLineNumber(md.sourceStart))){
2476                         lastCheckPoint = md.bodyStart;
2477                         currentElement = currentElement.add(md, 0);
2478                         lastIgnoredToken = -1;
2479                 } else {
2480                         lastCheckPoint = md.sourceStart;
2481                         restartRecovery = true;
2482                 }
2483         }               
2484 }
2485 protected void consumeMethodHeaderParameters() {
2486         // MethodHeaderParameters ::= FormalParameterListopt ')'
2487         int length = astLengthStack[astLengthPtr--];
2488         astPtr -= length;
2489         AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2490         md.sourceEnd =  rParenPos;
2491         //arguments
2492         if (length != 0) {
2493                 System.arraycopy(
2494                         astStack, 
2495                         astPtr + 1, 
2496                         md.arguments = new Argument[length], 
2497                         0, 
2498                         length); 
2499         }
2500         md.bodyStart = rParenPos+1;
2501         listLength = 0; // reset listLength after having read all parameters
2502         // recovery
2503         if (currentElement != null){
2504                 lastCheckPoint = md.bodyStart;
2505                 if (currentElement.parseTree() == md) return;
2506
2507                 // might not have been attached yet - in some constructor scenarii
2508                 if (md.isConstructor()){
2509                         if ((length != 0)
2510                                 || (currentToken == TokenNameLBRACE) 
2511                                 // || (currentToken == TokenNamethrows)
2512         ){
2513                                 currentElement = currentElement.add(md, 0);
2514                                 lastIgnoredToken = -1;
2515                         }       
2516                 }       
2517         }       
2518 }
2519 protected void consumeMethodHeaderThrowsClause() {
2520         // MethodHeaderThrowsClause ::= 'throws' ClassTypeList
2521         int length = astLengthStack[astLengthPtr--];
2522         astPtr -= length;
2523         AbstractMethodDeclaration md = (AbstractMethodDeclaration) astStack[astPtr];
2524         System.arraycopy(
2525                 astStack, 
2526                 astPtr + 1, 
2527                 md.thrownExceptions = new TypeReference[length], 
2528                 0, 
2529                 length);
2530         md.sourceEnd =  md.thrownExceptions[length-1].sourceEnd;
2531         md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1;
2532         listLength = 0; // reset listLength after having read all thrown exceptions     
2533         // recovery
2534         if (currentElement != null){
2535                 lastCheckPoint = md.bodyStart;
2536         }               
2537 }
2538 protected void consumeMethodInvocationName() {
2539         // MethodInvocation ::= Name '(' ArgumentListopt ')'
2540
2541         // when the name is only an identifier...we have a message send to "this" (implicit)
2542
2543         MessageSend m = newMessageSend();
2544         m.sourceEnd = rParenPos;
2545         m.sourceStart = 
2546                 (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32); 
2547         m.selector = identifierStack[identifierPtr--];
2548         if (identifierLengthStack[identifierLengthPtr] == 1) {
2549                 m.receiver = ThisReference.ThisImplicit;
2550                 identifierLengthPtr--;
2551         } else {
2552                 identifierLengthStack[identifierLengthPtr]--;
2553                 m.receiver = getUnspecifiedReference();
2554                 m.sourceStart = m.receiver.sourceStart;         
2555         }
2556         pushOnExpressionStack(m);
2557 }
2558 protected void consumeMethodInvocationPrimary() {
2559         //optimize the push/pop
2560         //MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
2561
2562         MessageSend m = newMessageSend();
2563         m.sourceStart = 
2564                 (int) ((m.nameSourcePosition = identifierPositionStack[identifierPtr]) >>> 32); 
2565         m.selector = identifierStack[identifierPtr--];
2566         identifierLengthPtr--;
2567         m.receiver = expressionStack[expressionPtr];
2568         m.sourceStart = m.receiver.sourceStart;
2569         m.sourceEnd = rParenPos;
2570         expressionStack[expressionPtr] = m;
2571 }
2572 protected void consumeMethodInvocationSuper() {
2573         // MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
2574
2575         MessageSend m = newMessageSend();
2576         m.sourceStart = intStack[intPtr--];
2577         m.sourceEnd = rParenPos;
2578         m.nameSourcePosition = identifierPositionStack[identifierPtr];
2579         m.selector = identifierStack[identifierPtr--];
2580         identifierLengthPtr--;
2581         m.receiver = new SuperReference(m.sourceStart, endPosition);
2582         pushOnExpressionStack(m);
2583 }
2584 protected void consumeMethodPushModifiersHeaderName() {
2585         // MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '('
2586         // MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '(' 
2587         MethodDeclaration md = new MethodDeclaration(this.compilationUnit.compilationResult);
2588
2589         //name
2590         md.selector = identifierStack[identifierPtr];
2591         long selectorSource = identifierPositionStack[identifierPtr--];
2592         identifierLengthPtr--;
2593
2594         //modifiers
2595         md.declarationSourceStart = intStack[intPtr--];
2596         md.modifiers = intStack[intPtr--];
2597
2598         //type
2599         md.returnType = getTypeReference(intStack[intPtr--]);
2600
2601         //highlight starts at selector start
2602         md.sourceStart = (int) (selectorSource >>> 32);
2603         pushOnAstStack(md);
2604         md.sourceEnd = lParenPos;
2605         md.bodyStart = lParenPos + 1;
2606         listLength = 0; // initialize listLength before reading parameters/throws
2607
2608         // recovery
2609         if (currentElement != null) {
2610                 lastCheckPoint = md.bodyStart;
2611                 currentElement = currentElement.add(md, 0);
2612                 lastIgnoredToken = -1;          
2613         }
2614 }
2615 protected void consumeModifiers() {
2616         int savedModifiersSourceStart = modifiersSourceStart;   
2617         checkAnnotation(); // might update modifiers with AccDeprecated
2618         pushOnIntStack(modifiers); // modifiers
2619         if (modifiersSourceStart >= savedModifiersSourceStart) {
2620                 modifiersSourceStart = savedModifiersSourceStart;
2621         }
2622         pushOnIntStack(modifiersSourceStart);
2623         resetModifiers();
2624 }
2625 protected void consumeNestedMethod() {
2626         // NestedMethod ::= $empty
2627         jumpOverMethodBody();
2628         nestedMethod[nestedType] ++;
2629         consumeOpenBlock();
2630 }
2631 protected void consumeNestedType() {
2632         // NestedType ::= $empty
2633         nestedType++;
2634         try {
2635                 nestedMethod[nestedType] = 0;
2636         } catch (IndexOutOfBoundsException e) {
2637                 //except in test's cases, it should never raise
2638                 int oldL = nestedMethod.length;
2639                 System.arraycopy(nestedMethod , 0, (nestedMethod = new int[oldL + 30]), 0, oldL);
2640                 nestedMethod[nestedType] = 0;
2641                 // increase the size of the fieldsCounter as well. It has to be consistent with the size of the nestedMethod collection
2642                 System.arraycopy(variablesCounter, 0, (variablesCounter = new int[oldL + 30]), 0, oldL);
2643         }
2644         variablesCounter[nestedType] = 0;
2645 }
2646 protected void consumeOneDimLoop() {
2647         // OneDimLoop ::= '[' ']'
2648         dimensions++;
2649 }
2650 protected void consumeOnlySynchronized() {
2651         // OnlySynchronized ::= 'synchronized'
2652         pushOnIntStack(this.synchronizedBlockSourceStart);
2653         resetModifiers();
2654 }
2655 protected void consumeOpenBlock() {
2656         // OpenBlock ::= $empty
2657
2658         pushOnIntStack(scanner.startPosition);
2659         try {
2660                 realBlockStack[++realBlockPtr] = 0;
2661         } catch (IndexOutOfBoundsException e) {
2662                 //realBlockPtr is correct 
2663                 int oldStackLength = realBlockStack.length;
2664                 int oldStack[] = realBlockStack;
2665                 realBlockStack = new int[oldStackLength + StackIncrement];
2666                 System.arraycopy(oldStack, 0, realBlockStack, 0, oldStackLength);
2667                 realBlockStack[realBlockPtr] = 0;
2668         }
2669 }
2670 protected void consumePackageDeclaration() {
2671         // PackageDeclaration ::= 'package' Name ';'
2672         /* build an ImportRef build from the last name 
2673         stored in the identifier stack. */
2674
2675         ImportReference impt = compilationUnit.currentPackage;
2676         // flush annotations defined prior to import statements
2677         impt.declarationEnd = endStatementPosition;
2678         impt.declarationSourceEnd = this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd);
2679 }
2680 protected void consumePackageDeclarationName() {
2681         // PackageDeclarationName ::= 'package' Name
2682         /* build an ImportRef build from the last name 
2683         stored in the identifier stack. */
2684
2685         ImportReference impt;
2686         int length;
2687         char[][] tokens = 
2688                 new char[length = identifierLengthStack[identifierLengthPtr--]][]; 
2689         identifierPtr -= length;
2690         long[] positions = new long[length];
2691         System.arraycopy(identifierStack, ++identifierPtr, tokens, 0, length);
2692         System.arraycopy(
2693                 identifierPositionStack, 
2694                 identifierPtr--, 
2695                 positions, 
2696                 0, 
2697                 length); 
2698         compilationUnit.currentPackage = 
2699                 impt = new ImportReference(tokens, positions, true); 
2700
2701         if (currentToken == TokenNameSEMICOLON){
2702                 impt.declarationSourceEnd = scanner.currentPosition - 1;
2703         } else {
2704                 impt.declarationSourceEnd = impt.sourceEnd;
2705         }
2706         impt.declarationEnd = impt.declarationSourceEnd;
2707         //endPosition is just before the ;
2708         impt.declarationSourceStart = intStack[intPtr--];
2709
2710         // recovery
2711         if (currentElement != null){
2712                 lastCheckPoint = impt.declarationSourceEnd+1;
2713                 restartRecovery = true; // used to avoid branching back into the regular automaton              
2714         }       
2715 }
2716 protected void consumePostfixExpression() {
2717         // PostfixExpression ::= Name
2718         pushOnExpressionStack(getUnspecifiedReferenceOptimized());
2719 }
2720 protected void consumePrimaryNoNewArray() {
2721         // PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN 
2722         updateSourcePosition(expressionStack[expressionPtr]);
2723 }
2724 protected void consumePrimaryNoNewArrayArrayType() {
2725         // PrimaryNoNewArray ::= ArrayType '.' 'class'
2726         intPtr--;
2727         pushOnExpressionStack(
2728                 new ClassLiteralAccess(intStack[intPtr--],
2729                 getTypeReference(intStack[intPtr--])));
2730 }
2731 protected void consumePrimaryNoNewArrayName() {
2732         // PrimaryNoNewArray ::= Name '.' 'class'
2733         intPtr--;
2734         pushOnExpressionStack(
2735                 new ClassLiteralAccess(intStack[intPtr--],
2736                 getTypeReference(0)));
2737 }
2738 protected void consumePrimaryNoNewArrayNameSuper() {
2739         // PrimaryNoNewArray ::= Name '.' 'super'
2740         pushOnExpressionStack(
2741                 new QualifiedSuperReference(
2742                         getTypeReference(0),
2743                         intStack[intPtr--],
2744                         endPosition));
2745 }
2746 protected void consumePrimaryNoNewArrayNameThis() {
2747         // PrimaryNoNewArray ::= Name '.' 'this'
2748         pushOnExpressionStack(
2749                 new QualifiedThisReference(
2750                         getTypeReference(0),
2751                         intStack[intPtr--],
2752                         endPosition));
2753 }
2754 protected void consumePrimaryNoNewArrayPrimitiveType() {
2755         // PrimaryNoNewArray ::= PrimitiveType '.' 'class'
2756         intPtr--;
2757         pushOnExpressionStack(
2758                 new ClassLiteralAccess(intStack[intPtr--],
2759                 getTypeReference(0)));
2760 }
2761 protected void consumePrimaryNoNewArrayThis() {
2762         // PrimaryNoNewArray ::= 'this'
2763         pushOnExpressionStack(new ThisReference(intStack[intPtr--], endPosition));
2764 }
2765 protected void consumePrimitiveType() {
2766         // Type ::= PrimitiveType
2767         pushOnIntStack(0);
2768 }
2769 protected void consumePushModifiers() {
2770         if ((modifiers & AccSynchronized) != 0) {
2771                  /* remove the starting position of the synchronized keyword
2772                   * we don't need it when synchronized is part of the modifiers
2773                   */
2774                 intPtr--;
2775         }
2776         pushOnIntStack(modifiers); // modifiers
2777         pushOnIntStack(modifiersSourceStart);
2778         resetModifiers();
2779 }
2780 protected void consumePushPosition() {
2781         // for source managment purpose
2782         // PushPosition ::= $empty
2783         pushOnIntStack(endPosition);
2784 }
2785 protected void consumeQualifiedName() {
2786         // QualifiedName ::= Name '.' SimpleName 
2787         /*back from the recursive loop of QualifiedName.
2788         Updates identifier length into the length stack*/
2789
2790         identifierLengthStack[--identifierLengthPtr]++;
2791 }
2792 protected void consumeReferenceType() {
2793         // ReferenceType ::= ClassOrInterfaceType
2794         pushOnIntStack(0);
2795 }
2796 protected void consumeRestoreDiet() {
2797         // RestoreDiet ::= $empty
2798         dietInt--;
2799 }
2800 protected void consumeRightParen() {
2801         // PushRPAREN ::= ')'
2802         pushOnIntStack(rParenPos);
2803 }
2804         // This method is part of an automatic generation : do NOT edit-modify  
2805          // This method is part of an automatic generation : do NOT edit-modify  
2806         protected void consumeRule(int act) {
2807           switch ( act ) {
2808             case 29 : // System.out.println("Type ::= PrimitiveType");
2809                             consumePrimitiveType();  
2810                                 break ;
2811          
2812             case 43 : // System.out.println("ReferenceType ::= ClassOrInterfaceType");
2813                             consumeReferenceType();   
2814                                 break ;
2815          
2816             case 52 : // System.out.println("QualifiedName ::= Name DOT SimpleName");
2817                             consumeQualifiedName();  
2818                                 break ;
2819          
2820             case 53 : // System.out.println("CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt");
2821                             consumeCompilationUnit();  
2822                                 break ;
2823          
2824             case 54 : // System.out.println("EnterCompilationUnit ::=");
2825                             consumeEnterCompilationUnit();  
2826                                 break ;
2827          
2828             case 66 : // System.out.println("CatchHeader ::= catch LPAREN FormalParameter RPAREN LBRACE");
2829                             consumeCatchHeader();  
2830                                 break ;
2831          
2832             case 68 : // System.out.println("ImportDeclarations ::= ImportDeclarations ImportDeclaration");
2833                             consumeImportDeclarations();  
2834                                 break ;
2835          
2836             case 70 : // System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration");
2837                             consumeTypeDeclarations();  
2838                                 break ;
2839          
2840             case 71 : // System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON");
2841                              consumePackageDeclaration();  
2842                                 break ;
2843          
2844             case 72 : // System.out.println("PackageDeclarationName ::= package Name");
2845                              consumePackageDeclarationName();  
2846                                 break ;
2847          
2848             case 75 : // System.out.println("SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName SEMICOLON");
2849                             consumeSingleTypeImportDeclaration();  
2850                                 break ;
2851          
2852             case 76 : // System.out.println("SingleTypeImportDeclarationName ::= import Name");
2853                             consumeSingleTypeImportDeclarationName();  
2854                                 break ;
2855          
2856             case 77 : // System.out.println("TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName SEMICOLON");
2857                             consumeTypeImportOnDemandDeclaration();  
2858                                 break ;
2859          
2860             case 78 : // System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT MULTIPLY");
2861                             consumeTypeImportOnDemandDeclarationName();  
2862                                 break ;
2863          
2864              case 81 : // System.out.println("TypeDeclaration ::= SEMICOLON");
2865                             consumeEmptyTypeDeclaration();  
2866                                 break ;
2867          
2868             case 95 : // System.out.println("ClassDeclaration ::= ClassHeader ClassBody");
2869                             consumeClassDeclaration();  
2870                                 break ;
2871          
2872             case 96 : // System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt");
2873                             consumeClassHeader();  
2874                                 break ;
2875          
2876             case 97 : // System.out.println("ClassHeaderName ::= Modifiersopt class Identifier");
2877                             consumeClassHeaderName();  
2878                                 break ;
2879          
2880             case 98 : // System.out.println("ClassHeaderExtends ::= extends ClassType");
2881                             consumeClassHeaderExtends();  
2882                                 break ;
2883          
2884             case 99 : // System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList");
2885                             consumeClassHeaderImplements();  
2886                                 break ;
2887          
2888             case 101 : // System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA InterfaceType");
2889                             consumeInterfaceTypeList();  
2890                                 break ;
2891          
2892             case 102 : // System.out.println("InterfaceType ::= ClassOrInterfaceType");
2893                             consumeInterfaceType();  
2894                                 break ;
2895          
2896             case 105 : // System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration");
2897                             consumeClassBodyDeclarations();  
2898                                 break ;
2899          
2900             case 109 : // System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block");
2901                             consumeClassBodyDeclaration();  
2902                                 break ;
2903          
2904             case 110 : // System.out.println("Diet ::=");
2905                             consumeDiet();  
2906                                 break ;
2907         
2908             case 111 : // System.out.println("Initializer ::= Diet NestedMethod Block");
2909                             consumeClassBodyDeclaration();  
2910                                 break ;
2911          
2912             case 118 : // System.out.println("ClassMemberDeclaration ::= SEMICOLON");
2913                             consumeEmptyClassMemberDeclaration();  
2914                                 break ;
2915         
2916             case 119 : // System.out.println("FieldDeclaration ::= Modifiersopt Type VariableDeclarators SEMICOLON");
2917                             consumeFieldDeclaration();  
2918                                 break ;
2919          
2920             case 121 : // System.out.println("VariableDeclarators ::= VariableDeclarators COMMA VariableDeclarator");
2921                             consumeVariableDeclarators();  
2922                                 break ;
2923          
2924             case 124 : // System.out.println("EnterVariable ::=");
2925                             consumeEnterVariable();  
2926                                 break ;
2927          
2928             case 125 : // System.out.println("ExitVariableWithInitialization ::=");
2929                             consumeExitVariableWithInitialization();  
2930                                 break ;
2931          
2932             case 126 : // System.out.println("ExitVariableWithoutInitialization ::=");
2933                             consumeExitVariableWithoutInitialization();  
2934                                 break ;
2935          
2936             case 127 : // System.out.println("ForceNoDiet ::=");
2937                             consumeForceNoDiet();  
2938                                 break ;
2939          
2940             case 128 : // System.out.println("RestoreDiet ::=");
2941                             consumeRestoreDiet();  
2942                                 break ;
2943          
2944             case 133 : // System.out.println("MethodDeclaration ::= MethodHeader MethodBody");
2945                             // set to true to consume a method with a body
2946           consumeMethodDeclaration(true);   
2947                                 break ;
2948          
2949             case 134 : // System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON");
2950                             // set to false to consume a method without body
2951           consumeMethodDeclaration(false);  
2952                                 break ;
2953          
2954             case 135 : // System.out.println("MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims");
2955                             consumeMethodHeader();  
2956                                 break ;
2957          
2958             case 136 : // System.out.println("MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters");
2959                             consumeMethodHeader();  
2960                                 break ;
2961          
2962             case 137 : // System.out.println("MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers Identifier LPAREN");
2963                             consumeMethodPushModifiersHeaderName();  
2964                                 break ;
2965          
2966             case 138 : // System.out.println("MethodPushModifiersHeaderName ::= Type PushModifiers Identifier LPAREN");
2967                             consumeMethodPushModifiersHeaderName();  
2968                                 break ;
2969          
2970             case 139 : // System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN");
2971                             consumeMethodHeaderName();  
2972                                 break ;
2973          
2974             case 140 : // System.out.println("MethodHeaderParameters ::= FormalParameterListopt RPAREN");
2975                             consumeMethodHeaderParameters();  
2976                                 break ;
2977          
2978             case 141 : // System.out.println("MethodHeaderExtendedDims ::= Dimsopt");
2979                             consumeMethodHeaderExtendedDims();  
2980                                 break ;
2981          
2982             case 142 : // System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList");
2983                             consumeMethodHeaderThrowsClause();  
2984                                 break ;
2985          
2986             case 143 : // System.out.println("ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters...");
2987                             consumeConstructorHeader();  
2988                                 break ;
2989          
2990             case 144 : // System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN");
2991                             consumeConstructorHeaderName();  
2992                                 break ;
2993          
2994             case 146 : // System.out.println("FormalParameterList ::= FormalParameterList COMMA FormalParameter");
2995                             consumeFormalParameterList();  
2996                                 break ;
2997          
2998             case 147 : // System.out.println("FormalParameter ::= Modifiersopt Type VariableDeclaratorId");
2999                             // the boolean is used to know if the modifiers should be reset
3000                 consumeFormalParameter();  
3001                                 break ;
3002          
3003             case 149 : // System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt");
3004                             consumeClassTypeList();  
3005                                 break ;
3006          
3007             case 150 : // System.out.println("ClassTypeElt ::= ClassType");
3008                             consumeClassTypeElt();  
3009                                 break ;
3010          
3011             case 151 : // System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt RBRACE");
3012                             consumeMethodBody();  
3013                                 break ;
3014          
3015             case 152 : // System.out.println("NestedMethod ::=");
3016                             consumeNestedMethod();  
3017                                 break ;
3018          
3019             case 153 : // System.out.println("StaticInitializer ::= StaticOnly Block");
3020                             consumeStaticInitializer();  
3021                                 break ;
3022         
3023             case 154 : // System.out.println("StaticOnly ::= static");
3024                             consumeStaticOnly();  
3025                                 break ;
3026          
3027             case 155 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3028                             consumeConstructorDeclaration() ;  
3029                                 break ;
3030          
3031             case 156 : // System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3032                             consumeInvalidConstructorDeclaration() ;  
3033                                 break ;
3034          
3035             case 157 : // System.out.println("ConstructorBody ::= NestedMethod LBRACE ConstructorBlockStatementsopt RBRACE");
3036                             consumeConstructorBody();  
3037                                 break ;
3038          
3039             case 160 : // System.out.println("ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements");
3040                              consumeConstructorBlockStatements();  
3041                                 break ;
3042          
3043             case 161 : // System.out.println("ExplicitConstructorInvocation ::= this LPAREN ArgumentListopt RPAREN SEMICOLON");
3044                             consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This);  
3045                                 break ;
3046          
3047             case 162 : // System.out.println("ExplicitConstructorInvocation ::= super LPAREN ArgumentListopt RPAREN SEMICOLON");
3048                             consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super);  
3049                                 break ;
3050          
3051             case 163 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT super LPAREN ArgumentListopt RPAREN");
3052                             consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super);  
3053                                 break ;
3054          
3055             case 164 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN ArgumentListopt RPAREN...");
3056                             consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super);  
3057                                 break ;
3058          
3059             case 165 : // System.out.println("ExplicitConstructorInvocation ::= Primary DOT this LPAREN ArgumentListopt RPAREN...");
3060                             consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This);  
3061                                 break ;
3062          
3063             case 166 : // System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN ArgumentListopt RPAREN...");
3064                             consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This);  
3065                                 break ;
3066          
3067             case 167 : // System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody");
3068                             consumeInterfaceDeclaration();  
3069                                 break ;
3070          
3071             case 168 : // System.out.println("InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt");
3072                             consumeInterfaceHeader();  
3073                                 break ;
3074          
3075             case 169 : // System.out.println("InterfaceHeaderName ::= Modifiersopt interface Identifier");
3076                             consumeInterfaceHeaderName();  
3077                                 break ;
3078          
3079             case 171 : // System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList");
3080                             consumeInterfaceHeaderExtends();  
3081                                 break ;
3082          
3083             case 174 : // System.out.println("InterfaceMemberDeclarations ::= InterfaceMemberDeclarations...");
3084                             consumeInterfaceMemberDeclarations();  
3085                                 break ;
3086          
3087             case 175 : // System.out.println("InterfaceMemberDeclaration ::= SEMICOLON");
3088                             consumeEmptyInterfaceMemberDeclaration();  
3089                                 break ;
3090          
3091             case 178 : // System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration");
3092                             ignoreMethodBody();  
3093                                 break ;
3094          
3095             case 179 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody");
3096                             ignoreInvalidConstructorDeclaration(true);   
3097                                 break ;
3098          
3099             case 180 : // System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader SEMICOLON");
3100                             ignoreInvalidConstructorDeclaration(false);   
3101                                 break ;
3102          
3103             case 186 : // System.out.println("ArrayInitializer ::= LBRACE ,opt RBRACE");
3104                             consumeEmptyArrayInitializer();  
3105                                 break ;
3106          
3107             case 187 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers RBRACE");
3108                             consumeArrayInitializer();  
3109                                 break ;
3110          
3111             case 188 : // System.out.println("ArrayInitializer ::= LBRACE VariableInitializers COMMA RBRACE");
3112                             consumeArrayInitializer();  
3113                                 break ;
3114          
3115             case 190 : // System.out.println("VariableInitializers ::= VariableInitializers COMMA VariableInitializer");
3116                             consumeVariableInitializers();  
3117                                 break ;
3118          
3119             case 191 : // System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE");
3120                             consumeBlock();  
3121                                 break ;
3122          
3123             case 192 : // System.out.println("OpenBlock ::=");
3124                             consumeOpenBlock() ;  
3125                                 break ;
3126          
3127             case 194 : // System.out.println("BlockStatements ::= BlockStatements BlockStatement");
3128                             consumeBlockStatements() ;  
3129                                 break ;
3130          
3131             case 198 : // System.out.println("BlockStatement ::= InvalidInterfaceDeclaration");
3132                             ignoreInterfaceDeclaration();  
3133                                 break ;
3134          
3135             case 199 : // System.out.println("LocalVariableDeclarationStatement ::= LocalVariableDeclaration SEMICOLON");
3136                             consumeLocalVariableDeclarationStatement();  
3137                                 break ;
3138          
3139             case 200 : // System.out.println("LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators");
3140                             consumeLocalVariableDeclaration();  
3141                                 break ;
3142          
3143             case 201 : // System.out.println("LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators");
3144                             consumeLocalVariableDeclaration();  
3145                                 break ;
3146          
3147             case 202 : // System.out.println("PushModifiers ::=");
3148                             consumePushModifiers();  
3149                                 break ;
3150          
3151             case 226 : // System.out.println("EmptyStatement ::= SEMICOLON");
3152                             consumeEmptyStatement();  
3153                                 break ;
3154          
3155             case 227 : // System.out.println("LabeledStatement ::= Identifier COLON Statement");
3156                             consumeStatementLabel() ;  
3157                                 break ;
3158          
3159             case 228 : // System.out.println("LabeledStatementNoShortIf ::= Identifier COLON StatementNoShortIf");
3160                             consumeStatementLabel() ;  
3161                                 break ;
3162          
3163              case 229 : // System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON");
3164                             consumeExpressionStatement();  
3165                                 break ;
3166          
3167             case 237 : // System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN Statement");
3168                             consumeStatementIfNoElse();  
3169                                 break ;
3170          
3171             case 238 : // System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN StatementNoShortIf else...");
3172                             consumeStatementIfWithElse();  
3173                                 break ;
3174          
3175             case 239 : // System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression RPAREN StatementNoShortIf...");
3176                             consumeStatementIfWithElse();  
3177                                 break ;
3178          
3179             case 240 : // System.out.println("SwitchStatement ::= switch OpenBlock LPAREN Expression RPAREN SwitchBlock");
3180                             consumeStatementSwitch() ;  
3181                                 break ;
3182          
3183             case 241 : // System.out.println("SwitchBlock ::= LBRACE RBRACE");
3184                             consumeEmptySwitchBlock() ;  
3185                                 break ;
3186          
3187             case 244 : // System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements SwitchLabels RBRACE");
3188                             consumeSwitchBlock() ;  
3189                                 break ;
3190          
3191             case 246 : // System.out.println("SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement");
3192                             consumeSwitchBlockStatements() ;  
3193                                 break ;
3194          
3195             case 247 : // System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements");
3196                             consumeSwitchBlockStatement() ;  
3197                                 break ;
3198          
3199             case 249 : // System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel");
3200                             consumeSwitchLabels() ;  
3201                                 break ;
3202          
3203              case 250 : // System.out.println("SwitchLabel ::= case ConstantExpression COLON");
3204                             consumeCaseLabel();  
3205                                 break ;
3206          
3207              case 251 : // System.out.println("SwitchLabel ::= default COLON");
3208                             consumeDefaultLabel();  
3209                                 break ;
3210          
3211             case 252 : // System.out.println("WhileStatement ::= while LPAREN Expression RPAREN Statement");
3212                             consumeStatementWhile() ;  
3213                                 break ;
3214          
3215             case 253 : // System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression RPAREN StatementNoShortIf");
3216                             consumeStatementWhile() ;  
3217                                 break ;
3218          
3219             case 254 : // System.out.println("DoStatement ::= do Statement while LPAREN Expression RPAREN SEMICOLON");
3220                             consumeStatementDo() ;  
3221                                 break ;
3222          
3223             case 255 : // System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON...");
3224                             consumeStatementFor() ;  
3225                                 break ;
3226          
3227             case 256 : // System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt SEMICOLON Expressionopt SEMICOLON");
3228                             consumeStatementFor() ;  
3229                                 break ;
3230          
3231             case 257 : // System.out.println("ForInit ::= StatementExpressionList");
3232                             consumeForInit() ;  
3233                                 break ;
3234          
3235             case 261 : // System.out.println("StatementExpressionList ::= StatementExpressionList COMMA StatementExpression");
3236                             consumeStatementExpressionList() ;  
3237                                 break ;
3238          
3239             case 262 : // System.out.println("AssertStatement ::= assert Expression SEMICOLON");
3240                             consumeSimpleAssertStatement() ;  
3241                                 break ;
3242          
3243             case 263 : // System.out.println("AssertStatement ::= assert Expression COLON Expression SEMICOLON");
3244                             consumeAssertStatement() ;  
3245                                 break ;
3246          
3247             case 264 : // System.out.println("BreakStatement ::= break SEMICOLON");
3248                             consumeStatementBreak() ;  
3249                                 break ;
3250          
3251             case 265 : // System.out.println("BreakStatement ::= break Identifier SEMICOLON");
3252                             consumeStatementBreakWithLabel() ;  
3253                                 break ;
3254          
3255             case 266 : // System.out.println("ContinueStatement ::= continue SEMICOLON");
3256                             consumeStatementContinue() ;  
3257                                 break ;
3258          
3259             case 267 : // System.out.println("ContinueStatement ::= continue Identifier SEMICOLON");
3260                             consumeStatementContinueWithLabel() ;  
3261                                 break ;
3262          
3263             case 268 : // System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON");
3264                             consumeStatementReturn() ;  
3265                                 break ;
3266          
3267             case 269 : // System.out.println("ThrowStatement ::= throw Expression SEMICOLON");
3268                             consumeStatementThrow();
3269          
3270                                 break ;
3271          
3272             case 270 : // System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN Expression RPAREN Block");
3273                             consumeStatementSynchronized();  
3274                                 break ;
3275          
3276             case 271 : // System.out.println("OnlySynchronized ::= synchronized");
3277                             consumeOnlySynchronized();  
3278                                 break ;
3279          
3280             case 272 : // System.out.println("TryStatement ::= try Block Catches");
3281                             consumeStatementTry(false);  
3282                                 break ;
3283          
3284             case 273 : // System.out.println("TryStatement ::= try Block Catchesopt Finally");
3285                             consumeStatementTry(true);  
3286                                 break ;
3287          
3288             case 275 : // System.out.println("Catches ::= Catches CatchClause");
3289                             consumeCatches();  
3290                                 break ;
3291          
3292             case 276 : // System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN Block");
3293                             consumeStatementCatch() ;  
3294                                 break ;
3295          
3296             case 278 : // System.out.println("PushLPAREN ::= LPAREN");
3297                             consumeLeftParen();  
3298                                 break ;
3299          
3300             case 279 : // System.out.println("PushRPAREN ::= RPAREN");
3301                             consumeRightParen();  
3302                                 break ;
3303          
3304             case 283 : // System.out.println("PrimaryNoNewArray ::= this");
3305                             consumePrimaryNoNewArrayThis();  
3306                                 break ;
3307          
3308             case 284 : // System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression PushRPAREN");
3309                             consumePrimaryNoNewArray();  
3310                                 break ;
3311          
3312             case 287 : // System.out.println("PrimaryNoNewArray ::= Name DOT this");
3313                             consumePrimaryNoNewArrayNameThis();  
3314                                 break ;
3315          
3316             case 288 : // System.out.println("PrimaryNoNewArray ::= Name DOT super");
3317                             consumePrimaryNoNewArrayNameSuper();  
3318                                 break ;
3319          
3320             case 289 : // System.out.println("PrimaryNoNewArray ::= Name DOT class");
3321                             consumePrimaryNoNewArrayName();  
3322                                 break ;
3323          
3324             case 290 : // System.out.println("PrimaryNoNewArray ::= ArrayType DOT class");
3325                             consumePrimaryNoNewArrayArrayType();  
3326                                 break ;
3327          
3328             case 291 : // System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class");
3329                             consumePrimaryNoNewArrayPrimitiveType();  
3330                                 break ;
3331          
3332             case 294 : // System.out.println("AllocationHeader ::= new ClassType LPAREN ArgumentListopt RPAREN");
3333                             consumeAllocationHeader();  
3334                                 break ;
3335          
3336             case 295 : // System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN ArgumentListopt RPAREN...");
3337                             consumeClassInstanceCreationExpression();  
3338                                 break ;
3339          
3340             case 296 : // System.out.println("ClassInstanceCreationExpression ::= Primary DOT new SimpleName LPAREN...");
3341                             consumeClassInstanceCreationExpressionQualified() ;  
3342                                 break ;
3343          
3344             case 297 : // System.out.println("ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName new...");
3345                             consumeClassInstanceCreationExpressionQualified() ;  
3346                                 break ;
3347          
3348             case 298 : // System.out.println("ClassInstanceCreationExpressionName ::= Name DOT");
3349                             consumeClassInstanceCreationExpressionName() ;  
3350                                 break ;
3351          
3352             case 299 : // System.out.println("ClassBodyopt ::=");
3353                             consumeClassBodyopt();  
3354                                 break ;
3355          
3356             case 301 : // System.out.println("EnterAnonymousClassBody ::=");
3357                             consumeEnterAnonymousClassBody();  
3358                                 break ;
3359          
3360             case 303 : // System.out.println("ArgumentList ::= ArgumentList COMMA Expression");
3361                             consumeArgumentList();  
3362                                 break ;
3363          
3364             case 304 : // System.out.println("ArrayCreationExpression ::= new PrimitiveType DimWithOrWithOutExprs...");
3365                             consumeArrayCreationExpression();  
3366                                 break ;
3367          
3368             case 305 : // System.out.println("ArrayCreationExpression ::= new ClassOrInterfaceType DimWithOrWithOutExprs...");
3369                             consumeArrayCreationExpression();  
3370                                 break ;
3371          
3372             case 307 : // System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr");
3373                             consumeDimWithOrWithOutExprs();  
3374                                 break ;
3375          
3376              case 309 : // System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET");
3377                             consumeDimWithOrWithOutExpr();  
3378                                 break ;
3379          
3380              case 310 : // System.out.println("Dims ::= DimsLoop");
3381                             consumeDims();  
3382                                 break ;
3383          
3384              case 313 : // System.out.println("OneDimLoop ::= LBRACKET RBRACKET");
3385                             consumeOneDimLoop();  
3386                                 break ;
3387          
3388             case 314 : // System.out.println("FieldAccess ::= Primary DOT Identifier");
3389                             consumeFieldAccess(false);  
3390                                 break ;
3391          
3392             case 315 : // System.out.println("FieldAccess ::= super DOT Identifier");
3393                             consumeFieldAccess(true);  
3394                                 break ;
3395          
3396             case 316 : // System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN");
3397                             consumeMethodInvocationName();  
3398                                 break ;
3399          
3400             case 317 : // System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN ArgumentListopt RPAREN");
3401                             consumeMethodInvocationPrimary();  
3402                                 break ;
3403          
3404             case 318 : // System.out.println("MethodInvocation ::= super DOT Identifier LPAREN ArgumentListopt RPAREN");
3405                             consumeMethodInvocationSuper();  
3406                                 break ;
3407          
3408             case 319 : // System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET");
3409                             consumeArrayAccess(true);  
3410                                 break ;
3411          
3412             case 320 : // System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression RBRACKET");
3413                             consumeArrayAccess(false);  
3414                                 break ;
3415          
3416             case 322 : // System.out.println("PostfixExpression ::= Name");
3417                             consumePostfixExpression();  
3418                                 break ;
3419          
3420             case 325 : // System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS");
3421                             consumeUnaryExpression(OperatorExpression.PLUS,true);  
3422                                 break ;
3423          
3424             case 326 : // System.out.println("PostDecrementExpression ::= PostfixExpression MINUS_MINUS");
3425                             consumeUnaryExpression(OperatorExpression.MINUS,true);  
3426                                 break ;
3427          
3428             case 327 : // System.out.println("PushPosition ::=");
3429                             consumePushPosition();  
3430                                 break ;
3431          
3432             case 330 : // System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression");
3433                             consumeUnaryExpression(OperatorExpression.PLUS);  
3434                                 break ;
3435          
3436             case 331 : // System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression");
3437                             consumeUnaryExpression(OperatorExpression.MINUS);  
3438                                 break ;
3439          
3440             case 333 : // System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition UnaryExpression");
3441                             consumeUnaryExpression(OperatorExpression.PLUS,false);  
3442                                 break ;
3443          
3444             case 334 : // System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition UnaryExpression");
3445                             consumeUnaryExpression(OperatorExpression.MINUS,false);  
3446                                 break ;
3447          
3448             case 336 : // System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition UnaryExpression");
3449                             consumeUnaryExpression(OperatorExpression.TWIDDLE);  
3450                                 break ;
3451          
3452             case 337 : // System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition UnaryExpression");
3453                             consumeUnaryExpression(OperatorExpression.NOT);  
3454                                 break ;
3455          
3456             case 339 : // System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression");
3457                             consumeCastExpression();  
3458                                 break ;
3459          
3460             case 340 : // System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus");
3461                             consumeCastExpression();  
3462                                 break ;
3463          
3464             case 341 : // System.out.println("CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus");
3465                             consumeCastExpressionLL1();  
3466                                 break ;
3467          
3468             case 343 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression MULTIPLY UnaryExpression");
3469                             consumeBinaryExpression(OperatorExpression.MULTIPLY);  
3470                                 break ;
3471          
3472             case 344 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression DIVIDE UnaryExpression");
3473                             consumeBinaryExpression(OperatorExpression.DIVIDE);  
3474                                 break ;
3475          
3476             case 345 : // System.out.println("MultiplicativeExpression ::= MultiplicativeExpression REMAINDER UnaryExpression");
3477                             consumeBinaryExpression(OperatorExpression.REMAINDER);  
3478                                 break ;
3479          
3480             case 347 : // System.out.println("AdditiveExpression ::= AdditiveExpression PLUS MultiplicativeExpression");
3481                             consumeBinaryExpression(OperatorExpression.PLUS);  
3482                                 break ;
3483          
3484             case 348 : // System.out.println("AdditiveExpression ::= AdditiveExpression MINUS MultiplicativeExpression");
3485                             consumeBinaryExpression(OperatorExpression.MINUS);  
3486                                 break ;
3487          
3488             case 350 : // System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT AdditiveExpression");
3489                             consumeBinaryExpression(OperatorExpression.LEFT_SHIFT);  
3490                                 break ;
3491          
3492             case 351 : // System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT AdditiveExpression");
3493                             consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT);  
3494                                 break ;
3495          
3496             case 352 : // System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT AdditiveExpression");
3497                             consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT);  
3498                                 break ;
3499          
3500             case 354 : // System.out.println("RelationalExpression ::= RelationalExpression LESS ShiftExpression");
3501                             consumeBinaryExpression(OperatorExpression.LESS);  
3502                                 break ;
3503          
3504             case 355 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER ShiftExpression");
3505                             consumeBinaryExpression(OperatorExpression.GREATER);  
3506                                 break ;
3507          
3508             case 356 : // System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL ShiftExpression");
3509                             consumeBinaryExpression(OperatorExpression.LESS_EQUAL);  
3510                                 break ;
3511          
3512             case 357 : // System.out.println("RelationalExpression ::= RelationalExpression GREATER_EQUAL ShiftExpression");
3513                             consumeBinaryExpression(OperatorExpression.GREATER_EQUAL);  
3514                                 break ;
3515          
3516             case 358 : // System.out.println("RelationalExpression ::= RelationalExpression instanceof ReferenceType");
3517                             consumeInstanceOfExpression(OperatorExpression.INSTANCEOF);  
3518                                 break ;
3519          
3520             case 360 : // System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL RelationalExpression");
3521                             consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL);  
3522                                 break ;
3523          
3524             case 361 : // System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL RelationalExpression");
3525                             consumeEqualityExpression(OperatorExpression.NOT_EQUAL);  
3526                                 break ;
3527          
3528             case 363 : // System.out.println("AndExpression ::= AndExpression AND EqualityExpression");
3529                             consumeBinaryExpression(OperatorExpression.AND);  
3530                                 break ;
3531          
3532             case 365 : // System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR AndExpression");
3533                             consumeBinaryExpression(OperatorExpression.XOR);  
3534                                 break ;
3535          
3536             case 367 : // System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR ExclusiveOrExpression");
3537                             consumeBinaryExpression(OperatorExpression.OR);  
3538                                 break ;
3539          
3540             case 369 : // System.out.println("ConditionalAndExpression ::= ConditionalAndExpression AND_AND InclusiveOrExpression");
3541                             consumeBinaryExpression(OperatorExpression.AND_AND);  
3542                                 break ;
3543          
3544             case 371 : // System.out.println("ConditionalOrExpression ::= ConditionalOrExpression OR_OR ConditionalAndExpression");
3545                             consumeBinaryExpression(OperatorExpression.OR_OR);  
3546                                 break ;
3547          
3548             case 373 : // System.out.println("ConditionalExpression ::= ConditionalOrExpression QUESTION Expression COLON...");
3549                             consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ;  
3550                                 break ;
3551          
3552             case 376 : // System.out.println("Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression");
3553                             consumeAssignment();  
3554                                 break ;
3555          
3556             case 378 : // System.out.println("Assignment ::= InvalidArrayInitializerAssignement");
3557                             ignoreExpressionAssignment(); 
3558                                 break ;
3559          
3560             case 379 : // System.out.println("LeftHandSide ::= Name");
3561                             consumeLeftHandSide();  
3562                                 break ;
3563          
3564             case 382 : // System.out.println("AssignmentOperator ::= EQUAL");
3565                             consumeAssignmentOperator(EQUAL);  
3566                                 break ;
3567          
3568             case 383 : // System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL");
3569                             consumeAssignmentOperator(MULTIPLY);  
3570                                 break ;
3571          
3572             case 384 : // System.out.println("AssignmentOperator ::= DIVIDE_EQUAL");
3573                             consumeAssignmentOperator(DIVIDE);  
3574                                 break ;
3575          
3576             case 385 : // System.out.println("AssignmentOperator ::= REMAINDER_EQUAL");
3577                             consumeAssignmentOperator(REMAINDER);  
3578                                 break ;
3579          
3580             case 386 : // System.out.println("AssignmentOperator ::= PLUS_EQUAL");
3581                             consumeAssignmentOperator(PLUS);  
3582                                 break ;
3583          
3584             case 387 : // System.out.println("AssignmentOperator ::= MINUS_EQUAL");
3585                             consumeAssignmentOperator(MINUS);  
3586                                 break ;
3587          
3588             case 388 : // System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL");
3589                             consumeAssignmentOperator(LEFT_SHIFT);  
3590                                 break ;
3591          
3592             case 389 : // System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL");
3593                             consumeAssignmentOperator(RIGHT_SHIFT);  
3594                                 break ;
3595          
3596             case 390 : // System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL");
3597                             consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
3598                                 break ;
3599          
3600             case 391 : // System.out.println("AssignmentOperator ::= AND_EQUAL");
3601                             consumeAssignmentOperator(AND);  
3602                                 break ;
3603          
3604             case 392 : // System.out.println("AssignmentOperator ::= XOR_EQUAL");
3605                             consumeAssignmentOperator(XOR);  
3606                                 break ;
3607          
3608             case 393 : // System.out.println("AssignmentOperator ::= OR_EQUAL");
3609                             consumeAssignmentOperator(OR);  
3610                                 break ;
3611          
3612             case 400 : // System.out.println("Expressionopt ::=");
3613                             consumeEmptyExpression();  
3614                                 break ;
3615          
3616             case 404 : // System.out.println("ImportDeclarationsopt ::=");
3617                             consumeEmptyImportDeclarationsopt();  
3618                                 break ;
3619          
3620             case 405 : // System.out.println("ImportDeclarationsopt ::= ImportDeclarations");
3621                             consumeImportDeclarationsopt();  
3622                                 break ;
3623          
3624             case 406 : // System.out.println("TypeDeclarationsopt ::=");
3625                             consumeEmptyTypeDeclarationsopt();  
3626                                 break ;
3627          
3628             case 407 : // System.out.println("TypeDeclarationsopt ::= TypeDeclarations");
3629                             consumeTypeDeclarationsopt();  
3630                                 break ;
3631          
3632             case 408 : // System.out.println("ClassBodyDeclarationsopt ::=");
3633                             consumeEmptyClassBodyDeclarationsopt();  
3634                                 break ;
3635          
3636             case 409 : // System.out.println("ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations");
3637                             consumeClassBodyDeclarationsopt();  
3638                                 break ;
3639          
3640              case 410 : // System.out.println("Modifiersopt ::=");
3641                             consumeDefaultModifiers();  
3642                                 break ;
3643          
3644             case 411 : // System.out.println("Modifiersopt ::= Modifiers");
3645                             consumeModifiers();  
3646                                 break ;
3647          
3648             case 412 : // System.out.println("BlockStatementsopt ::=");
3649                             consumeEmptyBlockStatementsopt();  
3650                                 break ;
3651          
3652              case 414 : // System.out.println("Dimsopt ::=");
3653                             consumeEmptyDimsopt();  
3654                                 break ;
3655          
3656              case 416 : // System.out.println("ArgumentListopt ::=");
3657                             consumeEmptyArgumentListopt();  
3658                                 break ;
3659          
3660             case 420 : // System.out.println("FormalParameterListopt ::=");
3661                             consumeFormalParameterListopt();  
3662                                 break ;
3663          
3664              case 424 : // System.out.println("InterfaceMemberDeclarationsopt ::=");
3665                             consumeEmptyInterfaceMemberDeclarationsopt();  
3666                                 break ;
3667          
3668              case 425 : // System.out.println("InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations");
3669                             consumeInterfaceMemberDeclarationsopt();  
3670                                 break ;
3671          
3672             case 426 : // System.out.println("NestedType ::=");
3673                             consumeNestedType();  
3674                                 break ;
3675         
3676              case 427 : // System.out.println("ForInitopt ::=");
3677                             consumeEmptyForInitopt();  
3678                                 break ;
3679          
3680              case 429 : // System.out.println("ForUpdateopt ::=");
3681                             consumeEmptyForUpdateopt();  
3682                                 break ;
3683          
3684              case 433 : // System.out.println("Catchesopt ::=");
3685                             consumeEmptyCatchesopt();  
3686                                 break ;
3687          
3688              case 435 : // System.out.println("ArrayInitializeropt ::=");
3689                             consumeEmptyArrayInitializeropt();  
3690                                 break ;
3691          
3692                 }
3693         } 
3694
3695         
3696 protected void consumeSimpleAssertStatement() {
3697         // AssertStatement ::= 'assert' Expression ';'
3698         expressionLengthPtr--;
3699         pushOnAstStack(new AssertStatement(expressionStack[expressionPtr--], intStack[intPtr--]));      
3700 }
3701         
3702 protected void consumeSingleTypeImportDeclaration() {
3703         // SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
3704
3705         ImportReference impt = (ImportReference) astStack[astPtr];
3706         // flush annotations defined prior to import statements
3707         impt.declarationEnd = endStatementPosition;
3708         impt.declarationSourceEnd = 
3709                 this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd); 
3710
3711         // recovery
3712         if (currentElement != null) {
3713                 lastCheckPoint = impt.declarationSourceEnd + 1;
3714                 currentElement = currentElement.add(impt, 0);
3715                 lastIgnoredToken = -1;
3716                 restartRecovery = true; 
3717                 // used to avoid branching back into the regular automaton
3718         }
3719 }
3720 protected void consumeSingleTypeImportDeclarationName() {
3721         // SingleTypeImportDeclarationName ::= 'import' Name
3722         /* push an ImportRef build from the last name 
3723         stored in the identifier stack. */
3724
3725         ImportReference impt;
3726         int length;
3727         char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
3728         identifierPtr -= length;
3729         long[] positions = new long[length];
3730         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
3731         System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
3732         pushOnAstStack(impt = new ImportReference(tokens, positions, false));
3733
3734         if (currentToken == TokenNameSEMICOLON){
3735                 impt.declarationSourceEnd = scanner.currentPosition - 1;
3736         } else {
3737                 impt.declarationSourceEnd = impt.sourceEnd;
3738         }
3739         impt.declarationEnd = impt.declarationSourceEnd;
3740         //endPosition is just before the ;
3741         impt.declarationSourceStart = intStack[intPtr--];
3742
3743         // recovery
3744         if (currentElement != null){
3745                 lastCheckPoint = impt.declarationSourceEnd+1;
3746                 currentElement = currentElement.add(impt, 0);
3747                 lastIgnoredToken = -1;
3748                 restartRecovery = true; // used to avoid branching back into the regular automaton              
3749         }
3750 }
3751 protected void consumeStatementBreak() {
3752         // BreakStatement ::= 'break' ';'
3753         // break pushs a position on intStack in case there is no label
3754
3755         pushOnAstStack(new Break(null, intStack[intPtr--], endPosition));
3756 }
3757 protected void consumeStatementBreakWithLabel() {
3758         // BreakStatement ::= 'break' Identifier ';'
3759         // break pushs a position on intStack in case there is no label
3760
3761         pushOnAstStack(
3762                 new Break(
3763                         identifierStack[identifierPtr--],
3764                         intStack[intPtr--],
3765                         endPosition)); 
3766         identifierLengthPtr--;
3767 }
3768 protected void consumeStatementCatch() {
3769         // CatchClause ::= 'catch' '(' FormalParameter ')'    Block
3770
3771         //catch are stored directly into the Try
3772         //has they always comes two by two....
3773         //we remove one entry from the astlengthPtr.
3774         //The construction of the try statement must
3775         //then fetch the catches using  2*i and 2*i + 1
3776
3777         astLengthPtr--;
3778         listLength = 0; // reset formalParameter counter (incremented for catch variable)
3779 }
3780 protected void consumeStatementContinue() {
3781         // ContinueStatement ::= 'continue' ';'
3782         // continue pushs a position on intStack in case there is no label
3783
3784         pushOnAstStack(
3785                 new Continue(
3786                         null,
3787                         intStack[intPtr--],
3788                         endPosition));
3789 }
3790 protected void consumeStatementContinueWithLabel() {
3791         // ContinueStatement ::= 'continue' Identifier ';'
3792         // continue pushs a position on intStack in case there is no label
3793
3794         pushOnAstStack(
3795                 new Continue(
3796                         identifierStack[identifierPtr--], 
3797                         intStack[intPtr--], 
3798                         endPosition)); 
3799         identifierLengthPtr--;
3800 }
3801 protected void consumeStatementDo() {
3802         // DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
3803
3804         //the 'while' pushes a value on intStack that we need to remove
3805         intPtr--;
3806
3807         //optimize the push/pop
3808         Statement action = (Statement) astStack[astPtr];
3809         if (action instanceof EmptyStatement
3810                 && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
3811                 expressionLengthPtr--;
3812                 astStack[astPtr] = 
3813                         new DoStatement(
3814                                 expressionStack[expressionPtr--], 
3815                                 null, 
3816                                 intStack[intPtr--], 
3817                                 endPosition); 
3818         } else {
3819                 expressionLengthPtr--;
3820                 astStack[astPtr] = 
3821                         new DoStatement(
3822                                 expressionStack[expressionPtr--], 
3823                                 action, 
3824                                 intStack[intPtr--], 
3825                                 endPosition); 
3826         }
3827 }
3828 protected void consumeStatementExpressionList() {
3829         // StatementExpressionList ::= StatementExpressionList ',' StatementExpression
3830         concatExpressionLists();
3831 }
3832 protected void consumeStatementFor() {
3833         // ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
3834         // ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
3835
3836         int length;
3837         Expression cond = null;
3838         Statement[] inits, updates;
3839         Statement action;
3840         boolean scope = true;
3841
3842         //statements
3843         astLengthPtr--; // we need to consume it
3844         action = (Statement) astStack[astPtr--];
3845         if (action instanceof EmptyStatement
3846                 && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
3847                 action = null;
3848         }
3849
3850         //updates are on the expresion stack
3851         if ((length = expressionLengthStack[expressionLengthPtr--]) == 0) {
3852                 updates = null;
3853         } else {
3854                 expressionPtr -= length;
3855                 System.arraycopy(
3856                         expressionStack, 
3857                         expressionPtr + 1, 
3858                         updates = new Statement[length], 
3859                         0, 
3860                         length); 
3861         }
3862
3863         if (expressionLengthStack[expressionLengthPtr--] != 0)
3864                 cond = expressionStack[expressionPtr--];
3865
3866         //inits may be on two different stacks
3867         if ((length = astLengthStack[astLengthPtr--]) == 0) {
3868                 inits = null;
3869                 scope = false;
3870         } else {
3871                 if (length == -1) { //on expressionStack
3872                         scope = false;
3873                         length = expressionLengthStack[expressionLengthPtr--];
3874                         expressionPtr -= length;
3875                         System.arraycopy(
3876                                 expressionStack, 
3877                                 expressionPtr + 1, 
3878                                 inits = new Statement[length], 
3879                                 0, 
3880                                 length); 
3881                 } else { //on astStack
3882                         astPtr -= length;
3883                         System.arraycopy(
3884                                 astStack, 
3885                                 astPtr + 1, 
3886                                 inits = new Statement[length], 
3887                                 0, 
3888                                 length); 
3889                 }
3890         };
3891         if (action instanceof Block) {
3892                 pushOnAstStack(
3893                         new ForStatement(
3894                                 inits, 
3895                                 cond, 
3896                                 updates, 
3897                                 action, 
3898                                 scope, 
3899                                 intStack[intPtr--], 
3900                                 endStatementPosition)); 
3901         } else {
3902                 pushOnAstStack(
3903                         new ForStatement(
3904                                 inits, 
3905                                 cond, 
3906                                 updates, 
3907                                 action, 
3908                                 scope, 
3909                                 intStack[intPtr--], 
3910                                 endPosition)); 
3911         }
3912 }
3913 protected void consumeStatementIfNoElse() {
3914         // IfThenStatement ::=  'if' '(' Expression ')' Statement
3915
3916         //optimize the push/pop
3917         expressionLengthPtr--;
3918         Statement thenStatement = (Statement) astStack[astPtr];
3919         if (thenStatement instanceof Block) {
3920                 astStack[astPtr] = 
3921                         new IfStatement(
3922                                 expressionStack[expressionPtr--], 
3923                                 thenStatement, 
3924                                 intStack[intPtr--], 
3925                                 endStatementPosition); 
3926         } else if (thenStatement instanceof EmptyStatement) {
3927                 astStack[astPtr] = 
3928                         new IfStatement(
3929                                 expressionStack[expressionPtr--], 
3930                                 Block.None, 
3931                                 intStack[intPtr--], 
3932                                 endStatementPosition); 
3933         } else {
3934                 astStack[astPtr] = 
3935                         new IfStatement(
3936                                 expressionStack[expressionPtr--], 
3937                                 thenStatement, 
3938                                 intStack[intPtr--], 
3939                                 endStatementPosition); 
3940         }
3941 }
3942 protected void consumeStatementIfWithElse() {
3943         // IfThenElseStatement ::=  'if' '(' Expression ')' StatementNoShortIf 'else' Statement
3944         // IfThenElseStatementNoShortIf ::=  'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
3945
3946         astLengthPtr--; // optimized {..., Then, Else } ==> {..., If }
3947         expressionLengthPtr--;
3948         //optimize the push/pop
3949         Statement elseStatement = (Statement) astStack[astPtr--];
3950         Statement thenStatement = (Statement) astStack[astPtr];
3951         if (elseStatement instanceof EmptyStatement) {
3952                 elseStatement = Block.None;
3953         }
3954         if (thenStatement instanceof EmptyStatement) {
3955                 thenStatement = Block.None;
3956         }
3957         if (elseStatement instanceof Block) {
3958                 astStack[astPtr] = 
3959                         new IfStatement(
3960                                 expressionStack[expressionPtr--], 
3961                                 thenStatement, 
3962                                 elseStatement, 
3963                                 intStack[intPtr--], 
3964                                 endStatementPosition); 
3965         } else {
3966                 astStack[astPtr] = 
3967                         new IfStatement(
3968                                 expressionStack[expressionPtr--], 
3969                                 thenStatement, 
3970                                 elseStatement, 
3971                                 intStack[intPtr--], 
3972                                 endStatementPosition); 
3973         }
3974 }
3975 protected void consumeStatementLabel() {
3976         // LabeledStatement ::= 'Identifier' ':' Statement
3977         // LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
3978
3979         //optimize push/pop
3980
3981         Statement stmt = (Statement) astStack[astPtr];
3982         if (stmt instanceof EmptyStatement) {
3983                 astStack[astPtr] = 
3984                         new LabeledStatement(
3985                                 identifierStack[identifierPtr], 
3986                                 Block.None, 
3987                                 (int) (identifierPositionStack[identifierPtr--] >>> 32), 
3988                                 endStatementPosition); 
3989         } else {
3990                 astStack[astPtr] = 
3991                         new LabeledStatement(
3992                                 identifierStack[identifierPtr], 
3993                                 stmt, 
3994                                 (int) (identifierPositionStack[identifierPtr--] >>> 32), 
3995                                 endStatementPosition); 
3996         }
3997         identifierLengthPtr--;
3998 }
3999 protected void consumeStatementReturn() {
4000         // ReturnStatement ::= 'return' Expressionopt ';'
4001         // return pushs a position on intStack in case there is no expression
4002
4003         if (expressionLengthStack[expressionLengthPtr--] != 0) {
4004                 pushOnAstStack(
4005                         new ReturnStatement(
4006                                 expressionStack[expressionPtr--], 
4007                                 intStack[intPtr--], 
4008                                 endPosition)
4009                 );
4010         } else {
4011                 pushOnAstStack(new ReturnStatement(null, intStack[intPtr--], endPosition));
4012         }
4013 }
4014 protected void consumeStatementSwitch() {
4015         // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
4016
4017         //OpenBlock just makes the semantic action blockStart()
4018         //the block is inlined but a scope need to be created
4019         //if some declaration occurs.
4020
4021         int length;
4022         SwitchStatement s = new SwitchStatement();
4023         expressionLengthPtr--;
4024         s.testExpression = expressionStack[expressionPtr--];
4025         if ((length = astLengthStack[astLengthPtr--]) != 0) {
4026                 astPtr -= length;
4027                 System.arraycopy(
4028                         astStack, 
4029                         astPtr + 1, 
4030                         s.statements = new Statement[length], 
4031                         0, 
4032                         length); 
4033         }
4034         s.explicitDeclarations = realBlockStack[realBlockPtr--];
4035         pushOnAstStack(s);
4036         intPtr--; // because of OpenBlock
4037         s.sourceStart = intStack[intPtr--];
4038         s.sourceEnd = endStatementPosition;
4039 }
4040 protected void consumeStatementSynchronized() {
4041         // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
4042         //optimize the push/pop
4043
4044         if (astLengthStack[astLengthPtr] == 0) {
4045                 astLengthStack[astLengthPtr] = 1;
4046                 expressionLengthPtr--;
4047                 astStack[++astPtr] = 
4048                         new SynchronizedStatement(
4049                                 expressionStack[expressionPtr--], 
4050                                 Block.None, 
4051                                 intStack[intPtr--], 
4052                                 endStatementPosition); 
4053         } else {
4054                 expressionLengthPtr--;
4055                 astStack[astPtr] = 
4056                         new SynchronizedStatement(
4057                                 expressionStack[expressionPtr--], 
4058                                 (Block) astStack[astPtr], 
4059                                 intStack[intPtr--], 
4060                                 endStatementPosition); 
4061         }
4062         resetModifiers();
4063 }
4064 protected void consumeStatementThrow() {
4065         // ThrowStatement ::= 'throw' Expression ';'
4066         expressionLengthPtr--;
4067         pushOnAstStack(new ThrowStatement(expressionStack[expressionPtr--], intStack[intPtr--]));
4068 }
4069 protected void consumeStatementTry(boolean withFinally) {
4070         //TryStatement ::= 'try'  Block Catches
4071         //TryStatement ::= 'try'  Block Catchesopt Finally
4072
4073         int length;
4074         TryStatement tryStmt = new TryStatement();
4075         //finally
4076         if (withFinally) {
4077                 astLengthPtr--;
4078                 tryStmt.finallyBlock = (Block) astStack[astPtr--];
4079         }
4080         //catches are handle by two <argument-block> [see statementCatch]
4081         if ((length = astLengthStack[astLengthPtr--]) != 0) {
4082                 if (length == 1) {
4083                         tryStmt.catchBlocks = new Block[] {(Block) astStack[astPtr--]};
4084                         tryStmt.catchArguments = new Argument[] {(Argument) astStack[astPtr--]};
4085                 } else {
4086                         Block[] bks = (tryStmt.catchBlocks = new Block[length]);
4087                         Argument[] args = (tryStmt.catchArguments = new Argument[length]);
4088                         while (length-- > 0) {
4089                                 bks[length] = (Block) astStack[astPtr--];
4090                                 args[length] = (Argument) astStack[astPtr--];
4091                         }
4092                 }
4093         }
4094         //try
4095         astLengthPtr--;
4096         tryStmt.tryBlock = (Block) astStack[astPtr--];
4097
4098         //positions
4099         tryStmt.sourceEnd = endStatementPosition;
4100         tryStmt.sourceStart = intStack[intPtr--];
4101         pushOnAstStack(tryStmt);
4102 }
4103 protected void consumeStatementWhile() {
4104         // WhileStatement ::= 'while' '(' Expression ')' Statement
4105         // WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
4106
4107         Statement action = (Statement) astStack[astPtr];
4108         expressionLengthPtr--;
4109         if (action instanceof Block) {
4110                 astStack[astPtr] = 
4111                         new WhileStatement(
4112                                 expressionStack[expressionPtr--], 
4113                                 action, 
4114                                 intStack[intPtr--], 
4115                                 endStatementPosition); 
4116         } else {
4117                 if (action instanceof EmptyStatement
4118                         && problemReporter.options.complianceLevel <= CompilerOptions.JDK1_3) {
4119                         astStack[astPtr] = 
4120                                 new WhileStatement(
4121                                         expressionStack[expressionPtr--], 
4122                                         null, 
4123                                         intStack[intPtr--], 
4124                                         endPosition); 
4125                 } else {
4126                         astStack[astPtr] = 
4127                                 new WhileStatement(
4128                                         expressionStack[expressionPtr--], 
4129                                         action, 
4130                                         intStack[intPtr--], 
4131                                         endPosition); 
4132                 }
4133         }
4134 }
4135 protected void consumeStaticInitializer() {
4136         // StaticInitializer ::=  StaticOnly Block
4137         //push an Initializer
4138         //optimize the push/pop
4139         Initializer initializer = new Initializer((Block) astStack[astPtr], AccStatic);
4140         astStack[astPtr] = initializer;
4141         initializer.sourceEnd = endStatementPosition;   
4142         initializer.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
4143         nestedMethod[nestedType] --;
4144         initializer.declarationSourceStart = intStack[intPtr--];
4145         
4146         // recovery
4147         if (currentElement != null){
4148                 lastCheckPoint = initializer.declarationSourceEnd;
4149                 currentElement = currentElement.add(initializer, 0);
4150                 lastIgnoredToken = -1;
4151         }
4152 }
4153 protected void consumeStaticOnly() {
4154         // StaticOnly ::= 'static'
4155         int savedModifiersSourceStart = modifiersSourceStart;
4156         checkAnnotation(); // might update declaration source start
4157         if (modifiersSourceStart >= savedModifiersSourceStart) {
4158                 modifiersSourceStart = savedModifiersSourceStart;
4159         }
4160         pushOnIntStack(
4161                 modifiersSourceStart >= 0 ? modifiersSourceStart : scanner.startPosition);
4162         jumpOverMethodBody();
4163         nestedMethod[nestedType]++;
4164         resetModifiers();
4165
4166         // recovery
4167         if (currentElement != null){
4168                 recoveredStaticInitializerStart = intStack[intPtr]; // remember start position only for static initializers
4169         }
4170 }
4171 protected void consumeSwitchBlock() {
4172         // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
4173         concatNodeLists();
4174 }
4175 protected void consumeSwitchBlockStatement() {
4176         // SwitchBlockStatement ::= SwitchLabels BlockStatements
4177         concatNodeLists();
4178 }
4179 protected void consumeSwitchBlockStatements() {
4180         // SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
4181         concatNodeLists();
4182 }
4183 protected void consumeSwitchLabels() {
4184         // SwitchLabels ::= SwitchLabels SwitchLabel
4185         optimizedConcatNodeLists();
4186 }
4187 protected void consumeToken(int type) {
4188         /* remember the last consumed value */
4189         /* try to minimize the number of build values */
4190         if (scanner.wasNonExternalizedStringLiteral) {
4191                 StringLiteral[] literals = this.scanner.nonNLSStrings;
4192                 // could not reproduce, but this is the only NPE
4193                 // added preventive null check see PR 9035
4194                 if (literals != null) {
4195                         for (int i = 0, max = literals.length; i < max; i++) {
4196                                 problemReporter().nonExternalizedStringLiteral(literals[i]);
4197                         }
4198                 }
4199                 scanner.currentLine = null;
4200                 scanner.wasNonExternalizedStringLiteral = false;
4201         }
4202         // clear the commentPtr of the scanner in case we read something different from a modifier
4203         switch(type) {
4204 //              case TokenNameabstract :
4205 //              case TokenNamestrictfp :
4206 //              case TokenNamefinal :
4207 //              case TokenNamenative :
4208 //              case TokenNameprivate :
4209 //              case TokenNameprotected :
4210 //              case TokenNamepublic :
4211 //              case TokenNametransient :
4212 //              case TokenNamevolatile :
4213                 case TokenNamestatic :
4214 //              case TokenNamesynchronized :
4215                         break;
4216                 default:
4217                         scanner.commentPtr = -1;
4218         }
4219         //System.out.println(scanner.toStringAction(type));
4220         switch (type) {
4221                 case TokenNameIdentifier :
4222                         pushIdentifier();
4223                         if (scanner.useAssertAsAnIndentifier) {
4224                                 long positions = identifierPositionStack[identifierPtr];
4225                                 problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
4226                         }
4227                         scanner.commentPtr = -1;
4228                         break;
4229 //              case TokenNameinterface :
4230 //                      adjustInterfaceModifiers();
4231 //                      //'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
4232 //                      pushOnIntStack(scanner.startPosition);
4233 //                      pushOnIntStack(scanner.currentPosition - 1);                    
4234 //                      scanner.commentPtr = -1;
4235 //                      break;
4236 //              case TokenNameabstract :
4237 //                      checkAndSetModifiers(AccAbstract);
4238 //                      break;
4239 //              case TokenNamestrictfp :
4240 //                      checkAndSetModifiers(AccStrictfp);
4241 //                      break;
4242 //              case TokenNamefinal :
4243 //                      checkAndSetModifiers(AccFinal);
4244 //                      break;
4245 //              case TokenNamenative :
4246 //                      checkAndSetModifiers(AccNative);
4247 //                      break;
4248 //              case TokenNameprivate :
4249 //                      checkAndSetModifiers(AccPrivate);
4250 //                      break;
4251 //              case TokenNameprotected :
4252 //                      checkAndSetModifiers(AccProtected);
4253 //                      break;
4254 //              case TokenNamepublic :
4255 //                      checkAndSetModifiers(AccPublic);
4256 //                      break;
4257 //              case TokenNametransient :
4258 //                      checkAndSetModifiers(AccTransient);
4259 //                      break;
4260 //              case TokenNamevolatile :
4261 //                      checkAndSetModifiers(AccVolatile);
4262 //                      break;
4263                 case TokenNamestatic :
4264                         checkAndSetModifiers(AccStatic);
4265                         break;
4266 //              case TokenNamesynchronized :
4267 //                      this.synchronizedBlockSourceStart = scanner.startPosition;      
4268 //                      checkAndSetModifiers(AccSynchronized);
4269 //                      break;
4270 //                      //==============================
4271 //              case TokenNamevoid :
4272 //                      pushIdentifier(-T_void);
4273 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4274 //                      pushOnIntStack(scanner.startPosition);
4275 //                      scanner.commentPtr = -1;
4276 //                      break;
4277 //                      //push a default dimension while void is not part of the primitive
4278 //                      //declaration baseType and so takes the place of a type without getting into
4279 //                      //regular type parsing that generates a dimension on intStack
4280 //              case TokenNameboolean :
4281 //                      pushIdentifier(-T_boolean);
4282 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4283 //                      pushOnIntStack(scanner.startPosition);          
4284 //                      scanner.commentPtr = -1;
4285 //                      break;
4286 //              case TokenNamebyte :
4287 //                      pushIdentifier(-T_byte);
4288 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4289 //                      pushOnIntStack(scanner.startPosition);                                  
4290 //                      scanner.commentPtr = -1;
4291 //                      break;
4292 //              case TokenNamechar :
4293 //                      pushIdentifier(-T_char);
4294 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4295 //                      pushOnIntStack(scanner.startPosition);                                  
4296 //                      scanner.commentPtr = -1;
4297 //                      break;
4298 //              case TokenNamedouble :
4299 //                      pushIdentifier(-T_double);
4300 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4301 //                      pushOnIntStack(scanner.startPosition);                                  
4302 //                      scanner.commentPtr = -1;
4303 //                      break;
4304 //              case TokenNamefloat :
4305 //                      pushIdentifier(-T_float);
4306 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4307 //                      pushOnIntStack(scanner.startPosition);                                  
4308 //                      scanner.commentPtr = -1;
4309 //                      break;
4310 //              case TokenNameint :
4311 //                      pushIdentifier(-T_int);
4312 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4313 //                      pushOnIntStack(scanner.startPosition);                                  
4314 //                      scanner.commentPtr = -1;
4315 //                      break;
4316 //              case TokenNamelong :
4317 //                      pushIdentifier(-T_long);
4318 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4319 //                      pushOnIntStack(scanner.startPosition);                                  
4320 //                      scanner.commentPtr = -1;
4321 //                      break;
4322 //              case TokenNameshort :
4323 //                      pushIdentifier(-T_short);
4324 //                      pushOnIntStack(scanner.currentPosition - 1);                            
4325 //                      pushOnIntStack(scanner.startPosition);                                  
4326 //                      scanner.commentPtr = -1;
4327 //                      break;
4328                         //==============================
4329                 case TokenNameIntegerLiteral :
4330                         pushOnExpressionStack(
4331                                 new IntLiteral(
4332                                         scanner.getCurrentTokenSource(), 
4333                                         scanner.startPosition, 
4334                                         scanner.currentPosition - 1)); 
4335                         scanner.commentPtr = -1;
4336                         break;
4337                 case TokenNameLongLiteral :
4338                         pushOnExpressionStack(
4339                                 new LongLiteral(
4340                                         scanner.getCurrentTokenSource(), 
4341                                         scanner.startPosition, 
4342                                         scanner.currentPosition - 1)); 
4343                         scanner.commentPtr = -1;
4344                         break;
4345                 case TokenNameFloatingPointLiteral :
4346                         pushOnExpressionStack(
4347                                 new FloatLiteral(
4348                                         scanner.getCurrentTokenSource(), 
4349                                         scanner.startPosition, 
4350                                         scanner.currentPosition - 1)); 
4351                         scanner.commentPtr = -1;
4352                         break;
4353                 case TokenNameDoubleLiteral :
4354                         pushOnExpressionStack(
4355                                 new DoubleLiteral(
4356                                         scanner.getCurrentTokenSource(), 
4357                                         scanner.startPosition, 
4358                                         scanner.currentPosition - 1)); 
4359                         scanner.commentPtr = -1;
4360                         break;
4361                 case TokenNameCharacterLiteral :
4362                         pushOnExpressionStack(
4363                                 new CharLiteral(
4364                                         scanner.getCurrentTokenSource(), 
4365                                         scanner.startPosition, 
4366                                         scanner.currentPosition - 1)); 
4367                         scanner.commentPtr = -1;
4368                         break;
4369                 case TokenNameStringLiteral :
4370                         StringLiteral stringLiteral = new StringLiteral(
4371                                         scanner.getCurrentTokenSourceString(), 
4372                                         scanner.startPosition, 
4373                                         scanner.currentPosition - 1); 
4374                         pushOnExpressionStack(stringLiteral); 
4375                         scanner.commentPtr = -1;
4376                         break;
4377                 case TokenNamefalse :
4378                         pushOnExpressionStack(
4379                                 new FalseLiteral(scanner.startPosition, scanner.currentPosition - 1)); 
4380                         scanner.commentPtr = -1;
4381                         break;
4382                 case TokenNametrue :
4383                         pushOnExpressionStack(
4384                                 new TrueLiteral(scanner.startPosition, scanner.currentPosition - 1)); 
4385                         break;
4386                 case TokenNamenull :
4387                         pushOnExpressionStack(
4388                                 new NullLiteral(scanner.startPosition, scanner.currentPosition - 1)); 
4389                         break;
4390                         //============================
4391 //              case TokenNamesuper :
4392 //              case TokenNamethis :
4393 //                      endPosition = scanner.currentPosition - 1;
4394 //                      pushOnIntStack(scanner.startPosition);
4395 //                      break;
4396 //              case TokenNameassert :
4397 //              case TokenNameimport :
4398 //              case TokenNamepackage :
4399 //              case TokenNamethrow :
4400                 case TokenNamenew :
4401                 case TokenNamedo :
4402                 case TokenNameif :
4403                 case TokenNamefor :
4404                 case TokenNameswitch :
4405 //              case TokenNametry :
4406                 case TokenNamewhile :
4407                 case TokenNamebreak :
4408                 case TokenNamecontinue :
4409                 case TokenNamereturn :
4410                 case TokenNamecase :
4411                         pushOnIntStack(scanner.startPosition);
4412                         break;
4413                 case TokenNameclass :
4414                         pushOnIntStack(scanner.currentPosition - 1);
4415                         pushOnIntStack(scanner.startPosition);
4416                         break;
4417                 case TokenNamedefault :
4418                         pushOnIntStack(scanner.startPosition);
4419                         pushOnIntStack(scanner.currentPosition - 1);
4420                         break;
4421                         //let extra semantic action decide when to push
4422                 case TokenNameRBRACKET :
4423                 case TokenNamePLUS :
4424                 case TokenNameMINUS :
4425                 case TokenNameNOT :
4426                 case TokenNameTWIDDLE :
4427                         endPosition = scanner.startPosition;
4428                         break;
4429                 case TokenNamePLUS_PLUS :
4430                 case TokenNameMINUS_MINUS :
4431                         endPosition = scanner.startPosition;
4432                         endStatementPosition = scanner.currentPosition - 1;
4433                         break;
4434                 case TokenNameRBRACE:
4435                 case TokenNameSEMICOLON :
4436                         endStatementPosition = scanner.currentPosition - 1;
4437                         endPosition = scanner.startPosition - 1; 
4438                         //the item is not part of the potential futur expression/statement
4439                         break;
4440                         // in order to handle ( expression) ////// (cast)expression///// foo(x)
4441                 case TokenNameRPAREN :
4442                         rParenPos = scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
4443                         break;
4444                 case TokenNameLPAREN :
4445                         lParenPos = scanner.startPosition;
4446                         break;
4447                         //  case TokenNameQUESTION  :
4448                         //  case TokenNameCOMMA :
4449                         //  case TokenNameCOLON  :
4450                         //  case TokenNameEQUAL  :
4451                         //  case TokenNameLBRACKET  :
4452                         //  case TokenNameDOT :
4453                         //  case TokenNameERROR :
4454                         //  case TokenNameEOF  :
4455                         //  case TokenNamecase  :
4456                         //  case TokenNamecatch  :
4457                         //  case TokenNameelse  :
4458                         //  case TokenNameextends  :
4459                         //  case TokenNamefinally  :
4460                         //  case TokenNameimplements  :
4461                         //  case TokenNamethrows  :
4462                         //  case TokenNameinstanceof  :
4463                         //  case TokenNameEQUAL_EQUAL  :
4464                         //  case TokenNameLESS_EQUAL  :
4465                         //  case TokenNameGREATER_EQUAL  :
4466                         //  case TokenNameNOT_EQUAL  :
4467                         //  case TokenNameLEFT_SHIFT  :
4468                         //  case TokenNameRIGHT_SHIFT  :
4469                         //  case TokenNameUNSIGNED_RIGHT_SHIFT :
4470                         //  case TokenNamePLUS_EQUAL  :
4471                         //  case TokenNameMINUS_EQUAL  :
4472                         //  case TokenNameMULTIPLY_EQUAL  :
4473                         //  case TokenNameDIVIDE_EQUAL  :
4474                         //  case TokenNameAND_EQUAL  :
4475                         //  case TokenNameOR_EQUAL  :
4476                         //  case TokenNameXOR_EQUAL  :
4477                         //  case TokenNameREMAINDER_EQUAL  :
4478                         //  case TokenNameLEFT_SHIFT_EQUAL  :
4479                         //  case TokenNameRIGHT_SHIFT_EQUAL  :
4480                         //  case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL  :
4481                         //  case TokenNameOR_OR  :
4482                         //  case TokenNameAND_AND  :
4483                         //  case TokenNameREMAINDER :
4484                         //  case TokenNameXOR  :
4485                         //  case TokenNameAND  :
4486                         //  case TokenNameMULTIPLY :
4487                         //  case TokenNameOR  :
4488                         //  case TokenNameDIVIDE :
4489                         //  case TokenNameGREATER  :
4490                         //  case TokenNameLESS  :
4491         }
4492 }
4493 protected void consumeTypeDeclarations() {
4494         // TypeDeclarations ::= TypeDeclarations TypeDeclaration
4495         concatNodeLists();
4496 }
4497 protected void consumeTypeDeclarationsopt() {
4498         // TypeDeclarationsopt ::= TypeDeclarations
4499         int length;
4500         if ((length = astLengthStack[astLengthPtr--]) != 0) {
4501                 astPtr -= length;
4502                 System.arraycopy(astStack, astPtr + 1, compilationUnit.types = new TypeDeclaration[length], 0, length);
4503         }
4504 }
4505 protected void consumeTypeImportOnDemandDeclaration() {
4506         // TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
4507
4508         ImportReference impt = (ImportReference) astStack[astPtr];
4509         // flush annotations defined prior to import statements
4510         impt.declarationEnd = endStatementPosition;
4511         impt.declarationSourceEnd = 
4512                 this.flushAnnotationsDefinedPriorTo(impt.declarationSourceEnd); 
4513
4514         // recovery
4515         if (currentElement != null) {
4516                 lastCheckPoint = impt.declarationSourceEnd + 1;
4517                 currentElement = currentElement.add(impt, 0);
4518                 restartRecovery = true;
4519                 lastIgnoredToken = -1;
4520                 // used to avoid branching back into the regular automaton
4521         }
4522 }
4523 protected void consumeTypeImportOnDemandDeclarationName() {
4524         // TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
4525         /* push an ImportRef build from the last name 
4526         stored in the identifier stack. */
4527
4528         ImportReference impt;
4529         int length;
4530         char[][] tokens = new char[length = identifierLengthStack[identifierLengthPtr--]][];
4531         identifierPtr -= length;
4532         long[] positions = new long[length];
4533         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4534         System.arraycopy(identifierPositionStack, identifierPtr + 1, positions, 0, length);
4535         pushOnAstStack(impt = new ImportReference(tokens, positions, true));
4536
4537         if (currentToken == TokenNameSEMICOLON){
4538                 impt.declarationSourceEnd = scanner.currentPosition - 1;
4539         } else {
4540                 impt.declarationSourceEnd = impt.sourceEnd;
4541         }
4542         impt.declarationEnd = impt.declarationSourceEnd;
4543         //endPosition is just before the ;
4544         impt.declarationSourceStart = intStack[intPtr--];
4545
4546         // recovery
4547         if (currentElement != null){
4548                 lastCheckPoint = impt.declarationSourceEnd+1;
4549                 currentElement = currentElement.add(impt, 0);
4550                 lastIgnoredToken = -1;
4551                 restartRecovery = true; // used to avoid branching back into the regular automaton              
4552         }       
4553 }
4554 protected void consumeUnaryExpression(int op) {
4555         // UnaryExpression ::= '+' PushPosition UnaryExpression
4556         // UnaryExpression ::= '-' PushPosition UnaryExpression
4557         // UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
4558         // UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
4559
4560         //optimize the push/pop
4561
4562         //handle manually the -2147483648 while it is not a real
4563         //computation of an - and 2147483648 (notice that 2147483648
4564         //is Integer.MAX_VALUE+1.....)
4565         //Same for -9223372036854775808L ............
4566
4567         //intStack have the position of the operator
4568
4569         Expression r, exp = expressionStack[expressionPtr];
4570         if (op == MINUS) {
4571                 if ((exp instanceof IntLiteral) && (((IntLiteral) exp).mayRepresentMIN_VALUE())) {
4572                         r = expressionStack[expressionPtr] = new IntLiteralMinValue();
4573                 } else {
4574                         if ((exp instanceof LongLiteral) && (((LongLiteral) exp).mayRepresentMIN_VALUE())) {
4575                                 r = expressionStack[expressionPtr] = new LongLiteralMinValue();
4576                         } else {
4577                                 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4578                         }
4579                 }
4580         } else {
4581                 r = expressionStack[expressionPtr] = new UnaryExpression(exp, op);
4582         }
4583         r.sourceStart = intStack[intPtr--];
4584         r.sourceEnd = exp.sourceEnd;
4585 }
4586 protected void consumeUnaryExpression(int op, boolean post) {
4587         // PreIncrementExpression ::= '++' PushPosition UnaryExpression
4588         // PreDecrementExpression ::= '--' PushPosition UnaryExpression
4589
4590         // ++ and -- operators
4591         //optimize the push/pop
4592
4593         //intStack has the position of the operator when prefix
4594
4595         Expression leftHandSide = expressionStack[expressionPtr];
4596         if (leftHandSide instanceof Reference) {
4597                 // ++foo()++ is unvalid 
4598                 if (post) {
4599                         expressionStack[expressionPtr] = 
4600                                 new PostfixExpression(
4601                                         leftHandSide,
4602                                         IntLiteral.One,
4603                                         op,
4604                                         endStatementPosition); 
4605                 } else {
4606                         expressionStack[expressionPtr] = 
4607                                 new PrefixExpression(
4608                                         leftHandSide,
4609                                         IntLiteral.One,
4610                                         op,
4611                                         intStack[intPtr--]); 
4612                 }
4613         } else {
4614                 //the ++ or the -- is NOT taken into account if code gen proceeds
4615                 if (!post) {
4616                         intPtr--;
4617                 }
4618                 problemReporter().invalidUnaryExpression(leftHandSide);
4619         }
4620 }
4621 protected void consumeVariableDeclarators() {
4622         // VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
4623         optimizedConcatNodeLists();
4624 }
4625 protected void consumeVariableInitializers() {
4626         // VariableInitializers ::= VariableInitializers ',' VariableInitializer
4627         concatExpressionLists();
4628 }
4629 protected TypeReference copyDims(TypeReference typeRef, int dim) {
4630         return typeRef.copyDims(dim);
4631 }
4632 protected FieldDeclaration createFieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4633         return new FieldDeclaration(null, name, sourceStart, sourceEnd);
4634 }
4635
4636 protected LocalDeclaration createLocalDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
4637         return new LocalDeclaration(null, name, sourceStart, sourceEnd);
4638 }
4639
4640 public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
4641
4642         CompilationUnitDeclaration parsedUnit;
4643         boolean old = diet;
4644         try {
4645                 diet = true;
4646                 parsedUnit = parse(sourceUnit, compilationResult);
4647         }
4648         finally {
4649                 diet = old;
4650         }
4651         return parsedUnit;
4652 }
4653 protected void dispatchDeclarationInto(int length) {
4654         /* they are length on astStack that should go into
4655            methods fields constructors lists of the typeDecl
4656
4657            Return if there is a constructor declaration in the methods declaration */
4658            
4659         
4660         // Looks for the size of each array . 
4661
4662         if (length == 0)
4663                 return;
4664         int[] flag = new int[length + 1]; //plus one -- see <HERE>
4665         int size1 = 0, size2 = 0, size3 = 0;
4666         for (int i = length - 1; i >= 0; i--) {
4667                 AstNode astNode = astStack[astPtr--];
4668                 if (astNode instanceof AbstractMethodDeclaration) {
4669                         //methods and constructors have been regrouped into one single list
4670                         flag[i] = 3;
4671                         size2++;
4672                 } else {
4673                         if (astNode instanceof TypeDeclaration) {
4674                                 flag[i] = 4;
4675                                 size3++;
4676                         } else {
4677                                 //field
4678                                 flag[i] = 1;
4679                                 size1++;
4680                         }
4681                 }
4682         }
4683
4684         //arrays creation
4685         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
4686         if (size1 != 0)
4687                 typeDecl.fields = new FieldDeclaration[size1];
4688         if (size2 != 0)
4689                 typeDecl.methods = new AbstractMethodDeclaration[size2];
4690         if (size3 != 0)
4691                 typeDecl.memberTypes = new MemberTypeDeclaration[size3];
4692
4693         //arrays fill up
4694         size1 = size2 = size3 = 0;
4695         int flagI = flag[0], start = 0;
4696         int length2;
4697         for (int end = 0; end <= length; end++) //<HERE> the plus one allows to 
4698                 {
4699                 if (flagI != flag[end]) //treat the last element as a ended flag.....
4700                         { //array copy
4701                         switch (flagI) {
4702                                 case 1 :
4703                                         size1 += (length2 = end - start);
4704                                         System.arraycopy(
4705                                                 astStack, 
4706                                                 astPtr + start + 1, 
4707                                                 typeDecl.fields, 
4708                                                 size1 - length2, 
4709                                                 length2); 
4710                                         break;
4711                                 case 3 :
4712                                         size2 += (length2 = end - start);
4713                                         System.arraycopy(
4714                                                 astStack, 
4715                                                 astPtr + start + 1, 
4716                                                 typeDecl.methods, 
4717                                                 size2 - length2, 
4718                                                 length2); 
4719                                         break;
4720                                 case 4 :
4721                                         size3 += (length2 = end - start);
4722                                         System.arraycopy(
4723                                                 astStack, 
4724                                                 astPtr + start + 1, 
4725                                                 typeDecl.memberTypes, 
4726                                                 size3 - length2, 
4727                                                 length2); 
4728                                         break;
4729                         };
4730                         flagI = flag[start = end];
4731                 }
4732         }
4733
4734         if (typeDecl.memberTypes != null) {
4735                 for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
4736                         typeDecl.memberTypes[i].enclosingType = typeDecl;
4737                 }
4738         }
4739 }
4740 protected CompilationUnitDeclaration endParse(int act) {
4741
4742         this.lastAct = act;
4743
4744         if (currentElement != null){
4745                 currentElement.topElement().updateParseTree();
4746                 if (VERBOSE_RECOVERY){
4747                         System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
4748                         System.out.println("--------------------------");                //$NON-NLS-1$
4749                         System.out.println(compilationUnit);            
4750                         System.out.println("----------------------------------"); //$NON-NLS-1$
4751                 }               
4752         } else {
4753                 if (diet & VERBOSE_RECOVERY){
4754                         System.out.print(Util.bind("parser.regularParse"));      //$NON-NLS-1$
4755                         System.out.println("--------------------------");        //$NON-NLS-1$
4756                         System.out.println(compilationUnit);            
4757                         System.out.println("----------------------------------"); //$NON-NLS-1$
4758                 }
4759         }
4760         if (scanner.recordLineSeparator) {
4761                 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
4762         }
4763         return compilationUnit;
4764 }
4765 /*
4766  * Flush annotations defined prior to a given positions.
4767  *
4768  * Note: annotations are stacked in syntactical order
4769  *
4770  * Either answer given <position>, or the end position of a comment line 
4771  * immediately following the <position> (same line)
4772  *
4773  * e.g.
4774  * void foo(){
4775  * } // end of method foo
4776  */
4777  
4778 public int flushAnnotationsDefinedPriorTo(int position) {
4779
4780         int lastAnnotationIndex = scanner.commentPtr;
4781         if (lastAnnotationIndex < 0) return position; // no comment
4782
4783         // compute the index of the first obsolete comment
4784         int index = lastAnnotationIndex;
4785         int validCount = 0;
4786         while (index >= 0){
4787                 int commentEnd = scanner.commentStops[index];
4788                 if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
4789                 if (commentEnd <= position){
4790                         break;
4791                 }
4792                 index--;
4793                 validCount++;
4794         }
4795         // if the source at <position> is immediately followed by a line comment, then
4796         // flush this comment and shift <position> to the comment end.
4797         if (validCount > 0){
4798                 int immediateCommentEnd = -scanner.commentStops[index+1]; //non-javadoc comment end positions are negative
4799                 if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments
4800                         // is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
4801                         immediateCommentEnd--; // comment end in one char too far
4802                         if (scanner.getLineNumber(position) == scanner.getLineNumber(immediateCommentEnd)){
4803                                 position = immediateCommentEnd;
4804                                 validCount--; // flush this comment
4805                                 index++;
4806                         }
4807                 }
4808         }
4809         // position can be located in the middle of a line break
4810         // this is a bug on Windows platform only.
4811         // http://dev.eclipse.org/bugs/show_bug.cgi?id=10557
4812         char[] source = scanner.source;
4813         
4814         if ((position < source.length)
4815                 && (source[position] == '\r')
4816             && ((position + 1) < source.length)
4817             && (source[position + 1] == '\n')) {
4818                 position++;
4819         }
4820         if (index < 0) return position; // no obsolete comment
4821
4822         if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
4823                 System.arraycopy(scanner.commentStarts, index + 1, scanner.commentStarts, 0, validCount);
4824                 System.arraycopy(scanner.commentStops, index + 1, scanner.commentStops, 0, validCount);         
4825         }
4826         scanner.commentPtr = validCount - 1;
4827         return position;
4828 }
4829 public final int getFirstToken() {
4830         // the first token is a virtual token that
4831         // allows the parser to parse several goals
4832         // even if they aren't LALR(1)....
4833         // Goal ::= '++' CompilationUnit
4834         // Goal ::= '--' MethodBody
4835         // Goal ::= '==' ConstructorBody
4836         // -- Initializer
4837         // Goal ::= '>>' StaticInitializer
4838         // Goal ::= '>>' Block
4839         // -- error recovery
4840         // Goal ::= '>>>' Headers
4841         // Goal ::= '*' BlockStatements
4842         // Goal ::= '*' MethodPushModifiersHeader
4843         // -- JDOM
4844         // Goal ::= '&&' FieldDeclaration
4845         // Goal ::= '||' ImportDeclaration
4846         // Goal ::= '?' PackageDeclaration
4847         // Goal ::= '+' TypeDeclaration
4848         // Goal ::= '/' GenericMethodDeclaration
4849         // Goal ::= '&' ClassBodyDeclaration
4850         // -- code snippet
4851         // Goal ::= '%' Expression
4852         // -- completion parser
4853         // Goal ::= '!' ConstructorBlockStatementsopt
4854         // Goal ::= '~' BlockStatementsopt
4855         
4856         return firstToken;
4857 }
4858 /*
4859  * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
4860  * The array is a flattened structure: 2*n entries with consecutives start and end positions.
4861  *
4862  * If no JavaDoc is available, then null is answered instead of an empty array.
4863  *
4864  * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
4865  */
4866 public int[] getJavaDocPositions() {
4867
4868         int javadocCount = 0;
4869         for (int i = 0, max = scanner.commentPtr; i <= max; i++){
4870                 // javadoc only (non javadoc comment have negative end positions.)
4871                 if (scanner.commentStops[i] > 0){
4872                         javadocCount++;
4873                 }
4874         }
4875         if (javadocCount == 0) return null;
4876
4877         int[] positions = new int[2*javadocCount];
4878         int index = 0;
4879         for (int i = 0, max = scanner.commentPtr; i <= max; i++){
4880                 // javadoc only (non javadoc comment have negative end positions.)
4881                 if (scanner.commentStops[i] > 0){
4882                         positions[index++] = scanner.commentStarts[i];
4883                         positions[index++] = scanner.commentStops[i]-1; //stop is one over                      
4884                 }
4885         }
4886         return positions;
4887 }
4888         protected void getMethodBodies(CompilationUnitDeclaration unit) {
4889                 //fill the methods bodies in order for the code to be generated
4890
4891                 if (unit == null) return;
4892                 
4893                 if (unit.ignoreMethodBodies) {
4894                         unit.ignoreFurtherInvestigation = true;
4895                         return;
4896                         // if initial diet parse did not work, no need to dig into method bodies.
4897                 }
4898
4899                 //real parse of the method....
4900                 this.scanner.setSource(
4901                         unit.compilationResult.compilationUnit.getContents());
4902                 if (unit.types != null) {
4903                         for (int i = unit.types.length; --i >= 0;)
4904                                 unit.types[i].parseMethod(this, unit);
4905                 }
4906         }
4907 protected TypeReference getTypeReference(int dim) { /* build a Reference on a variable that may be qualified or not
4908 This variable is a type reference and dim will be its dimensions*/
4909
4910         int length;
4911         TypeReference ref;
4912         if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
4913                 // single variable reference
4914                 if (dim == 0) {
4915                         ref = 
4916                                 new SingleTypeReference(
4917                                         identifierStack[identifierPtr], 
4918                                         identifierPositionStack[identifierPtr--]); 
4919                 } else {
4920                         ref = 
4921                                 new ArrayTypeReference(
4922                                         identifierStack[identifierPtr], 
4923                                         dim, 
4924                                         identifierPositionStack[identifierPtr--]); 
4925                         ref.sourceEnd = endPosition;                    
4926                 }
4927         } else {
4928                 if (length < 0) { //flag for precompiled type reference on base types
4929                         ref = TypeReference.baseTypeReference(-length, dim);
4930                         ref.sourceStart = intStack[intPtr--];
4931                         if (dim == 0) {
4932                                 ref.sourceEnd = intStack[intPtr--];
4933                         } else {
4934                                 intPtr--;
4935                                 ref.sourceEnd = endPosition;
4936                         }
4937                 } else { //Qualified variable reference
4938                         char[][] tokens = new char[length][];
4939                         identifierPtr -= length;
4940                         long[] positions = new long[length];
4941                         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4942                         System.arraycopy(
4943                                 identifierPositionStack, 
4944                                 identifierPtr + 1, 
4945                                 positions, 
4946                                 0, 
4947                                 length); 
4948                         if (dim == 0) {
4949                                 ref = new QualifiedTypeReference(tokens, positions);
4950                         } else {
4951                                 ref = new ArrayQualifiedTypeReference(tokens, dim, positions);
4952                                 ref.sourceEnd = endPosition;
4953                         }
4954                 }
4955         };
4956         return ref;
4957 }
4958 protected Expression getTypeReference(Expression exp) {
4959         
4960         exp.bits &= ~AstNode.RestrictiveFlagMASK;
4961         exp.bits |= TYPE;
4962         return exp;
4963 }
4964 protected NameReference getUnspecifiedReference() {
4965         /* build a (unspecified) NameReference which may be qualified*/
4966
4967         int length;
4968         NameReference ref;
4969         if ((length = identifierLengthStack[identifierLengthPtr--]) == 1)
4970                 // single variable reference
4971                 ref = 
4972                         new SingleNameReference(
4973                                 identifierStack[identifierPtr], 
4974                                 identifierPositionStack[identifierPtr--]); 
4975         else
4976                 //Qualified variable reference
4977                 {
4978                 char[][] tokens = new char[length][];
4979                 identifierPtr -= length;
4980                 System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
4981                 ref = 
4982                         new QualifiedNameReference(tokens, 
4983                                 (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
4984                                 (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
4985         };
4986         return ref;
4987 }
4988 protected NameReference getUnspecifiedReferenceOptimized() {
4989         /* build a (unspecified) NameReference which may be qualified
4990         The optimization occurs for qualified reference while we are
4991         certain in this case the last item of the qualified name is
4992         a field access. This optimization is IMPORTANT while it results
4993         that when a NameReference is build, the type checker should always
4994         look for that it is not a type reference */
4995
4996         int length;
4997         NameReference ref;
4998         if ((length = identifierLengthStack[identifierLengthPtr--]) == 1) {
4999                 // single variable reference
5000                 ref = 
5001                         new SingleNameReference(
5002                                 identifierStack[identifierPtr], 
5003                                 identifierPositionStack[identifierPtr--]); 
5004                 ref.bits &= ~AstNode.RestrictiveFlagMASK;
5005                 ref.bits |= LOCAL | FIELD;
5006                 return ref;
5007         }
5008
5009         //Qualified-variable-reference
5010         //In fact it is variable-reference DOT field-ref , but it would result in a type
5011         //conflict tha can be only reduce by making a superclass (or inetrface ) between
5012         //nameReference and FiledReference or putting FieldReference under NameReference
5013         //or else..........This optimisation is not really relevant so just leave as it is
5014
5015         char[][] tokens = new char[length][];
5016         identifierPtr -= length;
5017         System.arraycopy(identifierStack, identifierPtr + 1, tokens, 0, length);
5018         ref = new QualifiedNameReference(
5019                         tokens, 
5020                         (int) (identifierPositionStack[identifierPtr + 1] >> 32), // sourceStart
5021                         (int) identifierPositionStack[identifierPtr + length]); // sourceEnd
5022         ref.bits &= ~AstNode.RestrictiveFlagMASK;
5023         ref.bits |= LOCAL | FIELD;
5024         return ref;
5025 }
5026 public void goForBlockStatementsOrMethodHeaders() {
5027         //tells the scanner to go for block statements or method headers parsing 
5028
5029         firstToken = TokenNameMULTIPLY;
5030         scanner.recordLineSeparator = false;
5031 }
5032 public void goForClassBodyDeclarations() {
5033         //tells the scanner to go for any body declarations parsing
5034
5035         firstToken = TokenNameAND;
5036         scanner.recordLineSeparator = true;
5037 }
5038 public void goForCompilationUnit(){
5039         //tells the scanner to go for compilation unit parsing
5040
5041         firstToken = TokenNamePLUS_PLUS ;
5042         scanner.linePtr = -1;   
5043         scanner.recordLineSeparator = true;
5044         scanner.currentLine= null;
5045         scanner.lines= new ArrayList();
5046 }
5047 public void goForConstructorBody(){
5048         //tells the scanner to go for compilation unit parsing
5049
5050         firstToken = TokenNameEQUAL_EQUAL ;
5051         scanner.recordLineSeparator = false;
5052 }
5053 public void goForExpression() {
5054         //tells the scanner to go for an expression parsing
5055
5056         firstToken = TokenNameREMAINDER;
5057         scanner.recordLineSeparator = false;
5058 }
5059 public void goForFieldDeclaration(){
5060         //tells the scanner to go for field declaration parsing
5061
5062         firstToken = TokenNameAND_AND ;
5063         scanner.recordLineSeparator = true;
5064 }
5065 public void goForGenericMethodDeclaration(){
5066         //tells the scanner to go for generic method declarations parsing
5067
5068         firstToken = TokenNameDIVIDE;
5069         scanner.recordLineSeparator = true;
5070 }
5071 public void goForHeaders(){
5072         //tells the scanner to go for headers only parsing
5073
5074         firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
5075         scanner.recordLineSeparator = true;
5076 }
5077 public void goForImportDeclaration(){
5078         //tells the scanner to go for import declaration parsing
5079
5080         firstToken = TokenNameOR_OR ;
5081         scanner.recordLineSeparator = true;
5082 }
5083 public void goForInitializer(){
5084         //tells the scanner to go for initializer parsing
5085
5086         firstToken = TokenNameRIGHT_SHIFT ;
5087         scanner.recordLineSeparator = false;
5088 }
5089 public void goForMethodBody(){
5090         //tells the scanner to go for method body parsing
5091
5092         firstToken = TokenNameMINUS_MINUS ;
5093         scanner.recordLineSeparator = false;
5094 }
5095 public void goForPackageDeclaration() {
5096         //tells the scanner to go for package declaration parsing
5097
5098         firstToken = TokenNameQUESTION;
5099         scanner.recordLineSeparator = true;
5100 }
5101 public void goForTypeDeclaration() {
5102         //tells the scanner to go for type (interface or class) declaration parsing
5103
5104         firstToken = TokenNamePLUS;
5105         scanner.recordLineSeparator = true;
5106 }
5107 public final static void grammar(){
5108 /*
5109 --main options
5110 %options ACTION, AN=JavaAction.java, GP=java, 
5111 %options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
5112 %options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE=TIME , 
5113
5114 --error recovering options.....
5115 %options ERROR_MAPS 
5116
5117 --grammar understanding options
5118 %options first follow
5119 %options TRACE=FULL ,
5120 %options VERBOSE
5121
5122 --Usefull macros helping reading/writing semantic actions
5123 $Define 
5124 $putCase 
5125 /.    case $rule_number : // System.out.println("$rule_text");  
5126                    ./
5127
5128 $break
5129 /. 
5130                         break ;
5131 ./
5132
5133 -- here it starts really ------------------------------------------
5134 $Terminals
5135
5136         Identifier
5137
5138         abstract assert boolean break byte case catch char class 
5139         continue default do double else extends false final finally float
5140         for if implements import instanceof int
5141         interface long native new null package private
5142         protected public return short static strictfp super switch
5143         synchronized this throw throws transient true try void
5144         volatile while
5145
5146         IntegerLiteral
5147         LongLiteral
5148         FloatingPointLiteral
5149         DoubleLiteral
5150         CharacterLiteral
5151         StringLiteral
5152
5153         PLUS_PLUS
5154         MINUS_MINUS
5155         EQUAL_EQUAL
5156         LESS_EQUAL
5157         GREATER_EQUAL
5158         NOT_EQUAL
5159         LEFT_SHIFT
5160         RIGHT_SHIFT
5161         UNSIGNED_RIGHT_SHIFT
5162         PLUS_EQUAL
5163         MINUS_EQUAL
5164         MULTIPLY_EQUAL
5165         DIVIDE_EQUAL
5166         AND_EQUAL
5167         OR_EQUAL
5168         XOR_EQUAL
5169         REMAINDER_EQUAL
5170         LEFT_SHIFT_EQUAL
5171         RIGHT_SHIFT_EQUAL
5172         UNSIGNED_RIGHT_SHIFT_EQUAL
5173         OR_OR
5174         AND_AND
5175         PLUS
5176         MINUS
5177         NOT
5178         REMAINDER
5179         XOR
5180         AND
5181         MULTIPLY
5182         OR
5183         TWIDDLE
5184         DIVIDE
5185         GREATER
5186         LESS
5187         LPAREN
5188         RPAREN
5189         LBRACE
5190         RBRACE
5191         LBRACKET
5192         RBRACKET
5193         SEMICOLON
5194         QUESTION
5195         COLON
5196         COMMA
5197         DOT
5198         EQUAL
5199
5200 --    BodyMarker
5201
5202 $Alias
5203
5204         '++'   ::= PLUS_PLUS
5205         '--'   ::= MINUS_MINUS
5206         '=='   ::= EQUAL_EQUAL
5207         '<='   ::= LESS_EQUAL
5208         '>='   ::= GREATER_EQUAL
5209         '!='   ::= NOT_EQUAL
5210         '<<'   ::= LEFT_SHIFT
5211         '>>'   ::= RIGHT_SHIFT
5212         '>>>'  ::= UNSIGNED_RIGHT_SHIFT
5213         '+='   ::= PLUS_EQUAL
5214         '-='   ::= MINUS_EQUAL
5215         '*='   ::= MULTIPLY_EQUAL
5216         '/='   ::= DIVIDE_EQUAL
5217         '&='   ::= AND_EQUAL
5218         '|='   ::= OR_EQUAL
5219         '^='   ::= XOR_EQUAL
5220         '%='   ::= REMAINDER_EQUAL
5221         '<<='  ::= LEFT_SHIFT_EQUAL
5222         '>>='  ::= RIGHT_SHIFT_EQUAL
5223         '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
5224         '||'   ::= OR_OR
5225         '&&'   ::= AND_AND
5226
5227         '+'    ::= PLUS
5228         '-'    ::= MINUS
5229         '!'    ::= NOT
5230         '%'    ::= REMAINDER
5231         '^'    ::= XOR
5232         '&'    ::= AND
5233         '*'    ::= MULTIPLY
5234         '|'    ::= OR
5235         '~'    ::= TWIDDLE
5236         '/'    ::= DIVIDE
5237         '>'    ::= GREATER
5238         '<'    ::= LESS
5239         '('    ::= LPAREN
5240         ')'    ::= RPAREN
5241         '{'    ::= LBRACE
5242         '}'    ::= RBRACE
5243         '['    ::= LBRACKET
5244         ']'    ::= RBRACKET
5245         ';'    ::= SEMICOLON
5246         '?'    ::= QUESTION
5247         ':'    ::= COLON
5248         ','    ::= COMMA
5249         '.'    ::= DOT
5250         '='    ::= EQUAL
5251         
5252 $Start
5253         Goal
5254
5255 $Rules
5256
5257 /. // This method is part of an automatic generation : do NOT edit-modify  
5258 protected void consumeRule(int act) {
5259   switch ( act ) {
5260 ./
5261
5262
5263
5264 Goal ::= '++' CompilationUnit
5265 Goal ::= '--' MethodBody
5266 Goal ::= '==' ConstructorBody
5267 -- Initializer
5268 Goal ::= '>>' StaticInitializer
5269 Goal ::= '>>' Initializer
5270 -- error recovery
5271 Goal ::= '>>>' Headers
5272 Goal ::= '*' BlockStatements
5273 Goal ::= '*' MethodPushModifiersHeader
5274 Goal ::= '*' CatchHeader
5275 -- JDOM
5276 Goal ::= '&&' FieldDeclaration
5277 Goal ::= '||' ImportDeclaration
5278 Goal ::= '?' PackageDeclaration
5279 Goal ::= '+' TypeDeclaration
5280 Goal ::= '/' GenericMethodDeclaration
5281 Goal ::= '&' ClassBodyDeclaration
5282 -- code snippet
5283 Goal ::= '%' Expression
5284 -- completion parser
5285 Goal ::= '!' ConstructorBlockStatementsopt
5286 Goal ::= '~' BlockStatementsopt
5287
5288 Literal -> IntegerLiteral
5289 Literal -> LongLiteral
5290 Literal -> FloatingPointLiteral
5291 Literal -> DoubleLiteral
5292 Literal -> CharacterLiteral
5293 Literal -> StringLiteral
5294 Literal -> null
5295 Literal -> BooleanLiteral
5296 BooleanLiteral -> true
5297 BooleanLiteral -> false
5298
5299 -------------------------------------------------------------
5300 -------------------------------------------------------------
5301 --a Type results in both a push of its dimension(s) and its name(s).
5302
5303 Type ::= PrimitiveType
5304  /.$putCase consumePrimitiveType(); $break ./
5305 Type -> ReferenceType
5306
5307 PrimitiveType -> NumericType
5308 NumericType -> IntegralType
5309 NumericType -> FloatingPointType
5310
5311 PrimitiveType -> 'boolean'
5312 PrimitiveType -> 'void'
5313 IntegralType -> 'byte'
5314 IntegralType -> 'short'
5315 IntegralType -> 'int'
5316 IntegralType -> 'long'
5317 IntegralType -> 'char'
5318 FloatingPointType -> 'float'
5319 FloatingPointType -> 'double'
5320
5321 ReferenceType ::= ClassOrInterfaceType
5322 /.$putCase consumeReferenceType();  $break ./
5323 ReferenceType -> ArrayType -- here a push of dimensions is done, that explains the two previous push 0
5324
5325 ClassOrInterfaceType -> Name
5326
5327 --
5328 -- These rules have been rewritten to avoid some conflicts introduced
5329 -- by adding the 1.1 features
5330 --
5331 -- ArrayType ::= PrimitiveType '[' ']'
5332 -- ArrayType ::= Name '[' ']'
5333 -- ArrayType ::= ArrayType '[' ']'
5334 --
5335
5336 ArrayType ::= PrimitiveType Dims
5337 ArrayType ::= Name Dims
5338
5339 ClassType -> ClassOrInterfaceType
5340
5341
5342 --------------------------------------------------------------
5343 --------------------------------------------------------------
5344
5345 Name -> SimpleName
5346 Name -> QualifiedName
5347
5348 SimpleName -> 'Identifier'
5349
5350 QualifiedName ::= Name '.' SimpleName 
5351 /.$putCase consumeQualifiedName(); $break ./
5352
5353 CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt
5354 /.$putCase consumeCompilationUnit(); $break ./
5355
5356 EnterCompilationUnit ::= $empty
5357 /.$putCase consumeEnterCompilationUnit(); $break ./
5358
5359 Headers -> Header
5360 Headers ::= Headers Header
5361
5362 Header -> ImportDeclaration
5363 Header -> PackageDeclaration
5364 Header -> ClassHeader
5365 Header -> InterfaceHeader
5366 Header -> StaticInitializer
5367 Header -> MethodHeader
5368 Header -> ConstructorHeader
5369 Header -> FieldDeclaration
5370 Header -> AllocationHeader
5371
5372 CatchHeader ::= 'catch' '(' FormalParameter ')' '{'
5373 /.$putCase consumeCatchHeader(); $break ./
5374
5375 ImportDeclarations -> ImportDeclaration
5376 ImportDeclarations ::= ImportDeclarations ImportDeclaration 
5377 /.$putCase consumeImportDeclarations(); $break ./
5378
5379 TypeDeclarations -> TypeDeclaration
5380 TypeDeclarations ::= TypeDeclarations TypeDeclaration
5381 /.$putCase consumeTypeDeclarations(); $break ./
5382
5383 PackageDeclaration ::= PackageDeclarationName ';'
5384 /.$putCase  consumePackageDeclaration(); $break ./
5385
5386 PackageDeclarationName ::= 'package' Name
5387 /.$putCase  consumePackageDeclarationName(); $break ./
5388
5389 ImportDeclaration -> SingleTypeImportDeclaration
5390 ImportDeclaration -> TypeImportOnDemandDeclaration
5391
5392 SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
5393 /.$putCase consumeSingleTypeImportDeclaration(); $break ./
5394                           
5395 SingleTypeImportDeclarationName ::= 'import' Name
5396 /.$putCase consumeSingleTypeImportDeclarationName(); $break ./
5397                           
5398 TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
5399 /.$putCase consumeTypeImportOnDemandDeclaration(); $break ./
5400
5401 TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
5402 /.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
5403
5404 TypeDeclaration -> ClassDeclaration
5405 TypeDeclaration -> InterfaceDeclaration
5406 -- this declaration in part of a list od declaration and we will
5407 -- use and optimized list length calculation process 
5408 -- thus we decrement the number while it will be incremend.....
5409 TypeDeclaration ::= ';' 
5410 /. $putCase consumeEmptyTypeDeclaration(); $break ./
5411
5412 --18.7 Only in the LALR(1) Grammar
5413
5414 Modifiers ::= Modifier
5415 Modifiers ::= Modifiers Modifier
5416
5417 Modifier -> 'public' 
5418 Modifier -> 'protected'
5419 Modifier -> 'private'
5420 Modifier -> 'static'
5421 Modifier -> 'abstract'
5422 Modifier -> 'final'
5423 Modifier -> 'native'
5424 Modifier -> 'synchronized'
5425 Modifier -> 'transient'
5426 Modifier -> 'volatile'
5427 Modifier -> 'strictfp'
5428
5429 --18.8 Productions from 8: Class Declarations
5430 --ClassModifier ::=
5431 --      'abstract'
5432 --    | 'final'
5433 --    | 'public'
5434 --18.8.1 Productions from 8.1: Class Declarations
5435
5436 ClassDeclaration ::= ClassHeader ClassBody
5437 /.$putCase consumeClassDeclaration(); $break ./
5438
5439 ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
5440 /.$putCase consumeClassHeader(); $break ./
5441
5442 ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
5443 /.$putCase consumeClassHeaderName(); $break ./
5444
5445 ClassHeaderExtends ::= 'extends' ClassType
5446 /.$putCase consumeClassHeaderExtends(); $break ./
5447
5448 ClassHeaderImplements ::= 'implements' InterfaceTypeList
5449 /.$putCase consumeClassHeaderImplements(); $break ./
5450
5451 InterfaceTypeList -> InterfaceType
5452 InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
5453 /.$putCase consumeInterfaceTypeList(); $break ./
5454
5455 InterfaceType ::= ClassOrInterfaceType
5456 /.$putCase consumeInterfaceType(); $break ./
5457
5458 ClassBody ::= '{' ClassBodyDeclarationsopt '}'
5459
5460 ClassBodyDeclarations ::= ClassBodyDeclaration
5461 ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
5462 /.$putCase consumeClassBodyDeclarations(); $break ./
5463
5464 ClassBodyDeclaration -> ClassMemberDeclaration
5465 ClassBodyDeclaration -> StaticInitializer
5466 ClassBodyDeclaration -> ConstructorDeclaration
5467 --1.1 feature
5468 ClassBodyDeclaration ::= Diet NestedMethod Block
5469 /.$putCase consumeClassBodyDeclaration(); $break ./
5470 Diet ::= $empty
5471 /.$putCase consumeDiet(); $break./
5472
5473 Initializer ::= Diet NestedMethod Block
5474 /.$putCase consumeClassBodyDeclaration(); $break ./
5475
5476 ClassMemberDeclaration -> FieldDeclaration
5477 ClassMemberDeclaration -> MethodDeclaration
5478 --1.1 feature
5479 ClassMemberDeclaration -> ClassDeclaration
5480 --1.1 feature
5481 ClassMemberDeclaration -> InterfaceDeclaration
5482
5483 -- Empty declarations are not valid Java ClassMemberDeclarations.
5484 -- However, since the current (2/14/97) Java compiler accepts them 
5485 -- (in fact, some of the official tests contain this erroneous
5486 -- syntax)
5487
5488 GenericMethodDeclaration -> MethodDeclaration
5489 GenericMethodDeclaration -> ConstructorDeclaration
5490
5491 ClassMemberDeclaration ::= ';'
5492 /.$putCase consumeEmptyClassMemberDeclaration(); $break./
5493
5494 --18.8.2 Productions from 8.3: Field Declarations
5495 --VariableModifier ::=
5496 --      'public'
5497 --    | 'protected'
5498 --    | 'private'
5499 --    | 'static'
5500 --    | 'final'
5501 --    | 'transient'
5502 --    | 'volatile'
5503
5504 FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
5505 /.$putCase consumeFieldDeclaration(); $break ./
5506
5507 VariableDeclarators -> VariableDeclarator 
5508 VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
5509 /.$putCase consumeVariableDeclarators(); $break ./
5510
5511 VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
5512
5513 VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
5514
5515 EnterVariable ::= $empty
5516 /.$putCase consumeEnterVariable(); $break ./
5517
5518 ExitVariableWithInitialization ::= $empty
5519 /.$putCase consumeExitVariableWithInitialization(); $break ./
5520
5521 ExitVariableWithoutInitialization ::= $empty
5522 /.$putCase consumeExitVariableWithoutInitialization(); $break ./
5523
5524 ForceNoDiet ::= $empty
5525 /.$putCase consumeForceNoDiet(); $break ./
5526 RestoreDiet ::= $empty
5527 /.$putCase consumeRestoreDiet(); $break ./
5528
5529 VariableDeclaratorId ::= 'Identifier' Dimsopt
5530
5531 VariableInitializer -> Expression
5532 VariableInitializer -> ArrayInitializer
5533
5534 --18.8.3 Productions from 8.4: Method Declarations
5535 --MethodModifier ::=
5536 --      'public'
5537 --    | 'protected'
5538 --    | 'private'
5539 --    | 'static'
5540 --    | 'abstract'
5541 --    | 'final'
5542 --    | 'native'
5543 --    | 'synchronized'
5544 --
5545
5546 MethodDeclaration -> AbstractMethodDeclaration
5547 MethodDeclaration ::= MethodHeader MethodBody 
5548 /.$putCase // set to true to consume a method with a body
5549   consumeMethodDeclaration(true);  $break ./
5550
5551 AbstractMethodDeclaration ::= MethodHeader ';'
5552 /.$putCase // set to false to consume a method without body
5553   consumeMethodDeclaration(false); $break ./
5554
5555 MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5556 /.$putCase consumeMethodHeader(); $break ./
5557
5558 MethodPushModifiersHeader ::= MethodPushModifiersHeaderName MethodHeaderParameters MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
5559 /.$putCase consumeMethodHeader(); $break ./
5560
5561 MethodPushModifiersHeaderName ::= Modifiers Type PushModifiers 'Identifier' '(' 
5562 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5563
5564 MethodPushModifiersHeaderName ::= Type PushModifiers 'Identifier' '(' 
5565 /.$putCase consumeMethodPushModifiersHeaderName(); $break ./
5566
5567 MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
5568 /.$putCase consumeMethodHeaderName(); $break ./
5569
5570 MethodHeaderParameters ::= FormalParameterListopt ')'
5571 /.$putCase consumeMethodHeaderParameters(); $break ./
5572
5573 MethodHeaderExtendedDims ::= Dimsopt
5574 /.$putCase consumeMethodHeaderExtendedDims(); $break ./
5575
5576 MethodHeaderThrowsClause ::= 'throws' ClassTypeList
5577 /.$putCase consumeMethodHeaderThrowsClause(); $break ./
5578
5579 ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
5580 /.$putCase consumeConstructorHeader(); $break ./
5581
5582 ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
5583 /.$putCase consumeConstructorHeaderName(); $break ./
5584
5585 FormalParameterList -> FormalParameter
5586 FormalParameterList ::= FormalParameterList ',' FormalParameter
5587 /.$putCase consumeFormalParameterList(); $break ./
5588
5589 --1.1 feature
5590 FormalParameter ::= Modifiersopt Type VariableDeclaratorId
5591 /.$putCase // the boolean is used to know if the modifiers should be reset
5592         consumeFormalParameter(); $break ./
5593
5594 ClassTypeList -> ClassTypeElt
5595 ClassTypeList ::= ClassTypeList ',' ClassTypeElt
5596 /.$putCase consumeClassTypeList(); $break ./
5597
5598 ClassTypeElt ::= ClassType
5599 /.$putCase consumeClassTypeElt(); $break ./
5600
5601
5602 MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
5603 /.$putCase consumeMethodBody(); $break ./
5604
5605 NestedMethod ::= $empty
5606 /.$putCase consumeNestedMethod(); $break ./
5607
5608 --18.8.4 Productions from 8.5: Static Initializers
5609
5610 StaticInitializer ::=  StaticOnly Block
5611 /.$putCase consumeStaticInitializer(); $break./
5612
5613 StaticOnly ::= 'static'
5614 /.$putCase consumeStaticOnly(); $break ./
5615
5616 --18.8.5 Productions from 8.6: Constructor Declarations
5617 --ConstructorModifier ::=
5618 --      'public'
5619 --    | 'protected'
5620 --    | 'private'
5621 --
5622 --
5623 ConstructorDeclaration ::= ConstructorHeader ConstructorBody
5624 /.$putCase consumeConstructorDeclaration() ; $break ./ 
5625
5626 -- These rules are added to be able to parse constructors with no body
5627 ConstructorDeclaration ::= ConstructorHeader ';'
5628 /.$putCase consumeInvalidConstructorDeclaration() ; $break ./ 
5629
5630 -- the rules ExplicitConstructorInvocationopt has been expanded
5631 -- in the rule below in order to make the grammar lalr(1).
5632 -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}'
5633 -- Other inlining has occured into the next rule too....
5634
5635 ConstructorBody ::= NestedMethod  '{' ConstructorBlockStatementsopt '}'
5636 /.$putCase consumeConstructorBody(); $break ./
5637
5638 ConstructorBlockStatementsopt -> BlockStatementsopt
5639
5640 ConstructorBlockStatementsopt -> ExplicitConstructorInvocation
5641
5642 ConstructorBlockStatementsopt ::= ExplicitConstructorInvocation BlockStatements
5643 /.$putCase  consumeConstructorBlockStatements(); $break ./
5644
5645 ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
5646 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.This); $break ./
5647
5648 ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
5649 /.$putCase consumeExplicitConstructorInvocation(0,ExplicitConstructorCall.Super); $break ./
5650
5651 --1.1 feature
5652 ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
5653 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.Super); $break ./
5654
5655 --1.1 feature
5656 ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
5657 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.Super); $break ./
5658
5659 --1.1 feature
5660 ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
5661 /.$putCase consumeExplicitConstructorInvocation(1, ExplicitConstructorCall.This); $break ./
5662
5663 --1.1 feature
5664 ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
5665 /.$putCase consumeExplicitConstructorInvocation(2, ExplicitConstructorCall.This); $break ./
5666
5667 --18.9 Productions from 9: Interface Declarations
5668
5669 --18.9.1 Productions from 9.1: Interface Declarations
5670 --InterfaceModifier ::=
5671 --      'public'
5672 --    | 'abstract'
5673 --
5674 InterfaceDeclaration ::= InterfaceHeader InterfaceBody
5675 /.$putCase consumeInterfaceDeclaration(); $break ./
5676
5677 InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
5678 /.$putCase consumeInterfaceHeader(); $break ./
5679
5680 InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
5681 /.$putCase consumeInterfaceHeaderName(); $break ./
5682
5683 -- This rule will be used to accept inner local interface and then report a relevant error message
5684 InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody
5685
5686 InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
5687 /.$putCase consumeInterfaceHeaderExtends(); $break ./
5688
5689 InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}' 
5690
5691 InterfaceMemberDeclarations -> InterfaceMemberDeclaration
5692 InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
5693 /.$putCase consumeInterfaceMemberDeclarations(); $break ./
5694
5695 --same as for class members
5696 InterfaceMemberDeclaration ::= ';'
5697 /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./
5698
5699 -- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message
5700 InvalidMethodDeclaration -> MethodHeader MethodBody
5701
5702 InterfaceMemberDeclaration -> ConstantDeclaration
5703 InterfaceMemberDeclaration ::= InvalidMethodDeclaration
5704 /.$putCase ignoreMethodBody(); $break ./
5705
5706 -- These rules are added to be able to parse constructors inside interface and then report a relevent error message
5707 InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody
5708 /.$putCase ignoreInvalidConstructorDeclaration(true);  $break ./
5709
5710 InvalidConstructorDeclaration ::= ConstructorHeader ';'
5711 /.$putCase ignoreInvalidConstructorDeclaration(false);  $break ./
5712
5713 InterfaceMemberDeclaration -> AbstractMethodDeclaration
5714 InterfaceMemberDeclaration -> InvalidConstructorDeclaration
5715  
5716 --1.1 feature
5717 InterfaceMemberDeclaration -> ClassDeclaration
5718 --1.1 feature
5719 InterfaceMemberDeclaration -> InterfaceDeclaration
5720
5721 ConstantDeclaration -> FieldDeclaration
5722
5723 ArrayInitializer ::= '{' ,opt '}'
5724 /.$putCase consumeEmptyArrayInitializer(); $break ./
5725 ArrayInitializer ::= '{' VariableInitializers '}'
5726 /.$putCase consumeArrayInitializer(); $break ./
5727 ArrayInitializer ::= '{' VariableInitializers , '}'
5728 /.$putCase consumeArrayInitializer(); $break ./
5729
5730 VariableInitializers ::= VariableInitializer
5731 VariableInitializers ::= VariableInitializers ',' VariableInitializer
5732 /.$putCase consumeVariableInitializers(); $break ./
5733
5734 Block ::= OpenBlock '{' BlockStatementsopt '}'
5735 /.$putCase consumeBlock(); $break ./
5736 OpenBlock ::= $empty
5737 /.$putCase consumeOpenBlock() ; $break ./
5738
5739 BlockStatements -> BlockStatement
5740 BlockStatements ::= BlockStatements BlockStatement
5741 /.$putCase consumeBlockStatements() ; $break ./
5742
5743 BlockStatement -> LocalVariableDeclarationStatement
5744 BlockStatement -> Statement
5745 --1.1 feature
5746 BlockStatement -> ClassDeclaration
5747 BlockStatement ::= InvalidInterfaceDeclaration
5748 /.$putCase ignoreInterfaceDeclaration(); $break ./
5749
5750 LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
5751 /.$putCase consumeLocalVariableDeclarationStatement(); $break ./
5752
5753 LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
5754 /.$putCase consumeLocalVariableDeclaration(); $break ./
5755
5756 -- 1.1 feature
5757 -- The modifiers part of this rule makes the grammar more permissive. 
5758 -- The only modifier here is final. We put Modifiers to allow multiple modifiers
5759 -- This will require to check the validity of the modifier
5760
5761 LocalVariableDeclaration ::= Modifiers Type PushModifiers VariableDeclarators
5762 /.$putCase consumeLocalVariableDeclaration(); $break ./
5763
5764 PushModifiers ::= $empty
5765 /.$putCase consumePushModifiers(); $break ./
5766
5767 Statement -> StatementWithoutTrailingSubstatement
5768 Statement -> LabeledStatement
5769 Statement -> IfThenStatement
5770 Statement -> IfThenElseStatement
5771 Statement -> WhileStatement
5772 Statement -> ForStatement
5773
5774 StatementNoShortIf -> StatementWithoutTrailingSubstatement
5775 StatementNoShortIf -> LabeledStatementNoShortIf
5776 StatementNoShortIf -> IfThenElseStatementNoShortIf
5777 StatementNoShortIf -> WhileStatementNoShortIf
5778 StatementNoShortIf -> ForStatementNoShortIf
5779
5780 StatementWithoutTrailingSubstatement -> AssertStatement
5781 StatementWithoutTrailingSubstatement -> Block
5782 StatementWithoutTrailingSubstatement -> EmptyStatement
5783 StatementWithoutTrailingSubstatement -> ExpressionStatement
5784 StatementWithoutTrailingSubstatement -> SwitchStatement
5785 StatementWithoutTrailingSubstatement -> DoStatement
5786 StatementWithoutTrailingSubstatement -> BreakStatement
5787 StatementWithoutTrailingSubstatement -> ContinueStatement
5788 StatementWithoutTrailingSubstatement -> ReturnStatement
5789 StatementWithoutTrailingSubstatement -> SynchronizedStatement
5790 StatementWithoutTrailingSubstatement -> ThrowStatement
5791 StatementWithoutTrailingSubstatement -> TryStatement
5792
5793 EmptyStatement ::= ';'
5794 /.$putCase consumeEmptyStatement(); $break ./
5795
5796 LabeledStatement ::= 'Identifier' ':' Statement
5797 /.$putCase consumeStatementLabel() ; $break ./
5798
5799 LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
5800 /.$putCase consumeStatementLabel() ; $break ./
5801
5802 ExpressionStatement ::= StatementExpression ';'
5803 /. $putCase consumeExpressionStatement(); $break ./
5804
5805 StatementExpression ::= Assignment
5806 StatementExpression ::= PreIncrementExpression
5807 StatementExpression ::= PreDecrementExpression
5808 StatementExpression ::= PostIncrementExpression
5809 StatementExpression ::= PostDecrementExpression
5810 StatementExpression ::= MethodInvocation
5811 StatementExpression ::= ClassInstanceCreationExpression
5812
5813 IfThenStatement ::=  'if' '(' Expression ')' Statement
5814 /.$putCase consumeStatementIfNoElse(); $break ./
5815
5816 IfThenElseStatement ::=  'if' '(' Expression ')' StatementNoShortIf 'else' Statement
5817 /.$putCase consumeStatementIfWithElse(); $break ./
5818
5819 IfThenElseStatementNoShortIf ::=  'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
5820 /.$putCase consumeStatementIfWithElse(); $break ./
5821
5822 SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
5823 /.$putCase consumeStatementSwitch() ; $break ./
5824
5825 SwitchBlock ::= '{' '}'
5826 /.$putCase consumeEmptySwitchBlock() ; $break ./
5827
5828 SwitchBlock ::= '{' SwitchBlockStatements '}'
5829 SwitchBlock ::= '{' SwitchLabels '}'
5830 SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
5831 /.$putCase consumeSwitchBlock() ; $break ./
5832
5833 SwitchBlockStatements -> SwitchBlockStatement
5834 SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
5835 /.$putCase consumeSwitchBlockStatements() ; $break ./
5836
5837 SwitchBlockStatement ::= SwitchLabels BlockStatements
5838 /.$putCase consumeSwitchBlockStatement() ; $break ./
5839
5840 SwitchLabels -> SwitchLabel
5841 SwitchLabels ::= SwitchLabels SwitchLabel
5842 /.$putCase consumeSwitchLabels() ; $break ./
5843
5844 SwitchLabel ::= 'case' ConstantExpression ':'
5845 /. $putCase consumeCaseLabel(); $break ./
5846
5847 SwitchLabel ::= 'default' ':'
5848 /. $putCase consumeDefaultLabel(); $break ./
5849
5850 WhileStatement ::= 'while' '(' Expression ')' Statement
5851 /.$putCase consumeStatementWhile() ; $break ./
5852
5853 WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
5854 /.$putCase consumeStatementWhile() ; $break ./
5855
5856 DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
5857 /.$putCase consumeStatementDo() ; $break ./
5858
5859 ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
5860 /.$putCase consumeStatementFor() ; $break ./
5861 ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
5862 /.$putCase consumeStatementFor() ; $break ./
5863
5864 --the minus one allows to avoid a stack-to-stack transfer
5865 ForInit ::= StatementExpressionList
5866 /.$putCase consumeForInit() ; $break ./
5867 ForInit -> LocalVariableDeclaration
5868
5869 ForUpdate -> StatementExpressionList
5870
5871 StatementExpressionList -> StatementExpression
5872 StatementExpressionList ::= StatementExpressionList ',' StatementExpression
5873 /.$putCase consumeStatementExpressionList() ; $break ./
5874
5875 -- 1.4 feature
5876 AssertStatement ::= 'assert' Expression ';'
5877 /.$putCase consumeSimpleAssertStatement() ; $break ./
5878
5879 AssertStatement ::= 'assert' Expression ':' Expression ';'
5880 /.$putCase consumeAssertStatement() ; $break ./
5881           
5882 BreakStatement ::= 'break' ';'
5883 /.$putCase consumeStatementBreak() ; $break ./
5884
5885 BreakStatement ::= 'break' Identifier ';'
5886 /.$putCase consumeStatementBreakWithLabel() ; $break ./
5887
5888 ContinueStatement ::= 'continue' ';'
5889 /.$putCase consumeStatementContinue() ; $break ./
5890
5891 ContinueStatement ::= 'continue' Identifier ';'
5892 /.$putCase consumeStatementContinueWithLabel() ; $break ./
5893
5894 ReturnStatement ::= 'return' Expressionopt ';'
5895 /.$putCase consumeStatementReturn() ; $break ./
5896
5897 ThrowStatement ::= 'throw' Expression ';'
5898 /.$putCase consumeStatementThrow();
5899 $break ./
5900
5901 SynchronizedStatement ::= OnlySynchronized '(' Expression ')'    Block
5902 /.$putCase consumeStatementSynchronized(); $break ./
5903 OnlySynchronized ::= 'synchronized'
5904 /.$putCase consumeOnlySynchronized(); $break ./
5905
5906
5907 TryStatement ::= 'try'    Block Catches
5908 /.$putCase consumeStatementTry(false); $break ./
5909 TryStatement ::= 'try'    Block Catchesopt Finally
5910 /.$putCase consumeStatementTry(true); $break ./
5911
5912 Catches -> CatchClause
5913 Catches ::= Catches CatchClause
5914 /.$putCase consumeCatches(); $break ./
5915
5916 CatchClause ::= 'catch' '(' FormalParameter ')'    Block
5917 /.$putCase consumeStatementCatch() ; $break ./
5918
5919 Finally ::= 'finally'    Block
5920
5921 --18.12 Productions from 14: Expressions
5922
5923 --for source positionning purpose
5924 PushLPAREN ::= '('
5925 /.$putCase consumeLeftParen(); $break ./
5926 PushRPAREN ::= ')'
5927 /.$putCase consumeRightParen(); $break ./
5928
5929 Primary -> PrimaryNoNewArray
5930 Primary -> ArrayCreationExpression
5931
5932 PrimaryNoNewArray -> Literal
5933 PrimaryNoNewArray ::= 'this'
5934 /.$putCase consumePrimaryNoNewArrayThis(); $break ./
5935
5936 PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN 
5937 /.$putCase consumePrimaryNoNewArray(); $break ./
5938
5939 PrimaryNoNewArray -> ClassInstanceCreationExpression
5940 PrimaryNoNewArray -> FieldAccess
5941 --1.1 feature
5942 PrimaryNoNewArray ::= Name '.' 'this'
5943 /.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
5944 PrimaryNoNewArray ::= Name '.' 'super'
5945 /.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
5946
5947 --1.1 feature
5948 --PrimaryNoNewArray ::= Type '.' 'class'   
5949 --inline Type in the previous rule in order to make the grammar LL1 instead 
5950 -- of LL2. The result is the 3 next rules.
5951 PrimaryNoNewArray ::= Name '.' 'class'
5952 /.$putCase consumePrimaryNoNewArrayName(); $break ./
5953
5954 PrimaryNoNewArray ::= ArrayType '.' 'class'
5955 /.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
5956
5957 PrimaryNoNewArray ::= PrimitiveType '.' 'class'
5958 /.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
5959
5960 PrimaryNoNewArray -> MethodInvocation
5961 PrimaryNoNewArray -> ArrayAccess
5962
5963 --1.1 feature
5964 --
5965 -- In Java 1.0 a ClassBody could not appear at all in a
5966 -- ClassInstanceCreationExpression.
5967 --
5968
5969 AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
5970 /.$putCase consumeAllocationHeader(); $break ./
5971
5972 ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
5973 /.$putCase consumeClassInstanceCreationExpression(); $break ./
5974 --1.1 feature
5975
5976 ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
5977 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
5978
5979 --1.1 feature
5980 ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
5981 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
5982
5983 ClassInstanceCreationExpressionName ::= Name '.'
5984 /.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
5985
5986 ClassBodyopt ::= $empty --test made using null as contents
5987 /.$putCase consumeClassBodyopt(); $break ./
5988 ClassBodyopt ::= EnterAnonymousClassBody ClassBody
5989
5990 EnterAnonymousClassBody ::= $empty
5991 /.$putCase consumeEnterAnonymousClassBody(); $break ./
5992
5993 ArgumentList ::= Expression
5994 ArgumentList ::= ArgumentList ',' Expression
5995 /.$putCase consumeArgumentList(); $break ./
5996
5997 --Thess rules are re-written in order to be ll1 
5998 --ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer
5999 --ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt 
6000 --ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt
6001 --DimExprs ::= DimExpr
6002 --DimExprs ::= DimExprs DimExpr
6003
6004 ArrayCreationExpression ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializeropt
6005 /.$putCase consumeArrayCreationExpression(); $break ./
6006 ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializeropt
6007 /.$putCase consumeArrayCreationExpression(); $break ./
6008
6009 DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
6010 DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
6011 /.$putCase consumeDimWithOrWithOutExprs(); $break ./
6012
6013 DimWithOrWithOutExpr ::= '[' Expression ']'
6014 DimWithOrWithOutExpr ::= '[' ']'
6015 /. $putCase consumeDimWithOrWithOutExpr(); $break ./
6016 -- -----------------------------------------------
6017
6018 Dims ::= DimsLoop
6019 /. $putCase consumeDims(); $break ./
6020 DimsLoop -> OneDimLoop
6021 DimsLoop ::= DimsLoop OneDimLoop
6022 OneDimLoop ::= '[' ']'
6023 /. $putCase consumeOneDimLoop(); $break ./
6024
6025 FieldAccess ::= Primary '.' 'Identifier'
6026 /.$putCase consumeFieldAccess(false); $break ./
6027
6028 FieldAccess ::= 'super' '.' 'Identifier'
6029 /.$putCase consumeFieldAccess(true); $break ./
6030
6031 MethodInvocation ::= Name '(' ArgumentListopt ')'
6032 /.$putCase consumeMethodInvocationName(); $break ./
6033
6034 MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
6035 /.$putCase consumeMethodInvocationPrimary(); $break ./
6036
6037 MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
6038 /.$putCase consumeMethodInvocationSuper(); $break ./
6039
6040 ArrayAccess ::= Name '[' Expression ']'
6041 /.$putCase consumeArrayAccess(true); $break ./
6042 ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
6043 /.$putCase consumeArrayAccess(false); $break ./
6044
6045 PostfixExpression -> Primary
6046 PostfixExpression ::= Name
6047 /.$putCase consumePostfixExpression(); $break ./
6048 PostfixExpression -> PostIncrementExpression
6049 PostfixExpression -> PostDecrementExpression
6050
6051 PostIncrementExpression ::= PostfixExpression '++'
6052 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,true); $break ./
6053
6054 PostDecrementExpression ::= PostfixExpression '--'
6055 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,true); $break ./
6056
6057 --for source managment purpose
6058 PushPosition ::= $empty
6059  /.$putCase consumePushPosition(); $break ./
6060
6061 UnaryExpression -> PreIncrementExpression
6062 UnaryExpression -> PreDecrementExpression
6063 UnaryExpression ::= '+' PushPosition UnaryExpression
6064 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS); $break ./
6065 UnaryExpression ::= '-' PushPosition UnaryExpression
6066 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS); $break ./
6067 UnaryExpression -> UnaryExpressionNotPlusMinus
6068
6069 PreIncrementExpression ::= '++' PushPosition UnaryExpression
6070 /.$putCase consumeUnaryExpression(OperatorExpression.PLUS,false); $break ./
6071
6072 PreDecrementExpression ::= '--' PushPosition UnaryExpression
6073 /.$putCase consumeUnaryExpression(OperatorExpression.MINUS,false); $break ./
6074
6075 UnaryExpressionNotPlusMinus -> PostfixExpression
6076 UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
6077 /.$putCase consumeUnaryExpression(OperatorExpression.TWIDDLE); $break ./
6078 UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
6079 /.$putCase consumeUnaryExpression(OperatorExpression.NOT); $break ./
6080 UnaryExpressionNotPlusMinus -> CastExpression
6081
6082 CastExpression ::= PushLPAREN PrimitiveType Dimsopt PushRPAREN UnaryExpression
6083 /.$putCase consumeCastExpression(); $break ./
6084  CastExpression ::= PushLPAREN Name Dims PushRPAREN UnaryExpressionNotPlusMinus
6085 /.$putCase consumeCastExpression(); $break ./
6086 -- Expression is here only in order to make the grammar LL1
6087 CastExpression ::= PushLPAREN Expression PushRPAREN UnaryExpressionNotPlusMinus
6088 /.$putCase consumeCastExpressionLL1(); $break ./
6089
6090 MultiplicativeExpression -> UnaryExpression
6091 MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
6092 /.$putCase consumeBinaryExpression(OperatorExpression.MULTIPLY); $break ./
6093 MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
6094 /.$putCase consumeBinaryExpression(OperatorExpression.DIVIDE); $break ./
6095 MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
6096 /.$putCase consumeBinaryExpression(OperatorExpression.REMAINDER); $break ./
6097
6098 AdditiveExpression -> MultiplicativeExpression
6099 AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
6100 /.$putCase consumeBinaryExpression(OperatorExpression.PLUS); $break ./
6101 AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
6102 /.$putCase consumeBinaryExpression(OperatorExpression.MINUS); $break ./
6103
6104 ShiftExpression -> AdditiveExpression
6105 ShiftExpression ::= ShiftExpression '<<'  AdditiveExpression
6106 /.$putCase consumeBinaryExpression(OperatorExpression.LEFT_SHIFT); $break ./
6107 ShiftExpression ::= ShiftExpression '>>'  AdditiveExpression
6108 /.$putCase consumeBinaryExpression(OperatorExpression.RIGHT_SHIFT); $break ./
6109 ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
6110 /.$putCase consumeBinaryExpression(OperatorExpression.UNSIGNED_RIGHT_SHIFT); $break ./
6111
6112 RelationalExpression -> ShiftExpression
6113 RelationalExpression ::= RelationalExpression '<'  ShiftExpression
6114 /.$putCase consumeBinaryExpression(OperatorExpression.LESS); $break ./
6115 RelationalExpression ::= RelationalExpression '>'  ShiftExpression
6116 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER); $break ./
6117 RelationalExpression ::= RelationalExpression '<=' ShiftExpression
6118 /.$putCase consumeBinaryExpression(OperatorExpression.LESS_EQUAL); $break ./
6119 RelationalExpression ::= RelationalExpression '>=' ShiftExpression
6120 /.$putCase consumeBinaryExpression(OperatorExpression.GREATER_EQUAL); $break ./
6121 RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
6122 /.$putCase consumeInstanceOfExpression(OperatorExpression.INSTANCEOF); $break ./
6123
6124 EqualityExpression -> RelationalExpression
6125 EqualityExpression ::= EqualityExpression '==' RelationalExpression
6126 /.$putCase consumeEqualityExpression(OperatorExpression.EQUAL_EQUAL); $break ./
6127 EqualityExpression ::= EqualityExpression '!=' RelationalExpression
6128 /.$putCase consumeEqualityExpression(OperatorExpression.NOT_EQUAL); $break ./
6129
6130 AndExpression -> EqualityExpression
6131 AndExpression ::= AndExpression '&' EqualityExpression
6132 /.$putCase consumeBinaryExpression(OperatorExpression.AND); $break ./
6133
6134 ExclusiveOrExpression -> AndExpression
6135 ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
6136 /.$putCase consumeBinaryExpression(OperatorExpression.XOR); $break ./
6137
6138 InclusiveOrExpression -> ExclusiveOrExpression
6139 InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
6140 /.$putCase consumeBinaryExpression(OperatorExpression.OR); $break ./
6141
6142 ConditionalAndExpression -> InclusiveOrExpression
6143 ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
6144 /.$putCase consumeBinaryExpression(OperatorExpression.AND_AND); $break ./
6145
6146 ConditionalOrExpression -> ConditionalAndExpression
6147 ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
6148 /.$putCase consumeBinaryExpression(OperatorExpression.OR_OR); $break ./
6149
6150 ConditionalExpression -> ConditionalOrExpression
6151 ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
6152 /.$putCase consumeConditionalExpression(OperatorExpression.QUESTIONCOLON) ; $break ./
6153
6154 AssignmentExpression -> ConditionalExpression
6155 AssignmentExpression -> Assignment
6156
6157 Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
6158 /.$putCase consumeAssignment(); $break ./
6159
6160 -- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
6161 InvalidArrayInitializerAssignement ::= LeftHandSide AssignmentOperator ArrayInitializer
6162 Assignment ::= InvalidArrayInitializerAssignement
6163 /.$putcase ignoreExpressionAssignment();$break ./
6164
6165 LeftHandSide ::= Name
6166 /.$putCase consumeLeftHandSide(); $break ./
6167 LeftHandSide -> FieldAccess
6168 LeftHandSide -> ArrayAccess
6169
6170 AssignmentOperator ::= '='
6171 /.$putCase consumeAssignmentOperator(EQUAL); $break ./
6172 AssignmentOperator ::= '*='
6173 /.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
6174 AssignmentOperator ::= '/='
6175 /.$putCase consumeAssignmentOperator(DIVIDE); $break ./
6176 AssignmentOperator ::= '%='
6177 /.$putCase consumeAssignmentOperator(REMAINDER); $break ./
6178 AssignmentOperator ::= '+='
6179 /.$putCase consumeAssignmentOperator(PLUS); $break ./
6180 AssignmentOperator ::= '-='
6181 /.$putCase consumeAssignmentOperator(MINUS); $break ./
6182 AssignmentOperator ::= '<<='
6183 /.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
6184 AssignmentOperator ::= '>>='
6185 /.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
6186 AssignmentOperator ::= '>>>='
6187 /.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
6188 AssignmentOperator ::= '&='
6189 /.$putCase consumeAssignmentOperator(AND); $break ./
6190 AssignmentOperator ::= '^='
6191 /.$putCase consumeAssignmentOperator(XOR); $break ./
6192 AssignmentOperator ::= '|='
6193 /.$putCase consumeAssignmentOperator(OR); $break ./
6194
6195 Expression -> AssignmentExpression
6196
6197 ConstantExpression -> Expression
6198
6199 -- The following rules are for optional nonterminals.
6200 --
6201
6202 PackageDeclarationopt -> $empty 
6203 PackageDeclarationopt -> PackageDeclaration
6204
6205 ClassHeaderExtendsopt ::= $empty
6206 ClassHeaderExtendsopt -> ClassHeaderExtends
6207
6208 Expressionopt ::= $empty
6209 /.$putCase consumeEmptyExpression(); $break ./
6210 Expressionopt -> Expression
6211
6212
6213 ---------------------------------------------------------------------------------------
6214 --
6215 -- The rules below are for optional terminal symbols.  An optional comma,
6216 -- is only used in the context of an array initializer - It is a
6217 -- "syntactic sugar" that otherwise serves no other purpose. By contrast,
6218 -- an optional identifier is used in the definition of a break and 
6219 -- continue statement. When the identifier does not appear, a NULL
6220 -- is produced. When the identifier is present, the user should use the
6221 -- corresponding TOKEN(i) method. See break statement as an example.
6222 --
6223 ---------------------------------------------------------------------------------------
6224
6225 ,opt -> $empty
6226 ,opt -> ,
6227
6228 ImportDeclarationsopt ::= $empty
6229 /.$putCase consumeEmptyImportDeclarationsopt(); $break ./
6230 ImportDeclarationsopt ::= ImportDeclarations
6231 /.$putCase consumeImportDeclarationsopt(); $break ./
6232
6233
6234 TypeDeclarationsopt ::= $empty
6235 /.$putCase consumeEmptyTypeDeclarationsopt(); $break ./
6236 TypeDeclarationsopt ::= TypeDeclarations
6237 /.$putCase consumeTypeDeclarationsopt(); $break ./
6238
6239 ClassBodyDeclarationsopt ::= $empty
6240 /.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
6241 ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
6242 /.$putCase consumeClassBodyDeclarationsopt(); $break ./
6243
6244 Modifiersopt ::= $empty 
6245 /. $putCase consumeDefaultModifiers(); $break ./
6246 Modifiersopt ::= Modifiers 
6247 /.$putCase consumeModifiers(); $break ./ 
6248
6249 BlockStatementsopt ::= $empty
6250 /.$putCase consumeEmptyBlockStatementsopt(); $break ./
6251 BlockStatementsopt -> BlockStatements
6252
6253 Dimsopt ::= $empty
6254 /. $putCase consumeEmptyDimsopt(); $break ./
6255 Dimsopt -> Dims
6256
6257 ArgumentListopt ::= $empty
6258 /. $putCase consumeEmptyArgumentListopt(); $break ./
6259 ArgumentListopt -> ArgumentList
6260
6261 MethodHeaderThrowsClauseopt ::= $empty
6262 MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
6263    
6264 FormalParameterListopt ::= $empty
6265 /.$putcase consumeFormalParameterListopt(); $break ./
6266 FormalParameterListopt -> FormalParameterList
6267
6268 ClassHeaderImplementsopt ::= $empty
6269 ClassHeaderImplementsopt -> ClassHeaderImplements
6270
6271 InterfaceMemberDeclarationsopt ::= $empty
6272 /. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
6273 InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
6274 /. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
6275
6276 NestedType ::= $empty 
6277 /.$putCase consumeNestedType(); $break./
6278
6279 ForInitopt ::= $empty
6280 /. $putCase consumeEmptyForInitopt(); $break ./
6281 ForInitopt -> ForInit
6282
6283 ForUpdateopt ::= $empty
6284 /. $putCase consumeEmptyForUpdateopt(); $break ./
6285  ForUpdateopt -> ForUpdate
6286
6287 InterfaceHeaderExtendsopt ::= $empty
6288 InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
6289
6290 Catchesopt ::= $empty
6291 /. $putCase consumeEmptyCatchesopt(); $break ./
6292 Catchesopt -> Catches
6293
6294 ArrayInitializeropt ::= $empty
6295 /. $putCase consumeEmptyArrayInitializeropt(); $break ./
6296 ArrayInitializeropt -> ArrayInitializer
6297
6298 /.      }
6299 } ./
6300
6301 ---------------------------------------------------------------------------------------
6302
6303 $names
6304
6305 -- BodyMarker ::= '"class Identifier { ... MethodHeader "'
6306
6307 -- void ::= 'void'
6308
6309 PLUS_PLUS ::=    '++'   
6310 MINUS_MINUS ::=    '--'   
6311 EQUAL_EQUAL ::=    '=='   
6312 LESS_EQUAL ::=    '<='   
6313 GREATER_EQUAL ::=    '>='   
6314 NOT_EQUAL ::=    '!='   
6315 LEFT_SHIFT ::=    '<<'   
6316 RIGHT_SHIFT ::=    '>>'   
6317 UNSIGNED_RIGHT_SHIFT ::=    '>>>'  
6318 PLUS_EQUAL ::=    '+='   
6319 MINUS_EQUAL ::=    '-='   
6320 MULTIPLY_EQUAL ::=    '*='   
6321 DIVIDE_EQUAL ::=    '/='   
6322 AND_EQUAL ::=    '&='   
6323 OR_EQUAL ::=    '|='   
6324 XOR_EQUAL ::=    '^='   
6325 REMAINDER_EQUAL ::=    '%='   
6326 LEFT_SHIFT_EQUAL ::=    '<<='  
6327 RIGHT_SHIFT_EQUAL ::=    '>>='  
6328 UNSIGNED_RIGHT_SHIFT_EQUAL ::=    '>>>=' 
6329 OR_OR ::=    '||'   
6330 AND_AND ::=    '&&'   
6331
6332 PLUS ::=    '+'    
6333 MINUS ::=    '-'    
6334 NOT ::=    '!'    
6335 REMAINDER ::=    '%'    
6336 XOR ::=    '^'    
6337 AND ::=    '&'    
6338 MULTIPLY ::=    '*'    
6339 OR ::=    '|'    
6340 TWIDDLE ::=    '~'    
6341 DIVIDE ::=    '/'    
6342 GREATER ::=    '>'    
6343 LESS ::=    '<'    
6344 LPAREN ::=    '('    
6345 RPAREN ::=    ')'    
6346 LBRACE ::=    '{'    
6347 RBRACE ::=    '}'    
6348 LBRACKET ::=    '['    
6349 RBRACKET ::=    ']'    
6350 SEMICOLON ::=    ';'    
6351 QUESTION ::=    '?'    
6352 COLON ::=    ':'    
6353 COMMA ::=    ','    
6354 DOT ::=    '.'    
6355 EQUAL ::=    '='    
6356
6357 $end
6358 -- need a carriage return after the $end
6359 */
6360 }
6361 protected void ignoreExpressionAssignment() {
6362         // Assignment ::= InvalidArrayInitializerAssignement
6363         // encoded operator would be: intStack[intPtr]
6364         intPtr--;
6365         ArrayInitializer arrayInitializer = (ArrayInitializer) expressionStack[expressionPtr--];
6366         expressionLengthPtr -- ;
6367         // report a syntax error and abort parsing
6368         problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);      
6369 }
6370 protected void ignoreInterfaceDeclaration() {
6371         // BlockStatement ::= InvalidInterfaceDeclaration
6372         //InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
6373
6374         // length declarations
6375         int length;
6376         if ((length = astLengthStack[astLengthPtr--]) != 0) {
6377                 //there are length declarations
6378                 //dispatch according to the type of the declarations
6379                 dispatchDeclarationInto(length);
6380         }
6381         
6382         flushAnnotationsDefinedPriorTo(endStatementPosition);
6383
6384         // report the problem and continue parsing
6385         TypeDeclaration typeDecl = (TypeDeclaration) astStack[astPtr];
6386         typeDecl.bodyEnd = endStatementPosition;
6387         problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
6388
6389         // mark fields and initializer with local type mark if needed
6390         markFieldsWithLocalType(typeDecl);
6391
6392         // remove the ast node created in interface header
6393         astPtr--;       
6394         // Don't create an astnode for this inner interface, but have to push
6395         // a 0 on the astLengthStack to be consistent with the reduction made
6396         // at the end of the method:
6397         // public void parse(MethodDeclaration md, CompilationUnitDeclaration unit)
6398         pushOnAstLengthStack(0);
6399 }
6400 protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
6401         // InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
6402         // InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
6403
6404         /*
6405         astStack : modifiers arguments throws statements
6406         identifierStack : name
6407          ==>
6408         astStack : MethodDeclaration
6409         identifierStack :
6410         */
6411
6412         //must provide a default constructor call when needed
6413
6414         if (hasBody) {
6415                 // pop the position of the {  (body of the method) pushed in block decl
6416                 intPtr--;
6417         }
6418
6419         //statements
6420         if (hasBody) {
6421                 realBlockPtr--;
6422         }
6423
6424         int length;
6425         if (hasBody && ((length = astLengthStack[astLengthPtr--]) != 0)) {
6426                 astPtr -= length;
6427         }
6428 }
6429 protected void ignoreMethodBody() {
6430         // InterfaceMemberDeclaration ::= InvalidMethodDeclaration
6431
6432         /*
6433         astStack : modifiers arguments throws statements
6434         identifierStack : type name
6435         intStack : dim dim dim
6436          ==>
6437         astStack : MethodDeclaration
6438         identifierStack :
6439         intStack : 
6440         */
6441
6442         // pop the position of the {  (body of the method) pushed in block decl
6443         intPtr--;
6444         // retrieve end position of method declarator
6445
6446         //statements
6447         realBlockPtr--;
6448         int length;
6449         if ((length = astLengthStack[astLengthPtr--]) != 0) {
6450                 astPtr -= length;
6451         }
6452
6453         //watch for } that could be given as a unicode ! ( u007D is '}' )
6454         MethodDeclaration md = (MethodDeclaration) astStack[astPtr];
6455         md.bodyEnd = endPosition;
6456         md.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition);
6457
6458         // report the problem and continue the parsing - narrowing the problem onto the method
6459         problemReporter().abstractMethodNeedingNoBody(md);
6460 }
6461 public void initialize() {
6462         //positionning the parser for a new compilation unit
6463         //avoiding stack reallocation and all that....
6464         astPtr = -1;
6465         astLengthPtr = -1;
6466         expressionPtr = -1;
6467         expressionLengthPtr = -1;
6468         identifierPtr = -1;     
6469         identifierLengthPtr     = -1;
6470         intPtr = -1;
6471         nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
6472         variablesCounter[nestedType] = 0;
6473         dimensions = 0 ;
6474         realBlockPtr = -1;
6475         compilationUnit = null;
6476         referenceContext = null;
6477         endStatementPosition = 0;
6478
6479         //remove objects from stack too, while the same parser/compiler couple is
6480         //re-used between two compilations ....
6481         
6482         int astLength = astStack.length;
6483         if (noAstNodes.length < astLength){
6484                 noAstNodes = new AstNode[astLength];
6485                 //System.out.println("Resized AST stacks : "+ astLength);
6486                 
6487         }
6488         System.arraycopy(noAstNodes, 0, astStack, 0, astLength);
6489
6490         int expressionLength = expressionStack.length;
6491         if (noExpressions.length < expressionLength){
6492                 noExpressions = new Expression[expressionLength];
6493                 //System.out.println("Resized EXPR stacks : "+ expressionLength);
6494         }
6495         System.arraycopy(noExpressions, 0, expressionStack, 0, expressionLength);
6496
6497         // reset scanner state
6498         scanner.commentPtr = -1;
6499         scanner.eofPosition = Integer.MAX_VALUE;
6500
6501         resetModifiers();
6502
6503         // recovery
6504         lastCheckPoint = -1;
6505         currentElement = null;
6506         restartRecovery = false;
6507         hasReportedError = false;
6508         recoveredStaticInitializerStart = 0;
6509         lastIgnoredToken = -1;
6510         lastErrorEndPosition = -1;
6511         listLength = 0;
6512 }
6513 public void initializeScanner(){
6514         this.scanner = new Scanner(false, false, this.problemReporter.options.getNonExternalizedStringLiteralSeverity() != ProblemSeverities.Ignore , this.assertMode);
6515 }
6516 public final static void initTables() throws java.io.IOException {
6517
6518         final String prefix = FILEPREFIX;
6519         int i = 0;
6520         lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6521         char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6522         check_table = new short[chars.length];
6523         for (int c = chars.length; c-- > 0;) {
6524                 check_table[c] = (short) (chars[c] - 32768);
6525         }
6526         asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6527         asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6528         symbol_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
6529         action = lhs;
6530 }
6531 public final void jumpOverMethodBody() {
6532         //on diet parsing.....do not buffer method statements
6533
6534         //the scanner.diet is reinitialized to false
6535         //automatically by the scanner once it has jumped over
6536         //the statements
6537
6538         if (diet && (dietInt == 0))
6539                 scanner.diet = true;
6540 }
6541 protected void markCurrentMethodWithLocalType() {
6542         if (this.currentElement != null) return; // this is already done in the recovery code
6543         for (int i = this.astPtr; i >= 0; i--) {
6544                 AstNode node = this.astStack[i];
6545                 if (node instanceof AbstractMethodDeclaration 
6546                                 || node instanceof TypeDeclaration) { // mark type for now: all fields will be marked when added to this type
6547                         node.bits |= AstNode.HasLocalTypeMASK;
6548                         return;
6549                 }
6550         }
6551         // default to reference context (case of parse method body)
6552         if (this.referenceContext instanceof AbstractMethodDeclaration
6553                         || this.referenceContext instanceof TypeDeclaration) {
6554                 ((AstNode)this.referenceContext).bits |= AstNode.HasLocalTypeMASK;
6555         }
6556 }
6557 protected void markFieldsWithLocalType(TypeDeclaration type) {
6558         if (type.fields == null || (type.bits & AstNode.HasLocalTypeMASK) == 0) return;
6559         for (int i = 0, length = type.fields.length; i < length; i++) {
6560                 type.fields[i].bits |= AstNode.HasLocalTypeMASK;
6561         }
6562 }
6563 /*
6564  * Move checkpoint location (current implementation is moving it by one token)
6565  *
6566  * Answers true if successfully moved checkpoint (i.e. did not attempt to move it
6567  * beyond end of file).
6568  */
6569 protected boolean moveRecoveryCheckpoint() {
6570
6571         int pos = lastCheckPoint;
6572         /* reset scanner, and move checkpoint by one token */
6573         scanner.startPosition = pos;
6574         scanner.currentPosition = pos;
6575         scanner.diet = false; // quit jumping over method bodies
6576         
6577         /* if about to restart, then no need to shift token */
6578         if (restartRecovery){
6579                 lastIgnoredToken = -1;
6580                 return true;
6581         }
6582         
6583         /* protect against shifting on an invalid token */
6584         lastIgnoredToken = nextIgnoredToken;
6585         nextIgnoredToken = -1;
6586         do {
6587                 try {
6588                         nextIgnoredToken = scanner.getNextToken();
6589                         if(scanner.currentPosition == scanner.startPosition){
6590                                 scanner.currentPosition++; // on fake completion identifier
6591                                 nextIgnoredToken = -1;
6592                         }
6593                         
6594                 } catch(InvalidInputException e){
6595                         pos = scanner.currentPosition;
6596                 }
6597         } while (nextIgnoredToken < 0);
6598         
6599         if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6600                 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6601                         return false;
6602                 }
6603         }
6604         lastCheckPoint = scanner.currentPosition;
6605         
6606         /* reset scanner again to previous checkpoint location*/
6607         scanner.startPosition = pos;
6608         scanner.currentPosition = pos;
6609         scanner.commentPtr = -1;
6610
6611         return true;
6612
6613 /*
6614         The following implementation moves the checkpoint location by one line:
6615          
6616         int pos = lastCheckPoint;
6617         // reset scanner, and move checkpoint by one token
6618         scanner.startPosition = pos;
6619         scanner.currentPosition = pos;
6620         scanner.diet = false; // quit jumping over method bodies
6621         
6622         // if about to restart, then no need to shift token
6623         if (restartRecovery){
6624                 lastIgnoredToken = -1;
6625                 return true;
6626         }
6627         
6628         // protect against shifting on an invalid token
6629         lastIgnoredToken = nextIgnoredToken;
6630         nextIgnoredToken = -1;
6631         
6632         boolean wasTokenizingWhiteSpace = scanner.tokenizeWhiteSpace;
6633         scanner.tokenizeWhiteSpace = true;
6634         checkpointMove: 
6635                 do {
6636                         try {
6637                                 nextIgnoredToken = scanner.getNextToken();
6638                                 switch(nextIgnoredToken){
6639                                         case Scanner.TokenNameWHITESPACE :
6640                                                 if(scanner.getLineNumber(scanner.startPosition)
6641                                                         == scanner.getLineNumber(scanner.currentPosition)){
6642                                                         nextIgnoredToken = -1;
6643                                                         }
6644                                                 break;
6645                                         case TokenNameSEMICOLON :
6646                                         case TokenNameLBRACE :
6647                                         case TokenNameRBRACE :
6648                                                 break;
6649                                         case TokenNameIdentifier :
6650                                                 if(scanner.currentPosition == scanner.startPosition){
6651                                                         scanner.currentPosition++; // on fake completion identifier
6652                                                 }
6653                                         default:                                                
6654                                                 nextIgnoredToken = -1;
6655                                                 break;
6656                                         case TokenNameEOF :
6657                                                 break checkpointMove;
6658                                 }
6659                         } catch(InvalidInputException e){
6660                                 pos = scanner.currentPosition;
6661                         }
6662                 } while (nextIgnoredToken < 0);
6663         scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
6664         
6665         if (nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
6666                 if (currentToken == TokenNameEOF) { // already tried one iteration on EOF
6667                         return false;
6668                 }
6669         }
6670         lastCheckPoint = scanner.currentPosition;
6671         
6672         // reset scanner again to previous checkpoint location
6673         scanner.startPosition = pos;
6674         scanner.currentPosition = pos;
6675         scanner.commentPtr = -1;
6676
6677         return true;
6678 */
6679 }
6680 protected MessageSend newMessageSend() {
6681         // '(' ArgumentListopt ')'
6682         // the arguments are on the expression stack
6683
6684         MessageSend m = new MessageSend();
6685         int length;
6686         if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
6687                 expressionPtr -= length;
6688                 System.arraycopy(
6689                         expressionStack, 
6690                         expressionPtr + 1, 
6691                         m.arguments = new Expression[length], 
6692                         0, 
6693                         length); 
6694         };
6695         return m;
6696 }
6697 protected static int ntAction(int state, int sym) {
6698         return action[state + sym];
6699 }
6700 private final void optimizedConcatNodeLists() {
6701         /*back from a recursive loop. Virtualy group the
6702         astNode into an array using astLengthStack*/
6703
6704         /*
6705          * This is a case where you have two sublists into the astStack that you want
6706          * to merge in one list. There is no action required on the astStack. The only
6707          * thing you need to do is merge the two lengths specified on the astStackLength.
6708          * The top two length are for example:
6709          * ... p   n
6710          * and you want to result in a list like:
6711          * ... n+p 
6712          * This means that the p could be equals to 0 in case there is no astNode pushed
6713          * on the astStack.
6714          * Look at the InterfaceMemberDeclarations for an example.
6715          * This case optimizes the fact that p == 1.
6716          */
6717
6718         astLengthStack[--astLengthPtr]++;
6719 }
6720 protected static int original_state(int state) {
6721         return -check(state);
6722 }
6723 /*main loop of the automat
6724 When a rule is reduced, the method consumeRule(int) is called with the number
6725 of the consumed rule. When a terminal is consumed, the method consumeToken(int) is 
6726 called in order to remember (when needed) the consumed token */
6727 // (int)asr[asi(act)]
6728 // name[symbol_index[currentKind]]
6729 protected void parse() {
6730
6731         hasReportedError = false;
6732         int act = START_STATE;
6733         stateStackTop = -1;
6734         currentToken = getFirstToken();
6735         ProcessTerminals : for (;;) {
6736                 try {
6737                         stack[++stateStackTop] = act;
6738                 } catch (IndexOutOfBoundsException e) {
6739                         int oldStackLength = stack.length;
6740                         int oldStack[] = stack;
6741                         stack = new int[oldStackLength + StackIncrement];
6742                         System.arraycopy(oldStack, 0, stack, 0, oldStackLength);
6743                         stack[stateStackTop] = act;
6744                 };
6745
6746                 act = tAction(act, currentToken);
6747
6748                 if (act == ERROR_ACTION || restartRecovery) {
6749                         int errorPos = scanner.currentPosition;
6750                         if (!hasReportedError){
6751                                 this.reportSyntaxError(ERROR_ACTION, currentToken, stateStackTop);
6752                                 hasReportedError = true;
6753                         }
6754                         if (resumeOnSyntaxError()) {
6755                                 if (act == ERROR_ACTION) lastErrorEndPosition = errorPos;
6756                                 act = START_STATE;
6757                                 stateStackTop = -1;
6758                                 currentToken = getFirstToken();
6759                                 continue ProcessTerminals;
6760                         } else {
6761                                 act = ERROR_ACTION;
6762                         }       break ProcessTerminals;
6763                 }
6764                 if (act <= NUM_RULES)
6765                         stateStackTop--;
6766                 else
6767                         if (act > ERROR_ACTION) { /* shift-reduce */
6768                                 consumeToken(currentToken);
6769                                 if (currentElement != null) this.recoveryTokenCheck();
6770                                 try{
6771                                         currentToken = scanner.getNextToken();
6772                                 } catch(InvalidInputException e){
6773                                         if (!hasReportedError){
6774                                                 this.problemReporter().scannerError(this, e.getMessage());
6775                                                 hasReportedError = true;
6776                                         }
6777                                         lastCheckPoint = scanner.currentPosition;
6778                                         restartRecovery = true;
6779                                 }                                       
6780                                 act -= ERROR_ACTION;
6781                         } else
6782                                 if (act < ACCEPT_ACTION) { /* shift */
6783                                         consumeToken(currentToken);
6784                                         if (currentElement != null) this.recoveryTokenCheck();
6785                                         try{
6786                                                 currentToken = scanner.getNextToken();
6787                                         } catch(InvalidInputException e){
6788                                                 if (!hasReportedError){
6789                                                         this.problemReporter().scannerError(this, e.getMessage());
6790                                                         hasReportedError = true;
6791                                                 }
6792                                                 lastCheckPoint = scanner.currentPosition;
6793                                                 restartRecovery = true;
6794                                         }                                       
6795                                         continue ProcessTerminals;
6796                                 } else
6797                                         break ProcessTerminals;
6798
6799                 ProcessNonTerminals : do { /* reduce */
6800                         consumeRule(act);
6801                         stateStackTop -= (rhs[act] - 1);
6802                         act = ntAction(stack[stateStackTop], lhs[act]);
6803                 } while (act <= NUM_RULES);
6804         }
6805         endParse(act);
6806 }
6807 // A P I
6808
6809 public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
6810         //only parse the method body of cd
6811         //fill out its statements
6812
6813         //convert bugs into parse error
6814
6815         initialize();
6816         goForConstructorBody();
6817         nestedMethod[nestedType]++;
6818
6819         referenceContext = cd;
6820         compilationUnit = unit;
6821
6822         scanner.resetTo(cd.sourceEnd + 1, cd.declarationSourceEnd);
6823         try {
6824                 parse();
6825         } catch (AbortCompilation ex) {
6826                 lastAct = ERROR_ACTION;
6827         } finally {
6828                 nestedMethod[nestedType]--;
6829         }
6830
6831         if (lastAct == ERROR_ACTION) {
6832                 initialize();
6833                 return;
6834         }
6835
6836         //statements
6837         cd.explicitDeclarations = realBlockStack[realBlockPtr--];
6838         int length;
6839         if ((length = astLengthStack[astLengthPtr--]) != 0) {
6840                 astPtr -= length;
6841                 if (astStack[astPtr + 1] instanceof ExplicitConstructorCall)
6842                         //avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
6843                         {
6844                         System.arraycopy(
6845                                 astStack, 
6846                                 astPtr + 2, 
6847                                 cd.statements = new Statement[length - 1], 
6848                                 0, 
6849                                 length - 1); 
6850                         cd.constructorCall = (ExplicitConstructorCall) astStack[astPtr + 1];
6851                 } else { //need to add explicitly the super();
6852                         System.arraycopy(
6853                                 astStack, 
6854                                 astPtr + 1, 
6855                                 cd.statements = new Statement[length], 
6856                                 0, 
6857                                 length); 
6858                         cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6859                 }
6860         } else {
6861                 cd.constructorCall = SuperReference.implicitSuperConstructorCall();
6862         }
6863
6864         if (cd.constructorCall.sourceEnd == 0) {
6865                 cd.constructorCall.sourceEnd = cd.sourceEnd;
6866                 cd.constructorCall.sourceStart = cd.sourceStart;
6867         }
6868 }
6869 // A P I
6870
6871 public void parse(
6872         Initializer ini, 
6873         TypeDeclaration type, 
6874         CompilationUnitDeclaration unit) {
6875         //only parse the method body of md
6876         //fill out method statements
6877
6878         //convert bugs into parse error
6879
6880         initialize();
6881         goForInitializer();
6882         nestedMethod[nestedType]++;
6883
6884         referenceContext = type;
6885         compilationUnit = unit;
6886
6887         scanner.resetTo(ini.sourceStart, ini.sourceEnd); // just on the beginning {
6888         try {
6889                 parse();
6890         } catch (AbortCompilation ex) {
6891                 lastAct = ERROR_ACTION;
6892         } finally {
6893                 nestedMethod[nestedType]--;
6894         }
6895
6896         if (lastAct == ERROR_ACTION) {
6897                 return;
6898         }
6899
6900         ini.block = ((Initializer) astStack[astPtr]).block;
6901         
6902         // mark initializer with local type if one was found during parsing
6903         if ((type.bits & AstNode.HasLocalTypeMASK) != 0) {
6904                 ini.bits |= AstNode.HasLocalTypeMASK;
6905         }       
6906 }
6907 // A P I
6908
6909 public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
6910         //only parse the method body of md
6911         //fill out method statements
6912
6913         //convert bugs into parse error
6914
6915         if (md.isAbstract())
6916                 return;
6917         if (md.isNative())
6918                 return;
6919         if ((md.modifiers & AccSemicolonBody) != 0)
6920                 return;
6921
6922         initialize();
6923         goForMethodBody();
6924         nestedMethod[nestedType]++;
6925
6926         referenceContext = md;
6927         compilationUnit = unit;
6928
6929         scanner.resetTo(md.sourceEnd + 1, md.declarationSourceEnd); 
6930         // reset the scanner to parser from { down to }
6931         try {
6932                 parse();
6933         } catch (AbortCompilation ex) {
6934                 lastAct = ERROR_ACTION;
6935         } finally {
6936                 nestedMethod[nestedType]--;             
6937         }
6938
6939         if (lastAct == ERROR_ACTION) {
6940                 return;
6941         }
6942
6943         //refill statements
6944         md.explicitDeclarations = realBlockStack[realBlockPtr--];
6945         int length;
6946         if ((length = astLengthStack[astLengthPtr--]) != 0)
6947                 System.arraycopy(
6948                         astStack, 
6949                         (astPtr -= length) + 1, 
6950                         md.statements = new Statement[length], 
6951                         0, 
6952                         length); 
6953 }
6954 // A P I
6955
6956 public CompilationUnitDeclaration parse(
6957         ICompilationUnit sourceUnit, 
6958         CompilationResult compilationResult) {
6959         // parses a compilation unit and manages error handling (even bugs....)
6960
6961         CompilationUnitDeclaration unit;
6962         try {
6963                 /* automaton initialization */
6964                 initialize();
6965                 goForCompilationUnit();
6966
6967                 /* scanner initialization */
6968                 scanner.setSource(sourceUnit.getContents());
6969
6970                 /* unit creation */
6971                 referenceContext = 
6972                         compilationUnit = 
6973                                 new CompilationUnitDeclaration(
6974                                         problemReporter, 
6975                                         compilationResult, 
6976                                         scanner.source.length);
6977                 /* run automaton */
6978                 parse();
6979         } finally {
6980                 unit = compilationUnit;
6981                 compilationUnit = null; // reset parser
6982         }
6983         return unit;
6984 }
6985 // A P I
6986
6987 public CompilationUnitDeclaration parse(
6988         ICompilationUnit sourceUnit, 
6989         CompilationResult compilationResult,
6990         int start,
6991         int end) {
6992         // parses a compilation unit and manages error handling (even bugs....)
6993
6994         CompilationUnitDeclaration unit;
6995         try {
6996                 /* automaton initialization */
6997                 initialize();
6998                 goForCompilationUnit();
6999
7000                 /* scanner initialization */
7001                 scanner.setSource(sourceUnit.getContents());
7002                 scanner.resetTo(start, end);
7003                 /* unit creation */
7004                 referenceContext = 
7005                         compilationUnit = 
7006                                 new CompilationUnitDeclaration(
7007                                         problemReporter, 
7008                                         compilationResult, 
7009                                         scanner.source.length);
7010                 /* run automaton */
7011                 parse();
7012         } finally {
7013                 unit = compilationUnit;
7014                 compilationUnit = null; // reset parser
7015         }
7016         return unit;
7017 }
7018 /**
7019  * Returns this parser's problem reporter initialized with its reference context.
7020  * Also it is assumed that a problem is going to be reported, so initializes
7021  * the compilation result's line positions.
7022  */
7023 public ProblemReporter problemReporter(){
7024         if (scanner.recordLineSeparator) {
7025                 compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
7026         }
7027         problemReporter.referenceContext = referenceContext;
7028         return problemReporter;
7029 }
7030 protected void pushIdentifier() {
7031         /*push the consumeToken on the identifier stack.
7032         Increase the total number of identifier in the stack.
7033         identifierPtr points on the next top */
7034
7035         try {
7036                 identifierStack[++identifierPtr] = scanner.getCurrentIdentifierSource();
7037                 identifierPositionStack[identifierPtr] = 
7038                         (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1); 
7039         } catch (IndexOutOfBoundsException e) {
7040                 /*---stack reallaocation (identifierPtr is correct)---*/
7041                 int oldStackLength = identifierStack.length;
7042                 char[][] oldStack = identifierStack;
7043                 identifierStack = new char[oldStackLength + 20][];
7044                 System.arraycopy(oldStack, 0, identifierStack, 0, oldStackLength);
7045                 identifierStack[identifierPtr] = scanner.getCurrentTokenSource();
7046                 /*identifier position stack*/
7047                 long[] oldPos = identifierPositionStack;
7048                 identifierPositionStack = new long[oldStackLength + 20];
7049                 System.arraycopy(oldPos, 0, identifierPositionStack, 0, oldStackLength);
7050                 identifierPositionStack[identifierPtr] = 
7051                         (((long) scanner.startPosition) << 32) + (scanner.currentPosition - 1); 
7052         };
7053
7054         try {
7055                 identifierLengthStack[++identifierLengthPtr] = 1;
7056         } catch (IndexOutOfBoundsException e) {
7057                 /*---stack reallocation (identifierLengthPtr is correct)---*/
7058                 int oldStackLength = identifierLengthStack.length;
7059                 int oldStack[] = identifierLengthStack;
7060                 identifierLengthStack = new int[oldStackLength + 10];
7061                 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7062                 identifierLengthStack[identifierLengthPtr] = 1;
7063         };
7064
7065 }
7066 protected void pushIdentifier(int flag) {
7067         /*push a special flag on the stack :
7068         -zero stands for optional Name
7069         -negative number for direct ref to base types.
7070         identifierLengthPtr points on the top */
7071
7072         try {
7073                 identifierLengthStack[++identifierLengthPtr] = flag;
7074         } catch (IndexOutOfBoundsException e) {
7075                 /*---stack reallaocation (identifierLengthPtr is correct)---*/
7076                 int oldStackLength = identifierLengthStack.length;
7077                 int oldStack[] = identifierLengthStack;
7078                 identifierLengthStack = new int[oldStackLength + 10];
7079                 System.arraycopy(oldStack, 0, identifierLengthStack, 0, oldStackLength);
7080                 identifierLengthStack[identifierLengthPtr] = flag;
7081         };
7082
7083 }
7084 protected void pushOnAstLengthStack(int pos) {
7085         try {
7086                 astLengthStack[++astLengthPtr] = pos;
7087         } catch (IndexOutOfBoundsException e) {
7088                 int oldStackLength = astLengthStack.length;
7089                 int[] oldPos = astLengthStack;
7090                 astLengthStack = new int[oldStackLength + StackIncrement];
7091                 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7092                 astLengthStack[astLengthPtr] = pos;
7093         }
7094 }
7095 protected void pushOnAstStack(AstNode node) {
7096         /*add a new obj on top of the ast stack
7097         astPtr points on the top*/
7098
7099         try {
7100                 astStack[++astPtr] = node;
7101         } catch (IndexOutOfBoundsException e) {
7102                 int oldStackLength = astStack.length;
7103                 AstNode[] oldStack = astStack;
7104                 astStack = new AstNode[oldStackLength + AstStackIncrement];
7105                 System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
7106                 astPtr = oldStackLength;
7107                 astStack[astPtr] = node;
7108         }
7109
7110         try {
7111                 astLengthStack[++astLengthPtr] = 1;
7112         } catch (IndexOutOfBoundsException e) {
7113                 int oldStackLength = astLengthStack.length;
7114                 int[] oldPos = astLengthStack;
7115                 astLengthStack = new int[oldStackLength + AstStackIncrement];
7116                 System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
7117                 astLengthStack[astLengthPtr] = 1;
7118         }
7119 }
7120 protected void pushOnExpressionStack(Expression expr) {
7121
7122         try {
7123                 expressionStack[++expressionPtr] = expr;
7124         } catch (IndexOutOfBoundsException e) {
7125                 //expressionPtr is correct 
7126                 int oldStackLength = expressionStack.length;
7127                 Expression[] oldStack = expressionStack;
7128                 expressionStack = new Expression[oldStackLength + ExpressionStackIncrement];
7129                 System.arraycopy(oldStack, 0, expressionStack, 0, oldStackLength);
7130                 expressionStack[expressionPtr] = expr;
7131         }
7132
7133         try {
7134                 expressionLengthStack[++expressionLengthPtr] = 1;
7135         } catch (IndexOutOfBoundsException e) {
7136                 int oldStackLength = expressionLengthStack.length;
7137                 int[] oldPos = expressionLengthStack;
7138                 expressionLengthStack = new int[oldStackLength + ExpressionStackIncrement];
7139                 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7140                 expressionLengthStack[expressionLengthPtr] = 1;
7141         }
7142 }
7143 protected void pushOnExpressionStackLengthStack(int pos) {
7144         try {
7145                 expressionLengthStack[++expressionLengthPtr] = pos;
7146         } catch (IndexOutOfBoundsException e) {
7147                 int oldStackLength = expressionLengthStack.length;
7148                 int[] oldPos = expressionLengthStack;
7149                 expressionLengthStack = new int[oldStackLength + StackIncrement];
7150                 System.arraycopy(oldPos, 0, expressionLengthStack, 0, oldStackLength);
7151                 expressionLengthStack[expressionLengthPtr] = pos;
7152         }
7153 }
7154 protected void pushOnIntStack(int pos) {
7155
7156         try {
7157                 intStack[++intPtr] = pos;
7158         } catch (IndexOutOfBoundsException e) {
7159                 //intPtr is correct 
7160                 int oldStackLength = intStack.length;
7161                 int oldStack[] = intStack;
7162                 intStack = new int[oldStackLength + StackIncrement];
7163                 System.arraycopy(oldStack, 0, intStack, 0, oldStackLength);
7164                 intStack[intPtr] = pos;
7165         }
7166 }
7167 protected static char[] readTable(String filename) throws java.io.IOException {
7168
7169         //files are located at Parser.class directory
7170
7171         InputStream stream = new BufferedInputStream(Parser.class.getResourceAsStream(filename));
7172         if (stream == null) {
7173                 throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
7174         }
7175         byte[] bytes = null;
7176         try {
7177                 bytes = Util.getInputStreamAsByteArray(stream, -1);
7178         } finally {
7179                 try {
7180                         stream.close();
7181                 } catch (IOException e) {
7182                 }
7183         }
7184
7185         //minimal integrity check (even size expected)
7186         int length = bytes.length;
7187         if (length % 2 != 0)
7188                 throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
7189
7190         // convert bytes into chars
7191         char[] chars = new char[length / 2];
7192         int i = 0;
7193         int charIndex = 0;
7194
7195         while (true) {
7196                 chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
7197                 if (i == length)
7198                         break;
7199         }
7200         return chars;
7201 }
7202 /* Token check performed on every token shift once having entered
7203  * recovery mode.
7204  */
7205 public void recoveryTokenCheck() {
7206         switch (currentToken) {
7207                 case TokenNameLBRACE : {
7208                         RecoveredElement newElement = 
7209                                 currentElement.updateOnOpeningBrace(scanner.currentPosition - 1);
7210                         lastCheckPoint = scanner.currentPosition;                               
7211                         if (newElement != null){ // null means nothing happened
7212                                 restartRecovery = true; // opening brace detected
7213                                 currentElement = newElement;
7214                         }
7215                         break;
7216                 }
7217                 case TokenNameRBRACE : {
7218                         endPosition = this.flushAnnotationsDefinedPriorTo(scanner.currentPosition - 1);
7219                         RecoveredElement newElement =
7220                                 currentElement.updateOnClosingBrace(scanner.startPosition, scanner.currentPosition -1);
7221                                 lastCheckPoint = scanner.currentPosition;
7222                                 if (newElement != currentElement){
7223                                 currentElement = newElement;
7224                         }
7225                 }
7226         }
7227 }
7228 protected void reportSyntaxError(int act, int currentKind, int stateStackTop) {
7229
7230         /* remember current scanner position */
7231         int startPos = scanner.startPosition;
7232         int currentPos = scanner.currentPosition;
7233         
7234         String[] expectings;
7235         String tokenName = name[symbol_index[currentKind]];
7236
7237         //fetch all "accurate" possible terminals that could recover the error
7238         int start, end = start = asi(stack[stateStackTop]);
7239         while (asr[end] != 0)
7240                 end++;
7241         int length = end - start;
7242         expectings = new String[length];
7243         if (length != 0) {
7244                 char[] indexes = new char[length];
7245                 System.arraycopy(asr, start, indexes, 0, length);
7246                 for (int i = 0; i < length; i++) {
7247                         expectings[i] = name[symbol_index[indexes[i]]];
7248                 }
7249         }
7250
7251         //if the pb is an EOF, try to tell the user that they are some 
7252         if (tokenName.equals(UNEXPECTED_EOF)) {
7253                 if (!this.checkAndReportBracketAnomalies(problemReporter())) {
7254                         char[] tokenSource;
7255                         try {
7256                                 tokenSource = this.scanner.getCurrentTokenSource();
7257                         } catch (Exception e) {
7258                                 tokenSource = new char[] {};
7259                         }
7260                         problemReporter().parseError(
7261                                 this.scanner.startPosition, 
7262                                 this.scanner.currentPosition - 1, 
7263                                 tokenSource, 
7264                                 tokenName, 
7265                                 expectings); 
7266                 }
7267         } else { //the next test is HEAVILY grammar DEPENDENT.
7268                 if ((length == 2)
7269                         && (tokenName.equals(";")) //$NON-NLS-1$
7270                         && (expectings[0] == "++") //$NON-NLS-1$
7271                         && (expectings[1] == "--") //$NON-NLS-1$
7272                         && (expressionPtr > -1)) {
7273                         // the ; is not the expected token ==> it ends a statement when an expression is not ended
7274                         problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
7275                 } else {
7276                         char[] tokenSource;
7277                         try {
7278                                 tokenSource = this.scanner.getCurrentTokenSource();
7279                         } catch (Exception e) {
7280                                 tokenSource = new char[] {};
7281                         }
7282                         problemReporter().parseError(
7283                                 this.scanner.startPosition, 
7284                                 this.scanner.currentPosition - 1, 
7285                                 tokenSource, 
7286                                 tokenName, 
7287                                 expectings); 
7288                         this.checkAndReportBracketAnomalies(problemReporter());
7289                 }
7290         }
7291         /* reset scanner where it was */
7292         scanner.startPosition = startPos;
7293         scanner.currentPosition = currentPos;
7294 }
7295 protected void resetModifiers() {
7296         modifiers = AccDefault;
7297         modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
7298         scanner.commentPtr = -1;
7299 }
7300 /*
7301  * Reset context so as to resume to regular parse loop
7302  */
7303 protected void resetStacks() {
7304
7305         astPtr = -1;
7306         astLengthPtr = -1;
7307         expressionPtr = -1;
7308         expressionLengthPtr = -1;
7309         identifierPtr = -1;     
7310         identifierLengthPtr     = -1;
7311         intPtr = -1;
7312         nestedMethod[nestedType = 0] = 0; // need to reset for further reuse
7313         variablesCounter[nestedType] = 0;
7314         dimensions = 0 ;
7315         realBlockStack[realBlockPtr = 0] = 0;
7316         recoveredStaticInitializerStart = 0;
7317         listLength = 0;
7318 }
7319 /*
7320  * Reset context so as to resume to regular parse loop
7321  * If unable to reset for resuming, answers false.
7322  *
7323  * Move checkpoint location, reset internal stacks and
7324  * decide which grammar goal is activated.
7325  */
7326 protected boolean resumeAfterRecovery() {
7327
7328         // reset internal stacks 
7329         this.resetStacks();
7330         
7331         /* attempt to move checkpoint location */
7332         if (!this.moveRecoveryCheckpoint()) return false;
7333
7334         // only look for headers
7335         if (referenceContext instanceof CompilationUnitDeclaration){
7336                 goForHeaders();
7337                 diet = true; // passed this point, will not consider method bodies
7338                 return true;
7339         }
7340         // does not know how to restart
7341         return false;
7342 }
7343 /*
7344  * Syntax error was detected. Will attempt to perform some recovery action in order
7345  * to resume to the regular parse loop.
7346  */
7347 protected boolean resumeOnSyntaxError() {
7348
7349         /* request recovery initialization */
7350         if (currentElement == null){
7351                 currentElement = 
7352                         this.buildInitialRecoveryState(); // build some recovered elements
7353         }
7354         /* do not investigate deeper in recovery when no recovered element */
7355         if (currentElement == null) return false;
7356         
7357         /* manual forced recovery restart - after headers */
7358         if (restartRecovery){
7359                 restartRecovery = false;
7360         }
7361         /* update recovery state with current error state of the parser */
7362         this.updateRecoveryState();
7363         
7364         /* attempt to reset state in order to resume to parse loop */
7365         return this.resumeAfterRecovery();
7366 }
7367 protected static int tAction(int state, int sym) {
7368         return action[check(state + sym) == sym ? state + sym : state];
7369 }
7370 public String toString() {
7371
7372         String s = "identifierStack : char[][] = {"; //$NON-NLS-1$
7373         for (int i = 0; i <= identifierPtr; i++) {
7374                 s = s + "\"" + String.valueOf(identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
7375         };
7376         s = s + "}\n"; //$NON-NLS-1$
7377
7378         s = s + "identierLengthStack : int[] = {"; //$NON-NLS-1$
7379         for (int i = 0; i <= identifierLengthPtr; i++) {
7380                 s = s + identifierLengthStack[i] + ","; //$NON-NLS-1$
7381         };
7382         s = s + "}\n"; //$NON-NLS-1$
7383
7384         s = s + "astLengthStack : int[] = {"; //$NON-NLS-1$
7385         for (int i = 0; i <= astLengthPtr; i++) {
7386                 s = s + astLengthStack[i] + ","; //$NON-NLS-1$
7387         };
7388         s = s + "}\n"; //$NON-NLS-1$
7389         s = s + "astPtr : int = " + String.valueOf(astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7390
7391         s = s + "intStack : int[] = {"; //$NON-NLS-1$
7392         for (int i = 0; i <= intPtr; i++) {
7393                 s = s + intStack[i] + ","; //$NON-NLS-1$
7394         };
7395         s = s + "}\n"; //$NON-NLS-1$
7396
7397         s = s + "expressionLengthStack : int[] = {"; //$NON-NLS-1$
7398         for (int i = 0; i <= expressionLengthPtr; i++) {
7399                 s = s + expressionLengthStack[i] + ","; //$NON-NLS-1$
7400         };
7401         s = s + "}\n"; //$NON-NLS-1$
7402
7403         s = s + "expressionPtr : int = " + String.valueOf(expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
7404
7405         s = s + "\n\n\n----------------Scanner--------------\n" + scanner.toString(); //$NON-NLS-1$
7406         return s;
7407
7408 }
7409 /*
7410  * Update recovery state based on current parser/scanner state
7411  */
7412 protected void updateRecoveryState() {
7413
7414         /* expose parser state to recovery state */
7415         currentElement.updateFromParserState();
7416
7417         /* check and update recovered state based on current token,
7418                 this action is also performed when shifting token after recovery
7419                 got activated once. 
7420         */
7421         this.recoveryTokenCheck();
7422 }
7423 protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
7424         //fields is a definition of fields that are grouped together like in
7425         //public int[] a, b[], c
7426         //which results into 3 fields.
7427
7428         FieldDeclaration field;
7429         int endTypeDeclarationPosition = 
7430                 -1 + astStack[astPtr - variableDeclaratorsCounter + 1].sourceStart; 
7431         for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
7432                 //last one is special(see below)
7433                 field = (FieldDeclaration) astStack[astPtr - i - 1];
7434                 field.endPart1Position = endTypeDeclarationPosition;
7435                 field.endPart2Position = -1 + astStack[astPtr - i].sourceStart;
7436         }
7437         //last one
7438         (field = (FieldDeclaration) astStack[astPtr]).endPart1Position = 
7439                 endTypeDeclarationPosition; 
7440         field.endPart2Position = field.declarationSourceEnd;
7441
7442 }
7443 protected void updateSourcePosition(Expression exp) {
7444         //update the source Position of the expression
7445
7446         //intStack : int int
7447         //-->
7448         //intStack : 
7449
7450         exp.sourceEnd = intStack[intPtr--];
7451         exp.sourceStart = intStack[intPtr--];
7452 }
7453 }