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