1	package antlr;
2	
3	/**
4	 * <b>SOFTWARE RIGHTS</b>
5	 * <p>
6	 * ANTLR 2.3.0 MageLang Institute, 1998
7	 * <p>
8	 * We reserve no legal rights to the ANTLR--it is fully in the
9	 * public domain. An individual or company may do whatever
10	 * they wish with source code distributed with ANTLR or the
11	 * code generated by ANTLR, including the incorporation of
12	 * ANTLR, or its output, into commerical software.
13	 * <p>
14	 * We encourage users to develop software with ANTLR. However,
15	 * we do ask that credit is given to us for developing
16	 * ANTLR. By "credit", we mean that if you use ANTLR or
17	 * incorporate any source code into one of your programs
18	 * (commercial product, research project, or otherwise) that
19	 * you acknowledge this fact somewhere in the documentation,
20	 * research report, etc... If you like ANTLR and have
21	 * developed a nice tool with the output, please mention that
22	 * you developed it using ANTLR. In addition, we ask that the
23	 * headers remain intact in our source code. As long as these
24	 * guidelines are kept, we expect to continue enhancing this
25	 * system and expect to make other tools available as they are
26	 * completed.
27	 * <p>
28	 * The ANTLR gang:
29	 * @version ANTLR 2.3.0 MageLang Institute, 1998
30	 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
31	 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
32	 * @author <br><a href="mailto:pete@yamuna.demon.co.uk">Pete Wells</a>
33	 */
34	import java.util.Enumeration;
35	import java.util.Hashtable;
36	import antlr.collections.impl.BitSet;
37	import antlr.collections.impl.Vector;
38	import java.io.PrintWriter; //SAS: changed for proper text file io
39	import java.io.IOException;
40	import java.io.FileWriter;
41	
42	/**Generate MyParser.cpp, MyParser.hpp, MyLexer.cpp, MyLexer.hpp and MyParserTokenTypes.hpp */
43	public class CppCodeGenerator extends CodeGenerator {
44		// non-zero if inside syntactic predicate generation
45		protected int syntacticPredLevel = 0;
46	
47		// Are we generating ASTs (for parsers and tree parsers) right now?
48		protected boolean genAST = false;
49	
50		// Are we saving the text consumed (for lexers) right now?
51		protected boolean saveText = false;
52	
53		// Grammar parameters set up to handle different grammar classes.
54		// These are used to get instanceof tests out of code generation
55		String labeledElementType;
56		String labeledElementASTType;
57		String labeledElementInit;
58		String commonExtraArgs;
59		String commonExtraParams;
60		String commonLocalVars;
61		String lt1Value;
62		String exceptionThrown;
63		String throwNoViable;
64	
65		// Tracks the rule being generated.  Used for mapTreeId
66		RuleBlock currentRule;
67		// Tracks the rule or labeled subrule being generated.  Used for AST generation.
68		String currentASTResult;
69		// Mapping between the ids used in the current alt, and the
70		// names of variables used to represent their AST values.
71		Hashtable treeVariableMap = new Hashtable();
72		// Count of unnamed generated variables
73		int astVarNumber = 1;
74		// Special value used to mark duplicate in treeVariableMap
75		protected static final String NONUNIQUE = new String();
76	
77	
78		/** Create a C++ code-generator using the given Grammar.
79		 * The caller must still call setTool, setBehavior, and setAnalyzer
80		 * before generating code.
81		 */
82		public CppCodeGenerator() {
83			super();
84			charFormatter = new CppCharFormatter();
85		}
86		public void exitIfError() {
87			if (tool.hasError) {
88				System.out.println("Exiting due to errors.");
89				System.exit(1);
90			}
91		}
92		/**Generate the parser, lexer, treeparser, and token types in C++ */
93		public void gen() {
94			// Do the code generation
95			try {
96				// Loop over all grammars
97				Enumeration grammarIter = behavior.grammars.elements();
98				while (grammarIter.hasMoreElements()) {
99					Grammar g = (Grammar)grammarIter.nextElement();
100					// Connect all the components to each other
101					g.setGrammarAnalyzer(analyzer);
102					g.setCodeGenerator(this);
103					analyzer.setGrammar(g);
104					// To get right overloading behavior across hetrogeneous grammars
105					setupGrammarParameters(g);
106					g.generate();
107					exitIfError();
108				}
109	
110				// Loop over all token managers (some of which are lexers)
111				Enumeration tmIter = behavior.tokenManagers.elements();
112				while (tmIter.hasMoreElements()) {
113					TokenManager tm = (TokenManager)tmIter.nextElement();
114					if (!tm.isReadOnly()) {
115						// Write the token manager tokens as C++
116						// this must appear before genTokenInterchange so that
117						// labels are set on string literals
118						genTokenTypes(tm);
119						// Write the token manager tokens as plain text
120						genTokenInterchange(tm);
121					}
122					exitIfError();
123				}
124			}
125			catch (IOException e) {
126				System.out.println(e.getMessage());
127			}
128		}
129		/** Generate code for the given grammar element.
130		 * @param blk The {...} action to generate
131		 */
132		public void gen(ActionElement action) {
133			if ( DEBUG_CODE_GENERATOR ) System.out.println("genAction("+action+")");
134			if ( action.isSemPred ) {
135				genSemPred(action.actionText);
136			}
137			else {
138				if ( grammar.hasSyntacticPredicate ) {
139					println("if ( guessing==0 ) {");
140					tabs++;
141				}
142	
143				ActionTransInfo tInfo = new ActionTransInfo();
144				String actionStr = processActionForTreeSpecifiers(action.actionText, action.getLine(), currentRule, tInfo);
145	
146				if ( tInfo.refRuleRoot!=null ) {
147					// Somebody referenced "#rule", make sure translated var is valid
148					// assignment to #rule is left as a ref also, meaning that assignments
149					// with no other refs like "#rule = foo();" still forces this code to be
150					// generated (unnecessarily).
151					println(tInfo.refRuleRoot + " = currentAST.root;");
152				}
153	
154				// dump the translated action
155				printAction(actionStr);
156	
157				if ( tInfo.assignToRoot ) {
158					// Somebody did a "#rule=", reset internal currentAST.root
159					println("currentAST.root = "+tInfo.refRuleRoot+";");
160					// reset the child pointer too to be last sibling in sibling list
161					println("currentAST.child = "+tInfo.refRuleRoot+"!=nullAST &&"+tInfo.refRuleRoot+"->getFirstChild()!=0 ?");
162					tabs++;
163					println(tInfo.refRuleRoot+"->getFirstChild() : "+tInfo.refRuleRoot+";");
164					tabs--;
165					println("currentAST.advanceChildToEnd();");
166				}
167	
168				if ( grammar.hasSyntacticPredicate ) {
169					tabs--;
170					println("}");
171				}
172			}
173		}
174		/** Generate code for the given grammar element.
175		 * @param blk The "x|y|z|..." block to generate
176		 */
177		public void gen(AlternativeBlock blk) {
178			if ( DEBUG_CODE_GENERATOR ) System.out.println("gen("+blk+")");
179			println("{");
180			genBlockPreamble(blk);
181	
182			// Tell AST generation to build subrule result
183			String saveCurrentASTResult = currentASTResult;
184			if (blk.getLabel() != null) {
185				currentASTResult = blk.getLabel();
186			}
187	
188			boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
189			
190			CppBlockFinishingInfo howToFinish = genCommonBlock(blk, true);
191			genBlockFinish(howToFinish, throwNoViable);
192	
193			println("}");
194	
195			// Restore previous AST generation
196			currentASTResult = saveCurrentASTResult;
197		}
198		/** Generate code for the given grammar element.
199		 * @param blk The block-end element to generate.  Block-end
200		 * elements are synthesized by the grammar parser to represent
201		 * the end of a block.
202		 */
203		public void gen(BlockEndElement end) {
204			if ( DEBUG_CODE_GENERATOR ) System.out.println("genRuleEnd("+end+")");
205		}
206		/** Generate code for the given grammar element.
207		 * @param blk The character literal reference to generate
208		 */
209		public void gen(CharLiteralElement atom) {
210			if ( DEBUG_CODE_GENERATOR ) System.out.println("genChar("+atom+")");
211	
212			if ( atom.getLabel()!=null ) {
213				println(atom.getLabel() + " = " + lt1Value + ";");
214			}
215	
216			boolean oldsaveText = saveText;
217			saveText = saveText && atom.getAutoGenType()==GrammarElement.AUTO_GEN_NONE;
218			genMatch(atom);
219			saveText = oldsaveText;
220		}
221		/** Generate code for the given grammar element.
222		 * @param blk The character-range reference to generate
223		 */
224		public void gen(CharRangeElement r) {
225			if ( r.getLabel()!=null  && syntacticPredLevel == 0) {
226				println(r.getLabel() + " = " + lt1Value + ";");
227			}
228			println("matchRange("+r.beginText+","+r.endText+");");
229		}
230		/** Generate the lexer C++ files */
231		public  void gen(LexerGrammar g) throws IOException {
232			setGrammar(g);
233			if (!(grammar instanceof LexerGrammar)) {
234				tool.panic("Internal error generating lexer");
235			}
236	
237			genBody(g);
238			genInclude(g);
239		}
240		/** Generate code for the given grammar element.
241		 * @param blk The (...)+ block to generate
242		 */
243		public void gen(OneOrMoreBlock blk) {
244			if ( DEBUG_CODE_GENERATOR ) System.out.println("gen+("+blk+")");
245			String label;
246			String cnt;
247			println("{");
248			genBlockPreamble(blk);
249			if ( blk.getLabel() != null ) {
250				cnt = "_cnt_"+blk.getLabel();
251			}
252			else {
253				cnt = "_cnt" + blk.ID;
254			}
255			println("int "+cnt+"=0;");
256			if ( blk.getLabel() != null ) {
257				label = blk.getLabel();
258			}
259			else {
260				label = "_loop" + blk.ID;
261			}
262	
263			println("do {");
264			tabs++;
265			
266			// Tell AST generation to build subrule result
267			String saveCurrentASTResult = currentASTResult;
268			if (blk.getLabel() != null) {
269				currentASTResult = blk.getLabel();
270			}
271	
272			boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
273			CppBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
274			genBlockFinish(
275				howToFinish, 
276				"if ( "+cnt+">=1 ) { goto "+label+"; } else {" + throwNoViable + "}"
277			);
278	
279			println(cnt+"++;");
280			tabs--;
281			println("} while (true);");
282			println(label+":;");
283			println("}");
284	
285			// Restore previous AST generation
286			currentASTResult = saveCurrentASTResult;
287		}
288		/** Generate the parser C++ file */
289		public void gen(ParserGrammar g) throws IOException {
290			setGrammar(g);
291			if (!(grammar instanceof ParserGrammar)) {
292				tool.panic("Internal error generating parser");
293			}
294	
295			genBody(g);
296			genInclude(g);
297		}
298		/** Generate code for the given grammar element.
299		 * @param blk The rule-reference to generate
300		 */
301		public void gen(RuleRefElement rr) {
302			if ( DEBUG_CODE_GENERATOR ) System.out.println("genRR("+rr+")");
303			RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
304			if (rs == null || !rs.isDefined())
305			{
306				// Is this redundant???
307				tool.error("Rule '" + rr.targetRule + "' is not defined", rr.getLine());
308				return;
309			}
310			if (!(rs instanceof RuleSymbol))
311			{
312				// Is this redundant???
313				tool.error("'" + rr.targetRule + "' does not name a grammar rule", rr.getLine());
314				return;
315			}
316	
317			genErrorTryForElement(rr);
318	
319			// AST value for labeled rule refs in tree walker.
320			// This is not AST construction;  it is just the input tree node value.
321			if ( grammar instanceof TreeWalkerGrammar && 
322				rr.getLabel() != null && 
323				syntacticPredLevel == 0 )
324			{
325				println(rr.getLabel() + " = _t==ASTNULL ? nullAST : "+lt1Value+";");
326			}
327	
328			// if in lexer and ! on rule ref or alt or rule, save buffer index to kill later
329			if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
330				println("_saveIndex=text.length();");
331			}
332	
333			// Process return value assignment if any
334			printTabs();
335			if (rr.idAssign != null)
336			{
337				// Warn if the rule has no return type
338				if (rs.block.returnAction == null)
339				{
340					tool.warning("Rule '" + rr.targetRule + "' has no return type", rr.getLine());
341				}
342				_print(rr.idAssign + "=");
343			} else {
344				// Warn about return value if any, but not inside syntactic predicate
345				if ( !(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null)
346				{
347					tool.warning("Rule '" + rr.targetRule + "' returns a value", rr.getLine());
348				}
349			}
350	
351			// Call the rule
352			GenRuleInvocation(rr);
353	
354			// if in lexer and ! on element or alt or rule, save buffer index to kill later
355			if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
356				println("text.erase(_saveIndex);");
357			}
358	
359			// if not in a syntactic predicate
360			if (syntacticPredLevel == 0) {
361				boolean doNoGuessTest = (
362					grammar.hasSyntacticPredicate &&
363					(
364						grammar.buildAST && rr.getLabel() != null || 
365						(genAST && rr.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)
366					)
367				);
368				if (doNoGuessTest) {
369					println("if (guessing==0) {"); 
370					tabs++;
371				}
372	
373				if (grammar.buildAST && rr.getLabel() != null) {
374					// always gen variable for rule return on labeled rules
375					println(rr.getLabel() + "_AST = returnAST;");
376				}
377				if (genAST) {
378					switch (rr.getAutoGenType()) {
379					case GrammarElement.AUTO_GEN_NONE:
380						// println("theASTFactory.addASTChild(currentAST, returnAST);");
381						println("astFactory.addASTChild(currentAST, returnAST);");
382						break;
383					case GrammarElement.AUTO_GEN_CARET:
384						tool.error("Internal: encountered ^ after rule reference");
385						break;
386					default:
387						break;
388					}
389				}
390	
391				// if a lexer and labeled, Token label defined at rule level, just set it here
392				if ( grammar instanceof LexerGrammar && rr.getLabel() != null ) {
393					println(rr.getLabel()+"=_returnToken;");
394				}
395	
396				if (doNoGuessTest) {
397					tabs--;
398					println("}"); 
399				}
400			}
401			genErrorCatchForElement(rr);
402		}
403		/** Generate code for the given grammar element.
404		 * @param blk The string-literal reference to generate
405		 */
406		public void gen(StringLiteralElement atom) {
407			if ( DEBUG_CODE_GENERATOR ) System.out.println("genString("+atom+")");
408	
409			// Variable declarations for labeled elements
410			if (atom.getLabel()!=null && syntacticPredLevel == 0) {
411				println(atom.getLabel() + " = " + lt1Value + ";");
412			}
413	
414			// AST
415			genElementAST(atom);
416	
417			// is there a bang on the literal?
418			boolean oldsaveText = saveText;
419			saveText = saveText && atom.getAutoGenType()==GrammarElement.AUTO_GEN_NONE;
420	
421			// matching
422			genMatch(atom);
423	
424			saveText = oldsaveText;
425			
426			// tack on tree cursor motion if doing a tree walker
427			if (grammar instanceof TreeWalkerGrammar) {
428				println("_t = _t->getNextSibling();");
429			}
430		}
431		/** Generate code for the given grammar element.
432		 * @param blk The token-range reference to generate
433		 */
434		public void gen(TokenRangeElement r) {
435			genErrorTryForElement(r);
436			if ( r.getLabel()!=null  && syntacticPredLevel == 0) {
437				println(r.getLabel() + " = " + lt1Value + ";");
438			}
439	
440			// AST
441			genElementAST(r);
442	
443			// match
444			println("matchRange("+r.beginText+","+r.endText+");");
445			genErrorCatchForElement(r);
446		}
447		/** Generate code for the given grammar element.
448		 * @param blk The token-reference to generate
449		 */
450		public void gen(TokenRefElement atom) {
451			if ( DEBUG_CODE_GENERATOR ) System.out.println("genTokenRef("+atom+")");
452			if ( grammar instanceof LexerGrammar ) {
453				tool.panic("Token reference found in lexer");
454			}
455			genErrorTryForElement(atom);
456			// Assign Token value to token label variable
457			if ( atom.getLabel()!=null && syntacticPredLevel == 0) {
458				println(atom.getLabel() + " = " + lt1Value + ";");
459			}
460	
461			// AST
462			genElementAST(atom);
463			// matching
464			genMatch(atom);
465			genErrorCatchForElement(atom);
466			
467			// tack on tree cursor motion if doing a tree walker
468			if (grammar instanceof TreeWalkerGrammar) {
469				println("_t = _t->getNextSibling();");
470			}
471		}
472		public void gen(TreeElement t) {
473			// save AST cursor
474			println("RefAST __t" + t.ID + " = _t;");
475	
476			// If there is a label on the root, then assign that to the variable
477			if (t.root.getLabel() != null) {
478				println(t.root.getLabel() + " = _t==ASTNULL ? nullAST :_t;");
479			}
480	
481			// Generate AST variables
482			genElementAST(t.root);
483			if (grammar.buildAST) {
484				// Save the AST construction state
485				println("ASTPair __currentAST" + t.ID + " = currentAST;");
486				// Make the next item added a child of the TreeElement root
487				println("currentAST.root = currentAST.child;");
488				println("currentAST.child = nullAST;");
489			}
490	
491			// match root
492			genMatch(t.root);
493			// move to list of children
494			println("_t = _t->getFirstChild();"); 
495			
496			// walk list of children, generating code for each
497			for (int i=0; i<t.getAlternatives().size(); i++) {
498				Alternative a = t.getAlternativeAt(i);
499				AlternativeElement e = a.head;
500				while ( e != null ) {
501					e.generate();
502					e = e.next;
503				}
504			}
505	
506			if (grammar.buildAST) {
507				// restore the AST construction state to that just after the
508				// tree root was added
509				println("currentAST = __currentAST" + t.ID + ";");
510			}
511			// restore AST cursor
512			println("_t = __t" + t.ID + ";");
513			// move cursor to sibling of tree just parsed
514			println("_t = _t->getNextSibling();");
515		}
516		/** Generate the tree-parser C++ files */
517		public void gen(TreeWalkerGrammar g) throws IOException {
518			setGrammar(g);
519			if (!(grammar instanceof TreeWalkerGrammar)) {
520				tool.panic("Internal error generating tree-walker");
521			}
522	
523			genBody(g);
524			genInclude(g);
525		}
526		/** Generate code for the given grammar element.
527		 * @param wc The wildcard element to generate
528		 */
529		public void gen(WildcardElement wc) {
530			// Variable assignment for labeled elements
531			if (wc.getLabel()!=null && syntacticPredLevel == 0) {
532				println(wc.getLabel() + " = " + lt1Value + ";");
533			}
534	
535			// AST
536			genElementAST(wc);
537			// Match anything but EOF
538			if (grammar instanceof TreeWalkerGrammar) {
539				println("if ( _t==nullAST ) throw MismatchedTokenException();");
540			}
541			else if (grammar instanceof LexerGrammar) {
542				println("matchNot(EOF);");
543			}
544			else {
545				println("matchNot(" + getValueString(Token.EOF_TYPE) + ");");
546			}
547			
548			// tack on tree cursor motion if doing a tree walker
549			if (grammar instanceof TreeWalkerGrammar) {
550				println("_t = _t->getNextSibling();");
551			}
552		}
553		/** Generate code for the given grammar element.
554		 * @param blk The (...)* block to generate
555		 */
556		public void gen(ZeroOrMoreBlock blk) {
557			if ( DEBUG_CODE_GENERATOR ) System.out.println("gen*("+blk+")");
558			println("{");
559			genBlockPreamble(blk);
560			String label;
561			if ( blk.getLabel() != null ) {
562				label = blk.getLabel();
563			}
564			else {
565				label = "_loop" + blk.ID;
566			}
567			println("do {");
568			tabs++;
569		
570			// Tell AST generation to build subrule result
571			String saveCurrentASTResult = currentASTResult;
572			if (blk.getLabel() != null) {
573				currentASTResult = blk.getLabel();
574			}
575	
576			boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
577	
578			CppBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
579			genBlockFinish(howToFinish, "goto " + label + ";");
580			
581			tabs--;
582			println("} while (true);");
583			println(label+":;");
584			println("}");
585	
586			// Restore previous AST generation
587			currentASTResult = saveCurrentASTResult;
588		}
589		/** Generate an alternative.
590		  * @param alt  The alternative to generate
591		  * @param blk The block to which the alternative belongs
592		  */
593		protected void genAlt(Alternative alt, AlternativeBlock blk) {
594			// Save the AST generation state, and set it to that of the alt
595			boolean savegenAST = genAST;
596			genAST = genAST && alt.getAutoGen();
597	
598			boolean oldsaveTest = saveText;
599			saveText = saveText && alt.getAutoGen();
600	
601			// Reset the variable name map for the alternative
602			Hashtable saveMap = treeVariableMap;
603			treeVariableMap = new Hashtable();
604	
605			// Generate try block around the alt for  error handling
606			if (alt.exceptionSpec != null) {
607				println("try {      // for error handling");
608				tabs++;
609			}
610	
611			AlternativeElement elem = alt.head;
612			while ( !(elem instanceof BlockEndElement) ) {
613				elem.generate(); // alt can begin with anything. Ask target to gen.
614				elem = elem.next;
615			}
616	
617			if ( genAST) {
618				if (blk instanceof RuleBlock) {
619					// Set the AST return value for the rule
620					RuleBlock rblk = (RuleBlock)blk;
621					println(rblk.getRuleName() + "_AST = currentAST.root;");
622				} 
623				else if (blk.getLabel() != null) {
624					// ### future: also set AST value for labeled subrules.
625					// println(blk.getLabel() + "_AST = currentAST.root;");
626				}
627			}
628	
629			if (alt.exceptionSpec != null) {
630				// close try block
631				tabs--;
632				println("}");
633				genErrorHandler(alt.exceptionSpec);
634			}
635	
636			genAST = savegenAST;
637			saveText = oldsaveTest;
638	
639			treeVariableMap = saveMap;
640		}
641		/** Generate all the bitsets to be used in the parser or lexer
642		 * Generate the raw bitset data like "long _tokenSet1_data[] = {...};"
643		 * and the BitSet object declarations like "BitSet _tokenSet1 = new BitSet(_tokenSet1_data);"
644		 * Note that most languages do not support object initialization inside a
645		 * class definition, so other code-generators may have to separate the
646		 * bitset declarations from the initializations (e.g., put the initializations
647		 * in the generated constructor instead).
648		 * @param bitsetList The list of bitsets to generate.
649		 * @param maxVocabulary Ensure that each generated bitset can contain at least this value.
650		 */
651		protected void genBitsets(
652			Vector bitsetList,
653			int maxVocabulary,
654			String prefix
655		) {
656			println("");
657			for (int i = 0; i < bitsetList.size(); i++)
658			{
659				BitSet p = (BitSet)bitsetList.elementAt(i);
660				// Ensure that generated BitSet is large enough for vocabulary
661				p.growToInclude(maxVocabulary);
662				// initialization data
663				println(
664					"const unsigned long " + prefix + getBitsetName(i) + "_data_" + "[] = { " +
665					p.toStringOfHalfWords() + 
666					" };"
667				);
668				// BitSet object
669				println(
670					"const BitSet " + prefix + getBitsetName(i) + "(" +
671					getBitsetName(i) + "_data_," + p.size()/32 +
672					");"
673				);
674			}
675		}
676		protected void genBitsetsHeader(
677			Vector bitsetList,
678			int maxVocabulary
679		) {
680			println("");
681			for (int i = 0; i < bitsetList.size(); i++)
682			{
683				BitSet p = (BitSet)bitsetList.elementAt(i);
684				// Ensure that generated BitSet is large enough for vocabulary
685				p.growToInclude(maxVocabulary);
686				// initialization data
687				println("static const unsigned long " + getBitsetName(i) + "_data_" + "[];");
688				// BitSet object
689				println("static const BitSet " + getBitsetName(i) + ";");
690			}
691		}
692		/** Generate the finish of a block, using a combination of the info
693		 * returned from genCommonBlock() and the action to perform when
694		 * no alts were taken
695		 * @param howToFinish The return of genCommonBlock()
696		 * @param noViableAction What to generate when no alt is taken
697		 */
698		private void genBlockFinish(CppBlockFinishingInfo howToFinish, String noViableAction)
699		{
700			if (howToFinish.needAnErrorClause &&
701				 (howToFinish.generatedAnIf || howToFinish.generatedSwitch)) {
702				if ( howToFinish.generatedAnIf ) {
703					println("else {");
704				}
705				else {
706					println("{");
707				}
708				tabs++;
709				println(noViableAction);
710				tabs--;
711				println("}");
712			}
713	
714			if ( howToFinish.postscript!=null ) {
715				println(howToFinish.postscript);
716			}
717		}
718		/** Generate the header for a block, which may be a RuleBlock or a
719		 * plain AlternativeBLock.  This generates any variable declarations,
720		 * init-actions, and syntactic-predicate-testing variables.
721		 * @blk The block for which the preamble is to be generated.
722		 */
723		protected void genBlockPreamble(AlternativeBlock blk) {
724			// define labels for rule blocks.
725			if ( blk instanceof RuleBlock ) {
726				RuleBlock rblk = (RuleBlock)blk;
727				if ( rblk.labeledElements!=null ) {
728					for (int i=0; i<rblk.labeledElements.size(); i++) {
729	
730						AlternativeElement a = (AlternativeElement)rblk.labeledElements.elementAt(i);
731						//System.out.println("looking at labeled element: "+a);
732						// Variables for labeled rule refs and subrules are different than
733						// variables for grammar atoms.  This test is a little tricky because
734						// we want to get all rule refs and ebnf, but not rule blocks or
735						// syntactic predicates
736						if (
737							a instanceof RuleRefElement ||
738							a instanceof AlternativeBlock &&
739							!(a instanceof RuleBlock) &&
740							!(a instanceof SynPredBlock)
741						) {
742	
743							if (
744								!(a instanceof RuleRefElement) && 
745								((AlternativeBlock)a).not &&
746								analyzer.subruleCanBeInverted(((AlternativeBlock)a), grammar instanceof LexerGrammar)
747							) {
748								// Special case for inverted subrules that will be inlined.
749								// Treat these like token or char literal references
750								println(labeledElementType + " " + a.getLabel() + " = " + labeledElementInit + ";");
751								if (grammar.buildAST) {
752									println(labeledElementASTType+" " + a.getLabel() + "_AST = nullAST;");
753								}
754							}
755							else {
756								if (grammar.buildAST) {
757									// Always gen AST variables for labeled elements, even if the
758									// element itself is marked with !
759									println(labeledElementASTType+" " + a.getLabel() + "_AST = nullAST;");
760								}
761								if ( grammar instanceof LexerGrammar ) {
762									println("RefToken "+a.getLabel()+"(0);");
763								}
764								if (grammar instanceof TreeWalkerGrammar) {
765									// always generate rule-ref variables for tree walker
766									println(labeledElementType + " " + a.getLabel() + " = " + labeledElementInit + ";");
767								}
768							}
769						}
770						else {
771							// It is a token or literal reference.  Generate the
772							// correct variable type for this grammar
773							println(labeledElementType + " " + a.getLabel() + " = " + labeledElementInit + ";");
774							// In addition, generate *_AST variables if building ASTs
775							if (grammar.buildAST) {
776								println(labeledElementASTType+" " + a.getLabel() + "_AST = nullAST;");
777							}
778						}
779					}
780				}
781			}
782	
783			// dump out init action
784			if ( blk.initAction!=null ) {
785				printAction(
786					processActionForTreeSpecifiers(blk.initAction, 0, currentRule, null)
787				);
788			}
789		}
790		public void genBody(LexerGrammar g) throws IOException {
791			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".cpp");
792			//SAS: changed for proper text file io
793			
794			genAST = false;	// no way to gen trees.
795			saveText = true;	// save consumed characters.
796	
797			tabs=0;
798	
799			// Generate header common to all C++ output files
800			genHeader();
801			// Do not use printAction because we assume tabs==0
802			println(behavior.headerAction);
803	
804			// Construct a charbuffer appropriate to the type of processing being done.
805			String charBufferName = "CharBuffer";
806	
807			// Generate user-defined lexer file preamble
808			println(grammar.preambleAction);
809	
810			// Generate header specific to lexer C++ file
811			println("#include \"" + grammar.getClassName() + ".hpp\"");
812			println("#include \"" + grammar.tokenManager.getName() + "TokenTypes.hpp\"");
813			println("#include \"antlr/ScannerException.hpp\""+System.getProperty("line.separator"));
814	
815			// Generate lexer class definition
816			String sup=null;
817			if ( grammar.superClass!=null ) {
818				sup = grammar.superClass;
819			}
820			else {
821				sup = grammar.getSuperClass();
822			}
823	
824			// Generate user-defined lexer class members
825	//		print(
826	//			processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
827	//		);
828	
829			//
830			// Generate the constructor from InputStream
831			//
832			println(grammar.getClassName() + "::" + grammar.getClassName() + "(std::istream& in)");
833			tabs++;
834			println(": " + sup + "(new "+charBufferName+"(in))");
835			tabs--;
836			println("{");
837			tabs++;
838			println("setCaseSensitive("+g.caseSensitive+");");
839			println("initLiterals();");
840	//		if ( grammar.debuggingOutput ) println("ruleNames  = _ruleNames;");
841			tabs--;
842			println("}"+System.getProperty("line.separator"));
843	
844			// Generate the constructor from CharBuffer
845			println(grammar.getClassName() + "::" + grammar.getClassName() + "("+charBufferName+"& cb)");
846			tabs++;
847			println(": " + sup + "(cb)");
848			tabs--;
849			println("{");
850			tabs++;
851			println("setCaseSensitive("+g.caseSensitive+");");
852			println("initLiterals();");
853			tabs--;
854			println("}"+System.getProperty("line.separator"));
855	
856			println("void " + grammar.getClassName() + "::initLiterals()");
857			println("{");
858			tabs++;
859			// Generate the initialization of the map
860			// containing the string literals used in the lexer
861			// The literals variable itself is in CharScanner
862			Enumeration ids = grammar.tokenManager.getTokenSymbolElements();
863			while ( ids.hasMoreElements() ) {
864				TokenSymbol sym = (TokenSymbol)ids.nextElement();
865				if ( sym instanceof StringLiteralSymbol ) {
866					StringLiteralSymbol s = (StringLiteralSymbol)sym;
867					println("literals["+s.getId()+"] = "+s.getTokenType()+";");
868				}
869			}
870			// Generate the setting of various generated options.
871			tabs--;
872			println("}");
873	
874			// Generate getCaseSensitiveLiterals() method
875			println("bool " + grammar.getClassName() + "::getCaseSensitiveLiterals() const");
876			println("{");
877			tabs++;
878			println("return "+g.caseSensitiveLiterals + ";");
879			tabs--;
880			println("}");
881	
882			//
883			// Generate nextToken() rule.
884			// nextToken() is a synthetic lexer rule that is the implicit OR of all
885			// user-defined lexer rules.
886			genNextToken();
887	
888			//
889			// Generate code for each rule in the lexer
890			ids = grammar.rules.elements();
891			int ruleNum=0;
892			String ruleNameInits = "const char* "+grammar.getClassName()+"::_ruleNames[] = {"+System.getProperty("line.separator");
893			while ( ids.hasMoreElements() ) {
894				RuleSymbol sym = (RuleSymbol) ids.nextElement();
895				// Don't generate the synthetic rules
896				if (!sym.getId().equals("mnextToken")) {
897					if ( grammar.debuggingOutput ) {
898						ruleNameInits = ruleNameInits + "\t\t\""+sym.getId().substring(1)+"\","+System.getProperty("line.separator");
899					}
900					genRule(sym, false, ruleNum++, grammar.getClassName() + "::");
901				}
902				exitIfError();
903			}
904			if ( grammar.debuggingOutput ) {
905				println(ruleNameInits + "\t0};");
906			}
907	
908			// Generate the bitsets used throughout the lexer
909			genBitsets(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size(), grammar.getClassName() + "::");
910	
911			println("");
912	
913			// Close the lexer output stream
914			currentOutput.close();
915			currentOutput = null;
916		}
917		public void genBody(ParserGrammar g) throws IOException {
918			// Open the output stream for the parser and set the currentOutput
919			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".cpp");
920			//SAS: changed for proper text file io
921			
922			genAST = grammar.buildAST;
923	
924			tabs = 0;
925	
926			// Generate the header common to all output files.
927			genHeader();
928			// Do not use printAction because we assume tabs==0
929			println(behavior.headerAction);
930			
931			// Output the user-defined parser preamble
932			println(grammar.preambleAction);
933	
934			// Generate header for the parser
935			println("#include \"" + grammar.getClassName() + ".hpp\"");
936			println("#include \"" + grammar.tokenManager.getName() + "TokenTypes.hpp\"");
937			println("#include \"antlr/NoViableAltException.hpp\"");
938			println("#include \"antlr/SemanticException.hpp\"");
939	//		if (grammar.buildAST) {
940	//			println("import antlr.collections.AST;");
941	//			println("import antlr.ASTPair;");
942	//			println("import antlr.collections.impl.ASTArray;");
943	//		}
944			
945			String sup=null;
946			if ( grammar.superClass!=null ) {
947				sup = grammar.superClass;
948			}
949			else {
950				sup = grammar.getSuperClass();
951			}
952	
953	//		// Generate user-defined parser class members
954	//		println(grammar.classMemberAction);
955	
956			// Generate parser class constructor from TokenBuffer
957			print(grammar.getClassName() + "::" + grammar.getClassName());
958			println("(TokenBuffer& tokenBuf, int k)");
959			println(": " + sup + "(tokenBuf,k)");
960			println("{");
961			tabs++;
962			println("setTokenNames(_tokenNames);");
963	//		if ( grammar.debuggingOutput ) {
964	//			print("initDebugging(new File(\"" + tool.grammarFile+"\"),");
965	//			println("new File(\""+grammar.getClassName()+".java\"));");
966	//		}
967			tabs--;
968			println("}"+System.getProperty("line.separator"));
969	
970			print(grammar.getClassName() + "::" + grammar.getClassName());
971			println("(TokenBuffer& tokenBuf)");
972			println(": " + sup + "(tokenBuf," + grammar.maxk + ")");
973			println("{");
974			tabs++;
975			println("setTokenNames(_tokenNames);");
976	//		if ( grammar.debuggingOutput ) {
977	//			print("initDebugging(new File(\"" + tool.grammarFile+"\"),");
978	//			println("new File(\""+grammar.getClassName()+".java\"));");
979	//		}
980			tabs--;
981			println("}"+System.getProperty("line.separator"));
982	
983			// Generate parser class constructor from Tokenizer (lexer)
984			print(grammar.getClassName() + "::" + grammar.getClassName());
985			println("(Tokenizer& lexer, int k)");
986			println(": " + sup + "(lexer,k)");
987			println("{");
988			tabs++;
989			println("setTokenNames(_tokenNames);");
990	//		if ( grammar.debuggingOutput ) println("ruleNames = _ruleNames;");
991	//		if ( grammar.debuggingOutput ) {
992	//			print("initDebugging(new File(\"" + tool.grammarFile + "\"),");
993	//			println("new File(\"" + grammar.getClassName() + ".java\"))");
994	//		}
995			tabs--;
996			println("}"+System.getProperty("line.separator"));
997	
998			print(grammar.getClassName() + "::" + grammar.getClassName());
999			println("(Tokenizer& lexer)");
1000			println(": " + sup + "(lexer," + grammar.maxk + ")");
1001			println("{");
1002			tabs++;
1003			println("setTokenNames(_tokenNames);");
1004	//		if ( grammar.debuggingOutput ) println("ruleNames = _ruleNames;");
1005	//		if ( grammar.debuggingOutput ) {
1006	//			print("initDebugging(new File(\"" + tool.grammarFile + "\"),");
1007	//			println("new File(\"" + grammar.getClassName() + ".java\"))");
1008	//		}
1009			tabs--;
1010			println("}"+System.getProperty("line.separator"));
1011	
1012			// Generate code for each rule in the grammar
1013			Enumeration ids = grammar.rules.elements();
1014			int ruleNum=0;
1015			String ruleNameInits = "const char* "+grammar.getClassName()+"::_ruleNames[] = {"+System.getProperty("line.separator");
1016			while ( ids.hasMoreElements() ) {
1017				GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1018				if ( sym instanceof RuleSymbol) {
1019					RuleSymbol rs = (RuleSymbol)sym;
1020					if ( grammar.debuggingOutput ) {
1021						ruleNameInits = ruleNameInits +
1022							"\t\t\""+rs.getId()+"\","+System.getProperty("line.separator");
1023					}
1024					genRule(rs, rs.references.size()==0, ruleNum++, grammar.getClassName() + "::");
1025				}
1026				exitIfError();
1027			}
1028	
1029			if ( grammar.debuggingOutput )
1030				println(ruleNameInits+"\t0};");
1031	
1032			// Generate the token names
1033			genTokenStrings(grammar.getClassName() + "::");
1034	
1035			// Generate the bitsets used throughout the grammar
1036			genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType(), grammar.getClassName() + "::");
1037	
1038	//		// Close class definition
1039			println("");
1040			println("");
1041	
1042			// Close the parser output stream
1043			currentOutput.close();
1044			currentOutput = null;
1045		}
1046		public void genBody(TreeWalkerGrammar g) throws IOException {
1047			// Open the output stream for the parser and set the currentOutput
1048			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".cpp");
1049			//SAS: changed for proper text file io
1050			
1051			genAST = grammar.buildAST;
1052			tabs = 0;
1053	
1054			// Generate the header common to all output files.
1055			genHeader();
1056			// Do not use printAction because we assume tabs==0
1057			println(behavior.headerAction);
1058			
1059			// Output the user-defined parser premamble
1060			println(grammar.preambleAction);
1061	
1062			// Generate header for the parser
1063			println("#include \"" + grammar.getClassName() + ".hpp\"");
1064			println("#include \"" + grammar.tokenManager.getName() + "TokenTypes.hpp\"");
1065			println("#include \"antlr/Token.hpp\"");
1066			println("#include \"antlr/AST.hpp\"");
1067			println("#include \"antlr/ParserException.hpp\"");
1068			println("#include \"antlr/NoViableAltException.hpp\"");
1069			println("#include \"antlr/MismatchedTokenException.hpp\"");
1070			println("#include \"antlr/SemanticException.hpp\"");
1071			println("#include \"antlr/BitSet.hpp\"");
1072	//		if (grammar.buildAST) {
1073	//			println("import antlr.ASTPair;");
1074	//			println("import antlr.collections.impl.ASTArray;");
1075	//		}
1076		
1077			// Generate parser class definition
1078			String sup=null;
1079			if ( grammar.superClass!=null ) {
1080				sup = grammar.superClass;
1081			}
1082			else {
1083				sup = grammar.getSuperClass();
1084			}
1085	
1086	//		// Generate user-defined parser class members
1087	//		print(
1088	//			processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1089	//		);
1090	
1091			// Generate default parser class constructor
1092			println(grammar.getClassName() + "::" + grammar.getClassName() + "() {");
1093			tabs++;
1094			println("setTokenNames(_tokenNames);");
1095			if ( grammar.debuggingOutput ) println("ruleNames  = _ruleNames;");
1096			tabs--;
1097			println("}"+System.getProperty("line.separator"));
1098	
1099			// Generate code for each rule in the grammar
1100			Enumeration ids = grammar.rules.elements();
1101			int ruleNum=0;
1102			String ruleNameInits = "";
1103			while ( ids.hasMoreElements() ) {
1104				GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1105				if ( sym instanceof RuleSymbol) {
1106					RuleSymbol rs = (RuleSymbol)sym;
1107					genRule(rs, rs.references.size()==0, ruleNum++, grammar.getClassName() + "::");
1108				}
1109				exitIfError();
1110			}
1111	
1112	//   		if ( grammar.debuggingOutput ) //{
1113	//   		    println(ruleNameInits+"\n};");
1114	
1115			// Generate the token names
1116			genTokenStrings(grammar.getClassName() + "::");
1117	
1118			// Generate the bitsets used throughout the grammar
1119			genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType(), grammar.getClassName() + "::");
1120	
1121			// Close class definition
1122			println("");
1123			println("");
1124	
1125			// Close the parser output stream
1126			currentOutput.close();
1127			currentOutput = null;
1128		}
1129		/** Generate a series of case statements that implement a BitSet test.
1130		 * @param p The Bitset for which cases are to be generated
1131		 */
1132		protected void genCases(BitSet p) {
1133			if ( DEBUG_CODE_GENERATOR ) System.out.println("genCases("+p+")");
1134			int[] elems;
1135	
1136			elems = p.toArray();
1137			// Wrap cases four-per-line for lexer, one-per-line for parser
1138			int wrap = (grammar instanceof LexerGrammar) ? 4 : 1;
1139			int j=1;
1140			boolean startOfLine = true;
1141			for (int i = 0; i < elems.length; i++) {
1142				if (j==1) {
1143					print("");
1144				} else {
1145					_print("  ");
1146				}
1147				_print("case " + getValueString(elems[i]) + ":");
1148	
1149				if (j==wrap) {
1150					_println(""); 
1151					startOfLine = true;
1152					j=1;
1153				}
1154				else {
1155					j++;
1156					startOfLine = false;
1157				}
1158			}
1159			if (!startOfLine) {
1160				_println("");
1161			}
1162		}
1163		/**Generate common code for a block of alternatives; return a postscript
1164		 * that needs to be generated at the end of the block.  Other routines
1165		 * may append else-clauses and such for error checking before the postfix
1166		 * is generated.
1167		 * If the grammar is a lexer, then generate alternatives in an order where 
1168		 * alternatives requiring deeper lookahead are generated first, and 
1169		 * EOF in the lookahead set reduces the depth of the lookahead.
1170		 * @param blk The block to generate
1171		 * @param noTestForSingle If true, then it does not generate a test for a single alternative.
1172		 */
1173		public CppBlockFinishingInfo genCommonBlock(
1174			AlternativeBlock blk,
1175			boolean noTestForSingle)
1176		{
1177			int nIF=0;
1178			boolean createdLL1Switch = false;
1179			int closingBracesOfIFSequence = 0;
1180			CppBlockFinishingInfo finishingInfo = new CppBlockFinishingInfo();
1181			if ( DEBUG_CODE_GENERATOR ) System.out.println("genAltBlk("+blk+")");
1182	
1183			// Save the AST generation state, and set it to that of the block
1184			boolean savegenAST = genAST;
1185			genAST = genAST && blk.getAutoGen();
1186	
1187			boolean oldsaveTest = saveText;
1188			saveText = saveText && blk.getAutoGen();
1189	
1190			// Is this block inverted?  If so, generate special-case code
1191			if (
1192				blk.not &&
1193				analyzer.subruleCanBeInverted(blk, grammar instanceof LexerGrammar)
1194			) {
1195				Lookahead p = analyzer.look(1, blk);
1196				// Variable assignment for labeled elements
1197				if (blk.getLabel() != null && syntacticPredLevel == 0) {
1198					println(blk.getLabel() + " = " + lt1Value + ";");
1199				}
1200	
1201				// AST
1202				genElementAST(blk);
1203	
1204				String astArgs="";
1205				if (grammar instanceof TreeWalkerGrammar) {
1206					astArgs="_t,";
1207				}
1208	
1209				// match the bitset for the alternative
1210				println("match(" + astArgs + getBitsetName(markBitsetForGen(p.fset)) + ");");
1211				
1212				// tack on tree cursor motion if doing a tree walker
1213				if (grammar instanceof TreeWalkerGrammar) {
1214					println("_t = _t->getNextSibling();");
1215				}
1216				return finishingInfo;
1217			}
1218	
1219			// Special handling for single alt
1220			if (blk.getAlternatives().size() == 1) {
1221				Alternative alt = blk.getAlternativeAt(0);
1222				// Generate a warning if there is a synPred for single alt.
1223				if (alt.synPred != null)
1224				{
1225					tool.warning(
1226						"Syntactic predicate superfluous for single alternative", 
1227						blk.getAlternativeAt(0).synPred.getLine()
1228					);
1229				}
1230				if (noTestForSingle) {
1231					if (alt.semPred != null) {
1232						// Generate validating predicate
1233						genSemPred(alt.semPred);
1234					}
1235					genAlt(alt, blk);
1236					return finishingInfo;
1237				}
1238			}
1239	
1240			// count number of simple LL(1) cases; only do switch for
1241			// many LL(1) cases (no preds, no end of token refs)
1242			// We don't care about exit paths for (...)*, (...)+
1243			// because we don't explicitly have a test for them
1244			// as an alt in the loop.
1245			int nLL1 = 0;
1246			for (int i=0; i<blk.getAlternatives().size(); i++) {
1247				Alternative a = blk.getAlternativeAt(i);
1248				if ( a.lookaheadDepth == 1 && a.semPred == null &&
1249					  !a.cache[1].containsEpsilon()) {
1250					nLL1++;
1251				}
1252			}
1253	
1254			// do LL(1) cases
1255			if ( nLL1 >= makeSwitchThreshold) {
1256				// Determine the name of the item to be compared
1257				String testExpr = lookaheadString(1);
1258				createdLL1Switch = true;
1259				// when parsing trees, convert null to valid tree node with NULL lookahead
1260				if ( grammar instanceof TreeWalkerGrammar ) {
1261					println("if (_t==nullAST) _t=ASTNULL;");
1262				}
1263				println("switch ( "+testExpr+") {");
1264				for (int i=0; i<blk.alternatives.size(); i++) {
1265					Alternative alt = blk.getAlternativeAt(i);
1266					// ignore any non-LL(1) alts, predicated alts or end-of-token alts
1267					if ( alt.lookaheadDepth!=1 || alt.semPred != null ||
1268						  alt.cache[1].containsEpsilon() ) {
1269						continue;
1270					}
1271					Lookahead p = alt.cache[1];
1272					if (p.fset.degree() == 0 && !p.containsEpsilon()) {
1273						tool.warning("Alternate omitted due to empty prediction set",
1274							alt.head.getLine());
1275					}
1276					else {
1277						genCases(p.fset);
1278						println("{");
1279						tabs++;
1280						genAlt(alt, blk);
1281						println("break;");
1282						tabs--;
1283						println("}");
1284					}
1285				}
1286				println("default:");
1287				tabs++;
1288			}
1289	
1290			// do non-LL(1) and nondeterministic cases
1291			// This is tricky in the lexer, because of cases like:
1292			//     STAR : '*' ;
1293			//     ASSIGN_STAR : "*=";
1294			// Since nextToken is generated without a loop, then the STAR will
1295			// have end-of-token as it's lookahead set for LA(2).  So, we must generate the
1296			// alternatives containing trailing end-of-token in their lookahead sets *after*
1297			// the alternatives without end-of-token.  This implements the usual
1298			// lexer convention that longer matches come before shorter ones, e.g.
1299			// "*=" matches ASSIGN_STAR not STAR
1300			//
1301			// For non-lexer grammars, this does not sort the alternates by depth
1302			// Note that alts whose lookahead is purely end-of-token at k=1 end up
1303			// as default or else clauses.
1304			int startDepth = (grammar instanceof LexerGrammar) ? grammar.maxk : 0;
1305			for (int altDepth = startDepth; altDepth >= 0; altDepth--) {
1306				if ( DEBUG_CODE_GENERATOR ) System.out.println("checking depth "+altDepth);
1307				for (int i=0; i<blk.alternatives.size(); i++) {
1308					Alternative alt = blk.getAlternativeAt(i);
1309					if ( DEBUG_CODE_GENERATOR ) System.out.println("genAlt: "+i);
1310					// if we made a switch above, ignore what we already took care
1311					// of.  Specifically, LL(1) alts with no preds
1312					// that do not have end-of-token in their prediction set
1313					if ( createdLL1Switch &&
1314						  (alt.lookaheadDepth==1 && alt.semPred == null &&
1315						   !alt.cache[1].containsEpsilon()) ) {
1316						if ( DEBUG_CODE_GENERATOR ) System.out.println("ignoring alt because it was in the switch");
1317						continue;
1318					}
1319					String e;
1320	
1321					boolean unpredicted = false;
1322	
1323					if (grammar instanceof LexerGrammar) {
1324						// Calculate the "effective depth" of the alt, which is the max
1325						// depth at which cache[depth]!=end-of-token
1326						int effectiveDepth = alt.lookaheadDepth;
1327						if (effectiveDepth == GrammarAnalyzer.NONDETERMINISTIC) {
1328							// use maximum lookahead
1329							effectiveDepth = grammar.maxk;
1330						}
1331						while (
1332							effectiveDepth >= 1 &&
1333							alt.cache[effectiveDepth].containsEpsilon()
1334						) 
1335						{
1336							effectiveDepth--;
1337						}
1338						// Ignore alts whose effective depth is other than the ones we
1339						// are generating for this iteration.
1340						if (effectiveDepth != altDepth) {
1341							if ( DEBUG_CODE_GENERATOR )
1342								System.out.println("ignoring alt because effectiveDepth!=altDepth;"+effectiveDepth+"!="+altDepth);
1343							continue;
1344						}
1345						unpredicted = lookaheadIsEmpty(alt, effectiveDepth);
1346						e = getLookaheadTestExpression(alt, effectiveDepth);
1347					} else {
1348						unpredicted = lookaheadIsEmpty(alt, grammar.maxk);
1349						e = getLookaheadTestExpression(alt, grammar.maxk);
1350					}
1351	
1352					if (unpredicted && alt.semPred==null && alt.synPred==null) {
1353						// The alt has empty prediction set and no predicate to help out.
1354						// if we have not generated
1355						// a previous if, just put {...} around the end-of-token clause
1356						if ( nIF==0 ) {
1357							println("{");
1358						}
1359						else {
1360							println("else {");
1361						}
1362						finishingInfo.needAnErrorClause = false;
1363						// continue;
1364					}
1365					else { // check for sem and syn preds
1366	
1367						// Add any semantic predicate expression to the lookahead test
1368						if ( alt.semPred != null ) {
1369							e = "("+e+"&&("+alt.semPred +"))";
1370						}
1371	
1372						// Generate any syntactic predicates
1373						if ( nIF>0 ) {
1374							if ( alt.synPred != null ) {
1375								println("else {");
1376								tabs++;
1377								genSynPred( alt.synPred, e );
1378								closingBracesOfIFSequence++;
1379							}
1380							else {
1381								println("else if " + e + " {");
1382							}
1383						}
1384						else {
1385							if ( alt.synPred != null ) {
1386								genSynPred( alt.synPred, e );
1387							}
1388							else {
1389								// when parsing trees, convert null to valid tree node
1390								// with NULL lookahead.
1391								if ( grammar instanceof TreeWalkerGrammar ) {
1392									println("if (_t==nullAST) _t=ASTNULL;");
1393								}
1394								println("if " + e + " {");
1395							}
1396						}
1397	
1398					}
1399	
1400					nIF++;
1401					tabs++;
1402					genAlt(alt, blk);
1403					tabs--;
1404					println("}");
1405				}
1406			}
1407			String ps = "";
1408			for (int i=1; i<=closingBracesOfIFSequence; i++) {
1409				tabs--;
1410				ps+="}";
1411			}
1412	
1413			// Restore the AST generation state
1414			genAST = savegenAST;
1415			
1416			// restore save text state
1417			saveText=oldsaveTest;
1418	
1419			// Return the finishing info.
1420			if ( createdLL1Switch ) {
1421				tabs--;
1422				finishingInfo.postscript = ps+"}";
1423				finishingInfo.generatedSwitch = true;
1424				finishingInfo.generatedAnIf = nIF>0;
1425				//return new CppBlockFinishingInfo(ps+"}",true,nIF>0); // close up switch statement
1426	
1427			}
1428			else {
1429				finishingInfo.postscript = ps;
1430				finishingInfo.generatedSwitch = false;
1431				finishingInfo.generatedAnIf = nIF>0;
1432				//return new CppBlockFinishingInfo(ps, false,nIF>0);
1433			}
1434			return finishingInfo;
1435		}
1436		/** Generate code to link an element reference into the AST */
1437		private void genElementAST(AlternativeElement el) {
1438			if (grammar.buildAST && syntacticPredLevel == 0) {
1439				boolean doNoGuessTest = (
1440					grammar.hasSyntacticPredicate &&
1441					(
1442						el.getLabel() != null ||
1443						el.getAutoGenType() != GrammarElement.AUTO_GEN_BANG
1444					)
1445				);
1446	
1447				String elementRef;
1448				String astName;
1449	
1450				// Generate names and declarations of the AST variable(s)
1451				if (el.getLabel() != null) {
1452					elementRef = el.getLabel();
1453					astName = el.getLabel() + "_AST";
1454				} else {
1455					elementRef = lt1Value;
1456					// Generate AST variables for unlabeled stuff
1457					astName = "tmp" + astVarNumber + "_AST";
1458					astVarNumber++;
1459					// Generate the declaration
1460					println(labeledElementASTType+" " + astName + " = nullAST;");
1461					// Map the generated AST variable in the alternate
1462					mapTreeVariable(el, astName);
1463					if (grammar instanceof TreeWalkerGrammar) {
1464						// Generate an "input" AST variable also
1465						println(labeledElementASTType+" " + astName + "_in = nullAST;");
1466					}
1467				}
1468	
1469				// Enclose actions with !guessing
1470				if (doNoGuessTest) {
1471					println("if (guessing==0) {"); 
1472					tabs++;
1473				}
1474	
1475				if (el.getLabel() != null) {
1476					println(astName + " = "+getASTCreateString(elementRef) + ";");
1477				} else {
1478					elementRef = lt1Value;
1479					println(astName + " = "+getASTCreateString(elementRef) + ";");
1480					// Map the generated AST variable in the alternate
1481					if (grammar instanceof TreeWalkerGrammar) {
1482						// set "input" AST variable also
1483						println(astName + "_in = " + elementRef + ";");
1484					}
1485				}
1486	
1487				if (genAST) {
1488					switch (el.getAutoGenType()) {
1489					case GrammarElement.AUTO_GEN_NONE:
1490						println("astFactory.addASTChild(currentAST, " + astName + ");");
1491						break;
1492					case GrammarElement.AUTO_GEN_CARET:
1493						println("astFactory.makeASTRoot(currentAST, " + astName + ");");
1494						break;
1495					default:
1496						break;
1497					}
1498				}
1499				if (doNoGuessTest) {
1500					tabs--;
1501					println("}");
1502				}
1503			}
1504		}
1505		/** Close the try block and generate catch phrases 
1506		 * if the element has a labeled handler in the rule 
1507		 */
1508		private void genErrorCatchForElement(AlternativeElement el) {
1509			if (el.getLabel() == null) return;
1510			String r = el.enclosingRuleName;
1511			if ( grammar instanceof LexerGrammar ) {
1512				r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
1513			}
1514			RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
1515			if (rs == null) {
1516				tool.panic("Enclosing rule not found!");
1517			}
1518			ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
1519			if (ex != null) {
1520				tabs--;
1521				println("}");
1522				genErrorHandler(ex);
1523			}
1524		}
1525		/** Generate the catch phrases for a user-specified error handler */
1526		private void genErrorHandler(ExceptionSpec ex) {
1527			// Each ExceptionHandler in the ExceptionSpec is a separate catch
1528			for (int i = 0; i < ex.handlers.size(); i++)
1529			{
1530				ExceptionHandler handler = (ExceptionHandler)ex.handlers.elementAt(i);
1531				// Generate catch phrase
1532				println("catch (" + handler.exceptionTypeAndName.getText() + ") {");
1533				tabs++;
1534				if (grammar.hasSyntacticPredicate) {
1535					println("if (guessing==0) {");
1536					tabs++;
1537				}
1538	
1539				// When not guessing, execute user handler action
1540				printAction(
1541					processActionForTreeSpecifiers(handler.action, 0, currentRule, null)
1542				);
1543	
1544				if (grammar.hasSyntacticPredicate) {
1545					tabs--;
1546					println("} else {");
1547					tabs++;
1548					// When guessing, rethrow exception
1549					println(
1550						"throw " + 
1551						extractIdOfAction(handler.exceptionTypeAndName) + 
1552						";"
1553					);
1554					tabs--;
1555					println("}");
1556				}
1557				// Close catch phrase
1558				tabs--;
1559				println("}");
1560			}
1561		}
1562		/** Generate a try { opening if the element has a labeled handler in the rule */
1563		private void genErrorTryForElement(AlternativeElement el) {
1564			if (el.getLabel() == null) return;
1565			String r = el.enclosingRuleName;
1566			if ( grammar instanceof LexerGrammar ) {
1567				r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
1568			}
1569			RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
1570			if (rs == null) {
1571				tool.panic("Enclosing rule not found!");
1572			}
1573			ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
1574			if (ex != null) {
1575				println("try { // for error handling");
1576				tabs++;
1577			}
1578		}
1579		/** Generate a header that is common to all C++ files */
1580		protected void genHeader() 
1581		{
1582			println("/*");
1583			println(" * ANTLR-generated file resulting from grammar " + tool.grammarFile);
1584			println(" * ");
1585			println(" * Terence Parr, MageLang Institute");
1586			println(" * with John Lilley, Empathy Software");
1587			println(" * ANTLR Version " + ANTLRParser.version + "; 1996,1997,1998");
1588			println(" */");
1589			println("");
1590		}
1591		// these are unique to C++ mode
1592	
1593		public void genInclude(LexerGrammar g) throws IOException {
1594			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1595			//SAS: changed for proper text file io
1596			
1597			genAST = false;	// no way to gen trees.
1598			saveText = true;	// save consumed characters.
1599	
1600			tabs=0;
1601	
1602			// Generate a guard wrapper
1603			println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1604			println("#define INC_"+grammar.getClassName()+"_hpp_");
1605			println("");
1606			println("#include \"antlr/config.hpp\"");
1607	
1608			// Generate header common to all C++ output files
1609			genHeader();
1610			// Do not use printAction because we assume tabs==0
1611			println(behavior.headerAction);
1612	
1613			// Construct a charbuffer appropriate to the type of processing being done.
1614			String charBufferName = "CharBuffer";
1615	
1616			// Generate header specific to lexer header file
1617			println("#include \"antlr/CommonToken.hpp\"");
1618			println("#include \"antlr/"+charBufferName+".hpp\"");
1619			println("#include \"antlr/BitSet.hpp\"");
1620	//		println("#include <sys/types.h>");
1621	
1622			// Find the name of the super class
1623			String sup=null;
1624			if ( grammar.superClass!=null ) {
1625				sup = grammar.superClass;
1626				println("#include \""+sup+".hpp\"");
1627			}
1628			else {
1629				sup = grammar.getSuperClass();
1630				println("#include \"antlr/"+grammar.getSuperClass()+".hpp\"");
1631			}
1632	
1633			// Generate user-defined lexer file preamble
1634			println(grammar.preambleAction);
1635	
1636			// Generate lexer class definition
1637			println("class " + grammar.getClassName() + " : public " + sup);
1638	/*
1639			println(" implements " + grammar.tokenManager.getName() + "TokenTypes, Tokenizer");
1640			Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
1641			if ( tsuffix != null ) {
1642				String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
1643				if ( suffix != null ) {
1644					print(", "+suffix);  // must be an interface name for Java
1645				}
1646			}
1647	*/
1648			println(" {");
1649			
1650	//		if ( grammar.debuggingOutput ) {
1651	//            // serialize the parser grammar
1652	//            ObjectOutput s = new ObjectOutputStream(
1653	//                                new FileOutputStream(tool.grammarFile +
1654	//                                                        ".lexerGrammar"));
1655	//            s.writeObject(grammar);
1656	//            s.close();
1657	//        }
1658	
1659			// Generate user-defined lexer class members
1660			print(
1661				processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1662			);
1663			
1664			// Generate initLiterals() method
1665			tabs=0;
1666			println("private:");
1667			tabs=1;
1668			println("void initLiterals();");
1669	
1670			// Generate getCaseSensitiveLiterals() method
1671			tabs=0;
1672			println("public:");
1673			tabs=1;
1674			println("bool getCaseSensitiveLiterals() const;");
1675	
1676			// Make constructors public
1677			tabs=0;
1678			println("public:");
1679			tabs=1;
1680	
1681			// Generate the constructor from std::istream
1682			println(grammar.getClassName() + "(std::istream& in);");
1683	
1684			// Generate the constructor from CharBuffer
1685			println(grammar.getClassName() + "(" + charBufferName + "& cb);");
1686	
1687			// Generate nextToken() rule.
1688			// nextToken() is a synthetic lexer rule that is the implicit OR of all
1689			// user-defined lexer rules.
1690			println("RefToken nextToken();");
1691	
1692			// Generate code for each rule in the lexer
1693			Enumeration ids = grammar.rules.elements();
1694			int ruleNum=0;
1695			while ( ids.hasMoreElements() ) {
1696				RuleSymbol sym = (RuleSymbol) ids.nextElement();
1697				// Don't generate the synthetic rules
1698				if (!sym.getId().equals("mnextToken")) {
1699					genRuleHeader(sym, false);
1700				}
1701				exitIfError();
1702			}
1703			if ( grammar.debuggingOutput ) {
1704				tabs=0;
1705				println("public:");
1706				tabs=1;
1707				println("static const char* _ruleNames[];");
1708			}
1709	
1710			// Make the rest private
1711			tabs=0;
1712			println("private:");
1713			tabs=1;
1714	
1715			// Generate the bitsets used throughout the lexer
1716			genBitsetsHeader(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size());
1717	
1718			tabs=0;
1719			println("};");
1720			println("");
1721	
1722			// Generate a guard wrapper
1723			println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1724	
1725			// Close the lexer output stream
1726			currentOutput.close();
1727			currentOutput = null;
1728		}
1729		// the remaining methods still need checking
1730	
1731	
1732	
1733	
1734	
1735	
1736	
1737	
1738	
1739	
1740	
1741		public void genInclude(ParserGrammar g) throws IOException {
1742			// Open the output stream for the parser and set the currentOutput
1743			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1744			//SAS: changed for proper text file io
1745			
1746			genAST = grammar.buildAST;
1747	
1748			tabs = 0;
1749	
1750			// Generate a guard wrapper
1751			println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1752			println("#define INC_"+grammar.getClassName()+"_hpp_");
1753			println("");
1754			println("#include \"antlr/config.hpp\"");
1755	
1756			// Generate the header common to all output files.
1757			genHeader();
1758			// Do not use printAction because we assume tabs==0
1759			println(behavior.headerAction);
1760			
1761			// Generate header for the parser
1762	//		println("#include <sys/types.h>");
1763			println("#include \"antlr/Tokenizer.hpp\"");
1764			println("#include \"antlr/TokenBuffer.hpp\"");
1765			println("#include \"antlr/"+grammar.getSuperClass()+".hpp\"");
1766	//		println("#include \"antlr/CommonToken.hpp\"");
1767	//		println("#include \"antlr/LLkParser.hpp\"");
1768	//		if (grammar.buildAST) {
1769	//			println("import antlr.collections.AST;");
1770	//			println("import antlr.ASTPair;");
1771	//			println("import antlr.collections.impl.ASTArray;");
1772	//		}
1773			println("");
1774			
1775			// Output the user-defined parser preamble
1776	//		println(grammar.preambleAction);
1777	
1778			// Generate parser class definition
1779			String sup=null;
1780			if ( grammar.superClass!=null ) {
1781				sup = grammar.superClass;
1782			}
1783			else {
1784				sup = grammar.getSuperClass();
1785			}
1786			println("class " + grammar.getClassName() + " : public " + sup);
1787	/*
1788			Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
1789			if ( tsuffix != null ) {
1790				String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
1791				if ( suffix != null ) {
1792					print(", "+suffix);  // must be an interface name for Java
1793				}
1794			}
1795	*/
1796			println(" {");
1797	
1798			// Generate user-defined parser class members
1799			print(
1800				processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1801			);
1802	
1803			// Make constructors and rules public
1804			println("public:");
1805			tabs=1;
1806	
1807			// Generate parser class constructor from TokenBuffer
1808			tabs=0;
1809			println("protected:");
1810			tabs=1;
1811			println(grammar.getClassName() + "(TokenBuffer& tokenBuf, int k);");
1812			tabs=0;
1813			println("public:");
1814			tabs=1;
1815			println(grammar.getClassName() + "(TokenBuffer& tokenBuf);");
1816	
1817			// Generate parser class constructor from Tokenizer (lexer)
1818			tabs=0;
1819			println("protected:");
1820			tabs=1;
1821			println(grammar.getClassName()+"(Tokenizer& lexer, int k);");
1822			tabs=0;
1823			println("public:");
1824			tabs=1;
1825			println(grammar.getClassName()+"(Tokenizer& lexer);");
1826	
1827			// Generate code for each rule in the grammar
1828			Enumeration ids = grammar.rules.elements();
1829			while ( ids.hasMoreElements() ) {
1830				GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1831				if ( sym instanceof RuleSymbol) {
1832					RuleSymbol rs = (RuleSymbol)sym;
1833					genRuleHeader(rs, rs.references.size()==0);
1834				}
1835				exitIfError();
1836			}
1837	
1838			if ( grammar.debuggingOutput )
1839				println("public: static const char* _ruleNames[];");
1840	
1841			// Make the rest private
1842			tabs=0;
1843			println("private:");
1844			tabs=1;
1845	
1846			// Generate the token names
1847			println("static const char* _tokenNames[];");
1848	
1849			// Generate the bitsets used throughout the grammar
1850			genBitsetsHeader(bitsetsUsed, grammar.tokenManager.maxTokenType());
1851	
1852			// Close class definition
1853			tabs=0;
1854			println("};");
1855			println("");
1856	
1857			// Generate a guard wrapper
1858			println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1859	
1860			// Close the parser output stream
1861			currentOutput.close();
1862			currentOutput = null;
1863	
1864	//    if ( grammar.debuggingOutput ) {
1865	//            // serialize the parser grammar
1866	//            ObjectOutput s = new ObjectOutputStream(
1867	//                                new FileOutputStream(tool.grammarFile +
1868	//                                                        ".parserGrammar"));
1869	//            s.writeObject(grammar);
1870	//            s.close();
1871	//            s = null;
1872	//    }
1873		}
1874		public void genInclude(TreeWalkerGrammar g) throws IOException {
1875			// Open the output stream for the parser and set the currentOutput
1876			currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1877			//SAS: changed for proper text file io
1878			
1879			genAST = grammar.buildAST;
1880			tabs = 0;
1881	
1882			// Generate a guard wrapper
1883			println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1884			println("#define INC_"+grammar.getClassName()+"_hpp_");
1885			println("");
1886			println("#include \"antlr/config.hpp\"");
1887	
1888			// Generate the header common to all output files.
1889			genHeader();
1890			// Do not use printAction because we assume tabs==0
1891			println(behavior.headerAction);
1892			
1893			// Find the name of the super class
1894			String sup=null;
1895			if ( grammar.superClass!=null ) {
1896				sup = grammar.superClass;
1897				println("#include \""+sup+".hpp\"");
1898			}
1899			else {
1900				sup = grammar.getSuperClass();
1901				println("#include \"antlr/"+grammar.getSuperClass()+".hpp\"");
1902			}
1903	
1904			// Generate header for the parser
1905		
1906			// Output the user-defined parser premamble
1907			println(grammar.preambleAction);
1908	
1909			// Generate parser class definition
1910			print(System.getProperty("line.separator")+
1911				"class " + grammar.getClassName() + " : public "+sup);
1912	/*
1913			println(" implements " + grammar.tokenManager.getName() + "TokenTypes");
1914			Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
1915			if ( tsuffix != null ) {
1916				String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
1917				if ( suffix != null ) {
1918					print(", "+suffix);  // must be an interface name for Java
1919				}
1920			}
1921	*/
1922			println(" {");
1923	
1924			// Generate user-defined parser class members
1925			print(
1926				processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1927			);
1928	
1929			// Generate default parser class constructor
1930			tabs=0;
1931			println("public:");
1932			tabs=1;
1933			println(grammar.getClassName() + "();");
1934	
1935			// Generate code for each rule in the grammar
1936			Enumeration ids = grammar.rules.elements();
1937			int ruleNum=0;
1938			String ruleNameInits = "";
1939			while ( ids.hasMoreElements() ) {
1940				GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
1941				if ( sym instanceof RuleSymbol) {
1942					RuleSymbol rs = (RuleSymbol)sym;
1943					genRuleHeader(rs, rs.references.size()==0);
1944				}
1945				exitIfError();
1946			}
1947	
1948	//   		if ( grammar.debuggingOutput ) //{
1949	//   		    println(ruleNameInits+"\n};");
1950	
1951			// Make the rest private
1952			tabs=0;
1953			println("private:");
1954			tabs=1;
1955	
1956			// Generate the token names
1957			println("static const char* _tokenNames[];");
1958	
1959			// Generate the bitsets used throughout the grammar
1960			genBitsetsHeader(bitsetsUsed, grammar.tokenManager.maxTokenType());
1961	
1962			// Close class definition
1963			tabs=0;
1964			println("};");
1965			println("");
1966	
1967			// Generate a guard wrapper
1968			println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1969	
1970			// Close the parser output stream
1971			currentOutput.close();
1972			currentOutput = null;
1973		}
1974		private void genLiteralsTest() {
1975			println("_ttype = testLiteralsTable(_ttype);");
1976		}
1977		protected void genMatch(BitSet b) {
1978		}
1979		protected void genMatch(GrammarAtom atom) {
1980			if ( atom instanceof StringLiteralElement ) {
1981				if ( grammar instanceof LexerGrammar ) {
1982					genMatchUsingAtomText(atom);
1983				}
1984				else {
1985					genMatchUsingAtomTokenType(atom);
1986				}
1987			}
1988			else if ( atom instanceof CharLiteralElement ) {
1989				if ( grammar instanceof LexerGrammar ) {
1990					genMatchUsingAtomText(atom);
1991				}
1992				else {
1993					tool.error("cannot ref character literals in grammar: "+atom);				
1994				}
1995			}
1996			else if ( atom instanceof TokenRefElement ) {
1997				genMatchUsingAtomText(atom);
1998			}
1999		}
2000		protected void genMatchUsingAtomText(GrammarAtom atom) {
2001			// match() for trees needs the _t cursor
2002			String astArgs="";
2003			if (grammar instanceof TreeWalkerGrammar) {
2004				astArgs="_t,";
2005			}
2006	
2007			// if in lexer and ! on element, save buffer index to kill later
2008			if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
2009				println("_saveIndex=text.length();");
2010			}
2011	
2012			print(atom.not ? "matchNot(" : "match(");
2013			_print(astArgs);
2014	
2015			// print out what to match
2016			if (atom.atomText.equals("EOF")) {
2017				// horrible hack to handle EOF case
2018				_print("Token::EOF_TYPE");
2019			} 
2020			else {
2021	//			if (grammar instanceof LexerGrammar) {
2022					_print(atom.atomText);
2023	//			} else {
2024	//				_print(atom.atomText + "_");
2025	//			}
2026			}
2027			_println(");");
2028	
2029			if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
2030				println("text.erase(_saveIndex);");      // kill text atom put in buffer
2031			}
2032		}
2033		protected void genMatchUsingAtomTokenType(GrammarAtom atom) {
2034			// match() for trees needs the _t cursor
2035			String astArgs="";
2036			if (grammar instanceof TreeWalkerGrammar) {
2037				astArgs="_t,";
2038			}
2039	
2040			// If the literal can be mangled, generate the symbolic constant instead
2041			String mangledName = null;
2042			String s = astArgs + getValueString(atom.tokenType);
2043	
2044			// matching
2045			println( (atom.not ? "matchNot(" : "match(") + s + ");");
2046		}
2047		/** Generate the nextToken() rule.
2048		 * nextToken() is a synthetic lexer rule that is the implicit OR of all
2049		 * user-defined lexer rules.
2050		 * @param RuleBlock 
2051		 */
2052		public void genNextToken() {
2053			// Are there any public rules?  If not, then just generate a
2054			// fake nextToken().
2055			boolean hasPublicRules = false;
2056			for (int i = 0; i < grammar.rules.size(); i++) {
2057				RuleSymbol rs = (RuleSymbol)grammar.rules.elementAt(i);
2058				if ( rs.isDefined() && rs.access.equals("public") ) {
2059					hasPublicRules = true;
2060					break;
2061				}
2062			}
2063			if (!hasPublicRules) {
2064				println("");
2065				println("RefToken "+grammar.getClassName()+"::nextToken() { return RefToken(new CommonToken(Token::EOF_TYPE, \"\")); }");
2066				println("");
2067				return;
2068			}
2069	
2070			// Create the synthesized nextToken() rule
2071			RuleBlock nextTokenBlk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");
2072			// Define the nextToken rule symbol
2073			RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
2074			nextTokenRs.setDefined();
2075			nextTokenRs.setBlock(nextTokenBlk);
2076			nextTokenRs.access = "private";
2077			grammar.define(nextTokenRs);
2078			// Analyze the nextToken rule
2079			boolean ok = grammar.theLLkAnalyzer.deterministic(nextTokenBlk);
2080	
2081			// Generate the next token rule
2082			println(System.getProperty("line.separator")+"RefToken "+grammar.getClassName()+"::nextToken()");
2083			println("{");
2084			tabs++;
2085			println("RefToken _rettoken;");
2086			println("for (;;) {");
2087			tabs++;
2088			// println("int _ttype = Token::EOF_TYPE;");
2089			println("RefToken _rettoken;");
2090			println("int _ttype = Token::INVALID_TYPE;");
2091			println("resetText();");
2092	
2093			// Generate try around whole thing to trap scanner errors
2094			println("try {   // for error handling");
2095			tabs++;
2096	
2097			// Test for public lexical rules with empty paths
2098			for (int i=0; i<nextTokenBlk.getAlternatives().size(); i++) {
2099				Alternative a = nextTokenBlk.getAlternativeAt(i);
2100				if ( a.cache[1].containsEpsilon() ) {
2101					tool.warning("found optional path in nextToken()");
2102				}
2103			}
2104	
2105			// Generate the block
2106			CppBlockFinishingInfo howToFinish = genCommonBlock(nextTokenBlk, false);
2107			genBlockFinish(
2108				howToFinish,
2109				"if (LA(1)!=EOF) " + throwNoViable +
2110				"_returnToken = makeToken(Token::EOF_TYPE);"
2111			);
2112	
2113			// Generate literals test if desired
2114			// make sure _ttype is set first; note _returnToken must be
2115			// non-null as the rule was required to create it.
2116			println("_ttype = _returnToken->getType();");
2117			if ( ((LexerGrammar)grammar).getTestLiterals()) {
2118				genLiteralsTest();
2119			}
2120	
2121			// return token created by rule reference in switch
2122			println("if ( _ttype!=Token::SKIP ) {");
2123			tabs++;
2124			println("_returnToken->setType(_ttype);");
2125			println("return _returnToken;");
2126			tabs--;
2127			println("}");
2128	
2129			// Close try block
2130			tabs--;
2131			println("}");
2132			println("catch (ScannerException& e) {");
2133			tabs++;
2134			println("consume();");
2135			println("reportError(e);");
2136			tabs--;
2137			println("}");
2138	
2139			// close for-loop
2140			tabs--;
2141			println("}");
2142	
2143			// close method nextToken
2144			tabs--;
2145			println("}"+System.getProperty("line.separator"));
2146		}
2147		/** Gen a named rule block.
2148		 * ASTs are generated for each element of an alternative unless
2149		 * the rule or the alternative have a '!' modifier.
2150		 *
2151		 * If an alternative defeats the default tree construction, it
2152		 * must set <rule>_AST to the root of the returned AST.
2153		 *
2154		 * Each alternative that does automatic tree construction, builds
2155		 * up root and child list pointers in an ASTPair structure.
2156		 *
2157		 * A rule finishes by setting the returnAST variable from the
2158		 * ASTPair.
2159		 *
2160		 * @param rule The name of the rule to generate
2161		 * @param startSymbol true if the rule is a start symbol (i.e., not referenced elsewhere)
2162		*/
2163		public void genRule(RuleSymbol s, boolean startSymbol, int ruleNum, String prefix) {
2164	//		tabs=1;
2165			if ( DEBUG_CODE_GENERATOR ) System.out.println("genRule("+ s.getId() +")");
2166			if ( !s.isDefined() ) {
2167				tool.error("undefined rule: "+ s.getId());
2168				return;
2169			}
2170	
2171			// Generate rule return type, name, arguments
2172			RuleBlock rblk = s.getBlock();
2173			currentRule = rblk;
2174			currentASTResult = s.getId();
2175	
2176			// Save the AST generation state, and set it to that of the rule
2177			boolean savegenAST = genAST;
2178			genAST = genAST && rblk.getAutoGen();
2179	
2180			// boolean oldsaveTest = saveText;
2181			saveText = rblk.getAutoGen();
2182	
2183			// Gen method access and final qualifier
2184	//		print(s.access + " final ");
2185	//		print(s.access + " ");
2186	
2187			// Gen method return type (note lexer return action set at rule creation)
2188			if (rblk.returnAction != null)
2189			{
2190				// Has specified return value
2191				_print(extractTypeOfAction(rblk.returnAction, rblk.getLine()) + " ");
2192			} else {
2193				// No specified return value
2194				_print("void ");
2195			}
2196	
2197			// Gen method name
2198			_print(prefix + s.getId() + "(");
2199	
2200			// Additional rule parameters common to all rules for this grammar
2201			_print(commonExtraParams);
2202			if (commonExtraParams.length() != 0 && rblk.argAction != null ) {
2203				_print(",");
2204			}
2205	
2206			// Gen arguments
2207			if (rblk.argAction != null) 
2208			{
2209				// Has specified arguments
2210				_println("");
2211				tabs++;
2212				println(rblk.argAction);
2213				tabs--;
2214				print(")");
2215			} else {
2216				// No specified arguments
2217				_print(")");
2218			}
2219	
2220			// Gen throws clause and open curly
2221	//		_println(" throws " + exceptionThrown + " {"); //}
2222			_println(" {");
2223			tabs++;
2224	
2225			// Convert return action to variable declaration
2226			if (rblk.returnAction != null)
2227			{
2228				println(rblk.returnAction + ";");
2229			}
2230	
2231			// print out definitions needed by rules for various grammar types
2232			println(commonLocalVars);
2233	
2234	/*
2235		 // if the caller asks for a token, but the input chars should not be
2236		 // added to text buffer, simply create a local buffer.
2237			println("antlr.ANTLRStringBuffer text = this.text;");
2238			println("if ( _createToken && !saveConsumedInput ) {");
2239			println("   text = new antlr.ANTLRStringBuffer();");
2240			println("}");
2241	*/
2242	
2243	/*
2244			if ( grammar.debuggingOutput)
2245				 if (grammar instanceof ParserGrammar)
2246					println("debugger.enterRule(" + ruleNum + ",guessing);");
2247				 else if (grammar instanceof LexerGrammar)
2248					println("debugger.enterScanRule(" + ruleNum + ",guessing);");
2249	*/
2250	
2251			if (grammar.traceRules)
2252				println("Tracer traceInOut(this,\""+ s.getId() +"\");");
2253	//			println("traceIn(\""+ s.getId() +"\");");
2254	
2255			if ( grammar instanceof LexerGrammar ) {
2256				// lexer rule default return value is the rule's token name
2257				// This is a horrible hack to support the built-in EOF lexer rule.
2258				if (s.getId().equals("mEOF")) {
2259					println("_ttype = Token::EOF_TYPE;");
2260				} 
2261				else {
2262	//				println("_ttype = "+ s.getId().substring(1)+"_;");
2263					println("_ttype = "+ s.getId().substring(1)+";");
2264				}
2265				println("int _saveIndex;");		// used for element! (so we can kill text matched for element)
2266	/*
2267				println("boolean old_saveConsumedInput=saveConsumedInput;");
2268				if ( !rblk.getAutoGen() ) {      // turn off "save input" if ! on rule
2269					println("saveConsumedInput=false;");
2270				}
2271	*/
2272			}
2273	
2274			// Generate trace code if desired
2275	//		if ( grammar.debuggingOutput || grammar.traceRules) {
2276	//			println("try { // debugging");
2277	//			tabs++;
2278	//		}
2279	
2280			// Initialize AST variables
2281			if (grammar.buildAST) {
2282				// Parser member used to pass AST returns from rule invocations
2283				println("returnAST = nullAST;");
2284				// Tracks AST construction
2285				println("ASTPair currentAST;"); // = new ASTPair();");
2286				// User-settable return value for rule.
2287				println(labeledElementASTType+" " + s.getId() + "_AST = nullAST;");
2288				if (grammar instanceof TreeWalkerGrammar) {
2289					// "Input" value for rule
2290					println(labeledElementASTType+" " + s.getId() + "_AST_in = _t;");
2291				}
2292			}
2293	
2294			genBlockPreamble(rblk);
2295			println("");
2296	
2297			// Search for an unlabeled exception specification attached to the rule
2298			ExceptionSpec unlabeledUserSpec = rblk.findExceptionSpec("");
2299	
2300			// Generate try block around the entire rule for  error handling
2301			if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler() ) {
2302				println("try {      // for error handling");
2303				tabs++;
2304			}
2305	
2306			// Generate the alternatives
2307			if ( rblk.alternatives.size()==1 ) {
2308				// One alternative -- use simple form
2309				Alternative alt = rblk.getAlternativeAt(0);
2310				String pred = alt.semPred;
2311				if ( pred!=null ) {
2312					genSemPred(pred);
2313				}
2314				if (alt.synPred != null) {
2315					tool.warning(
2316						"Syntactic predicate ignored for single alternative", 
2317						alt.synPred.getLine()
2318					);
2319				}
2320				genAlt(alt, rblk);
2321			}
2322			else {
2323				// Multiple alternatives -- generate complex form
2324				boolean ok = grammar.theLLkAnalyzer.deterministic(rblk);
2325			
2326				CppBlockFinishingInfo howToFinish = genCommonBlock(rblk, false);
2327				genBlockFinish(howToFinish, throwNoViable);
2328			}
2329	
2330			// Generate catch phrase for error handling
2331			if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler() ) {
2332				// Close the try block
2333				tabs--;
2334				println("}");
2335			}
2336	
2337			// Generate user-defined or default catch phrases
2338			if (unlabeledUserSpec != null) {
2339				genErrorHandler(unlabeledUserSpec);
2340			}
2341			else if (rblk.getDefaultErrorHandler()) {
2342				// Generate default catch phrase
2343				println("catch (" + exceptionThrown + "& ex) {");
2344				tabs++;
2345				// Generate code to handle error if not guessing
2346				if (grammar.hasSyntacticPredicate) {
2347					println("if (guessing==0) {");
2348					tabs++;
2349				}
2350				println("reportError(ex.toString());");
2351				if ( !(grammar instanceof TreeWalkerGrammar) ) {
2352					// Generate code to consume until token in k==1 follow set
2353					Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1, rblk.endNode);
2354					String followSetName = getBitsetName(markBitsetForGen(follow.fset));
2355					println("consume();");
2356					println("consumeUntil(" + followSetName + ");");
2357				} else {
2358					// Just consume one token
2359					println("if (_t!=nullAST) {_t = _t->getNextSibling();}");
2360				}
2361				if (grammar.hasSyntacticPredicate) {
2362					tabs--;
2363					// When guessing, rethrow exception
2364					println("} else {");
2365					tabs++;
2366					println("throw ex;");
2367					tabs--;
2368					println("}");
2369				}
2370				// Close catch phrase
2371				tabs--;
2372				println("}");
2373			}
2374	
2375			// Squirrel away the AST "return" value
2376			if (grammar.buildAST) {
2377				println("returnAST = " + s.getId() + "_AST;");
2378			}
2379	
2380			// Set return tree value for tree walkers
2381			if ( grammar instanceof TreeWalkerGrammar ) {
2382				println("_retTree = _t;");
2383			}
2384	
2385			// Generate literals test for lexer rules so marked
2386			if (rblk.getTestLiterals()) {
2387				genLiteralsTest();
2388			}
2389	
2390			// if doing a lexer rule, dump code to create token if necessary
2391			if ( grammar instanceof LexerGrammar ) {
2392				println("if ( _createToken && _token==0 ) {");
2393				println("   _token = makeToken(_ttype);");
2394				println("   _token->setText(text.substr(_begin, text.length()-_begin));");
2395				println("}");
2396				println("_returnToken = _token;");
2397	/*
2398				if ( saveText ) {
2399					println("saveConsumedInput=old_saveConsumedInput;");
2400				}
2401	*/
2402			}
2403	
2404			// Gen the return statement if there is one (lexer has hard-wired return action)
2405			if (rblk.returnAction != null) {
2406				println("return " + extractIdOfAction(rblk.returnAction, rblk.getLine()) + ";");
2407			}
2408	
2409	//		if ( grammar.debuggingOutput || grammar.traceRules) {
2410	//			tabs--;
2411	//			println("} finally { // debugging");
2412	//			tabs++;
2413	//
2414	//			// Generate trace code if desired
2415	//			if ( grammar.debuggingOutput)
2416	//				if (grammar instanceof ParserGrammar) {
2417	//					println("debugger.exitRule();");
2418	//					if (startSymbol)
2419	//						println("doneParsing();");
2420	//				}
2421	//				else if (grammar instanceof LexerGrammar)
2422	//					println("debugger.exitScanRule(_ttype);");
2423	//
2424	//			if ( grammar.traceRules) {
2425	//				println("traceOut(\"" + s.getId() + "\");");
2426	//			}
2427	//
2428	//			tabs--;
2429	//			println("}");
2430	//		}
2431	
2432			tabs--;
2433			println("}"+System.getProperty("line.separator"));
2434			
2435			// Restore the AST generation state
2436			genAST = savegenAST;
2437	
2438			// restore char save state
2439			// saveText = oldsaveTest;
2440		}
2441		public void genRuleHeader(RuleSymbol s, boolean startSymbol) {
2442			tabs=1;
2443			if ( DEBUG_CODE_GENERATOR ) System.out.println("genRuleHeader("+ s.getId() +")");
2444			if ( !s.isDefined() ) {
2445				tool.error("undefined rule: "+ s.getId());
2446				return;
2447			}
2448	
2449			// Generate rule return type, name, arguments
2450			RuleBlock rblk = s.getBlock();
2451			currentRule = rblk;
2452			currentASTResult = s.getId();
2453	
2454			// Save the AST generation state, and set it to that of the rule
2455			boolean savegenAST = genAST;
2456			genAST = genAST && rblk.getAutoGen();
2457	
2458			// boolean oldsaveTest = saveText;
2459			saveText = rblk.getAutoGen();
2460	
2461			// Gen method access
2462			print(s.access + ": ");
2463	
2464			// Gen method return type (note lexer return action set at rule creation)
2465			if (rblk.returnAction != null)
2466			{
2467				// Has specified return value
2468				_print(extractTypeOfAction(rblk.returnAction, rblk.getLine()) + " ");
2469			} else {
2470				// No specified return value
2471				_print("void ");
2472			}
2473	
2474			// Gen method name
2475			_print(s.getId() + "(");
2476	
2477			// Additional rule parameters common to all rules for this grammar
2478			_print(commonExtraParams);
2479			if (commonExtraParams.length() != 0 && rblk.argAction != null ) {
2480				_print(",");
2481			}
2482	
2483			// Gen arguments
2484			if (rblk.argAction != null) 
2485			{
2486				// Has specified arguments
2487				_println("");
2488				tabs++;
2489				println(rblk.argAction);
2490				tabs--;
2491				print(")");
2492			} else {
2493				// No specified arguments
2494				_print(")");
2495			}
2496			_println(";");
2497	
2498			tabs--;
2499			
2500			// Restore the AST generation state
2501			genAST = savegenAST;
2502	
2503			// restore char save state
2504			// saveText = oldsaveTest;
2505		}
2506		private void GenRuleInvocation(RuleRefElement rr) {	
2507			// dump rule name
2508			_print(rr.targetRule + "(");
2509	
2510			// lexers must tell rule if it should set _returnToken
2511			if ( grammar instanceof LexerGrammar ) {
2512				// if labeled, could access Token, so tell rule to create
2513				if ( rr.getLabel() != null ) {
2514					_print("true");
2515				}
2516				else {
2517					_print("false");
2518				}
2519				if (commonExtraArgs.length() != 0 || rr.args!=null ) {
2520					_print(",");
2521				}
2522			}
2523	
2524			// Extra arguments common to all rules for this grammar
2525			_print(commonExtraArgs);
2526			if (commonExtraArgs.length() != 0 && rr.args!=null ) {
2527				_print(",");
2528			}
2529	
2530			// Process arguments to method, if any
2531			RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
2532			if (rr.args != null)
2533			{
2534				// When not guessing, execute user arg action
2535				ActionTransInfo tInfo = new ActionTransInfo();
2536				String args = processActionForTreeSpecifiers(rr.args, 0, currentRule, tInfo);
2537				if ( tInfo.assignToRoot || tInfo.refRuleRoot!=null ) {
2538					tool.error("Arguments of rule reference '" + rr.targetRule + "' cannot set or ref #"+
2539						currentRule.getRuleName()+" on line "+rr.getLine());
2540				}
2541				_print(args);
2542	
2543				// Warn if the rule accepts no arguments
2544				if (rs.block.argAction == null)
2545				{
2546					tool.warning("Rule '" + rr.targetRule + "' accepts no arguments", rr.getLine());
2547				}
2548			} else {
2549				// No warning if rule has parameters, because there may be default
2550				// values for all of the parameters
2551			}
2552			_println(");");
2553			
2554			// move down to the first child while parsing
2555			if ( grammar instanceof TreeWalkerGrammar ) {
2556				println("_t = _retTree;");
2557			}
2558		}
2559		protected void genSemPred(String pred) {
2560			println("if (!("+pred+")) {");
2561			tabs++;
2562			println("throw SemanticException(\"" + charFormatter.escapeString(pred)+"\");");
2563			tabs--;
2564			println("}");
2565		}
2566		protected void genSynPred(SynPredBlock blk, String lookaheadExpr) {
2567			if ( DEBUG_CODE_GENERATOR ) System.out.println("gen=>("+blk+")");
2568	
2569			// Dump synpred result variable
2570			println("bool synPredMatched" + blk.ID + " = false;");
2571			// Gen normal lookahead test
2572			println("if (" + lookaheadExpr + ") {");
2573			tabs++;
2574	
2575			// Save input state
2576			if ( grammar instanceof TreeWalkerGrammar ) {
2577				println("RefAST __t" + blk.ID + " = _t;");
2578			}
2579			else {
2580				println("int _m" + blk.ID + " = mark();");
2581			}
2582	
2583			// Once inside the try, assume synpred works unless exception caught
2584			println("synPredMatched" + blk.ID + " = true;");
2585			println("guessing++;");
2586			syntacticPredLevel++;
2587			println("try {");
2588			tabs++;
2589			gen((AlternativeBlock)blk);		// gen code to test predicate
2590			tabs--;
2591			//println("System.out.println(\"pred "+blk+" succeeded\");");
2592			println("}");
2593			println("catch (" + exceptionThrown + "& pe) {");
2594			tabs++;
2595			println("synPredMatched"+blk.ID+" = false;");
2596			//println("System.out.println(\"pred "+blk+" failed\");");
2597			tabs--;
2598			println("}");
2599	
2600			// Restore input state
2601			if ( grammar instanceof TreeWalkerGrammar ) {
2602				println("_t = __t"+blk.ID+";");
2603			}
2604			else {
2605				println("rewind(_m"+blk.ID+");");
2606			}
2607			println("guessing--;");
2608			syntacticPredLevel--;
2609			tabs--;
2610	
2611			// Close lookahead test
2612			println("}");
2613	
2614			// Test synpred result
2615			println("if ( synPredMatched"+blk.ID+" ) {");
2616		}
2617		/** Generate a static array containing the names of the tokens,
2618		 * indexed by the token type values.  This static array is used
2619		 * to format error messages so that the token identifers or literal
2620		 * strings are displayed instead of the token numbers.
2621		 *
2622		 * If a lexical rule has a paraphrase, use it rather than the
2623		 * token label.
2624		 */
2625		public void genTokenStrings(String prefix) {
2626			// Generate a string for each token.  This creates a static
2627			// array of Strings indexed by token type.
2628	//		println("");
2629			println("const char* " + prefix + "_tokenNames[] = {");
2630			tabs++;
2631	
2632			// Walk the token vocabulary and generate a Vector of strings
2633			// from the tokens.
2634			Vector v = grammar.tokenManager.getVocabulary();
2635			for (int i = 0; i < v.size(); i++)
2636			{
2637				String s = (String)v.elementAt(i);
2638				if (s == null)
2639				{
2640					s = "<"+String.valueOf(i)+">";
2641				}
2642				if ( !s.startsWith("\"") && !s.startsWith("<") ) {
2643					TokenSymbol ts = (TokenSymbol)grammar.tokenManager.getTokenSymbol(s);
2644					if ( ts!=null && ts.getParaphrase()!=null ) {
2645						s = antlr.Tool.stripFrontBack(ts.getParaphrase(), "\"", "\"");
2646					}
2647				}
2648				print(charFormatter.literalString(s));
2649				_println(",");
2650			}
2651			_println("0");
2652	
2653			// Close the string array initailizer
2654			tabs--;
2655			println("};");
2656		}
2657		/** Generate the token types C++ file */
2658		protected void genTokenTypes(TokenManager tm) throws IOException {
2659			// Open the token output header file and set the currentOutput stream
2660			currentOutput = antlr.Tool.openOutputFile(tm.getName() + "TokenTypes.hpp");
2661			//SAS: changed for proper text file io
2662			
2663			tabs = 0;
2664	
2665			// Generate a guard wrapper
2666			println("#ifndef INC_"+tm.getName()+"TokenTypes_hpp_");
2667			println("#define INC_"+tm.getName()+"TokenTypes_hpp_");
2668			println("");
2669			println("#include \"antlr/config.hpp\"");
2670	
2671			// Generate the header common to all C++ files
2672			genHeader();
2673			// Do not use printAction because we assume tabs==0
2674			println(behavior.headerAction);
2675	
2676			// Encapsulate the definitions in an interface.  This can be done
2677			// because they are all constants.
2678			println("enum " + tm.getName() + "TokenTypes {");
2679			tabs++;
2680	
2681	
2682			// Generate a definition for each token type
2683			Vector v = tm.getVocabulary();
2684	
2685			// Do special tokens manually
2686			println("EOF_ = " + Token.EOF_TYPE + ",");
2687			println("NULL_TREE_LOOKAHEAD = " + Token.NULL_TREE_LOOKAHEAD + ",");
2688	
2689			for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) {
2690				String s = (String)v.elementAt(i);
2691				if (s != null) {
2692					if ( s.startsWith("\"") ) {
2693						// a string literal
2694						StringLiteralSymbol sl = (StringLiteralSymbol)grammar.tokenManager.getTokenSymbol(s);
2695						if ( sl==null ) {
2696							antlr.Tool.panic("String literal "+s+" not in symbol table");
2697						}
2698						else if ( sl.label != null ) {
2699	//						println(sl.label + "_ = " + i + ",");
2700							println(sl.label + " = " + i + ",");
2701						}
2702						else {
2703							String mangledName = mangleLiteral(s);
2704							if (mangledName != null) {
2705								// We were able to create a meaningful mangled token name
2706	//							println(mangledName + "_ = " + i + ",");
2707								println(mangledName + " = " + i + ",");
2708								// if no label specified, make the label equal to the mangled name
2709								sl.label = mangledName;
2710							}
2711							else {
2712	//							println("// " + s + "_ = " + i);
2713								println("// " + s + " = " + i);
2714							}
2715						}
2716					}
2717					else if ( !s.startsWith("<") ) {
2718	//					println(s + "_ = " + i + ",");
2719						println(s + " = " + i + ",");
2720					}
2721				}
2722			}
2723	
2724			// Close the interface
2725			tabs--;
2726			println("};");
2727	
2728			// Generate a guard wrapper
2729			println("#endif /*INC_"+tm.getName()+"TokenTypes_hpp_*/");
2730	
2731			// Close the tokens output file
2732			currentOutput.close();
2733			currentOutput = null;
2734			exitIfError();
2735		}
2736		/** Get a string for an expression to generate creation of an AST subtree.
2737		  * @param v A Vector of String, where each element is an expression in the target language yielding an AST node.
2738		  */
2739		public String getASTCreateString(Vector v) {
2740			if (v.size() == 0) {
2741				return "";
2742			}
2743			StringBuffer buf = new StringBuffer();
2744			buf.append("astFactory.make( (new ASTArray(" + v.size() + "))");
2745			for (int i = 0; i < v.size(); i++) {
2746				buf.append("->add(" + v.elementAt(i) + ")");
2747			}
2748			buf.append(")");
2749			return buf.toString();
2750		}
2751		/** Get a string for an expression to generate creating of an AST node
2752		  * @param str The arguments to the AST constructor
2753		  */
2754		public String getASTCreateString(String str) {
2755			return "astFactory.create(" + str + ")";
2756		}
2757		/**Generate a lookahead test expression for an alternate.  This
2758		 * will be a series of tests joined by '&&' and enclosed by '()',
2759		 * the number of such tests being determined by the depth of the lookahead.
2760		 */
2761		protected String getLookaheadTestExpression(Alternative alt, int maxDepth) {
2762			StringBuffer e = new StringBuffer("(");
2763	
2764			int depth = alt.lookaheadDepth;
2765			if ( depth == GrammarAnalyzer.NONDETERMINISTIC ) {
2766				// if the decision is nondeterministic, do the best we can: LL(k)
2767				// any predicates that are around will be generated later.
2768				depth = grammar.maxk;
2769			}
2770	
2771			if ( maxDepth==0 ) {
2772				// empty lookahead can result from alt with sem pred
2773				// that can see end of token.  E.g., A : {pred}? ('a')? ;
2774				return "true";
2775			}
2776	
2777			boolean first = true;
2778			for (int i=1; i<=depth && i<=maxDepth; i++) {
2779				BitSet p = alt.cache[i].fset;
2780				if (!first) {
2781					e.append(") && (");
2782				}
2783				first = false;
2784	
2785				// Syn preds can yield <end-of-syn-pred> (epsilon) lookahead.
2786				// There is no way to predict what that token would be.  Just
2787				// allow anything instead.
2788				if ( alt.cache[i].containsEpsilon() ) {
2789					e.append("true");
2790				}
2791				else {
2792					e.append(getLookaheadTestTerm(i, p));
2793				}
2794			}
2795	
2796			e.append(")");
2797	
2798			return "(" + e.toString() + ")";
2799		}
2800		/**Generate a depth==1 lookahead test expression given the BitSet.
2801		 * This may be one of:
2802		 * 1) a series of 'x==X||' tests
2803		 * 2) a range test using >= && <= where possible,
2804		 * 3) a bitset membership test for complex comparisons
2805		 * @param k The lookahead level
2806		 * @param p The lookahead set for level k
2807		 */
2808		protected String getLookaheadTestTerm(int k, BitSet p) {
2809			// Determine the name of the item to be compared
2810			String ts = lookaheadString(k);
2811	
2812			// Generate a range expression if possible
2813			int[] elems = p.toArray();
2814			if (elementsAreRange(elems)) {
2815				return getRangeExpression(k, elems);
2816			}
2817	
2818			// Generate a bitset membership test if possible
2819			StringBuffer e;
2820			if (p.degree() >= bitsetTestThreshold) {
2821				int bitsetIdx = markBitsetForGen(p);
2822				return getBitsetName(bitsetIdx) + ".member(" + ts + ")";
2823			}
2824	
2825			// Otherwise, generate the long-winded series of "x==X||" tests
2826			e = new StringBuffer();
2827			for (int i = 0; i < elems.length; i++) {
2828				// Get the compared-to item (token or character value)
2829				String cs = getValueString(elems[i]);
2830	
2831				// Generate the element comparison
2832				if ( i>0 ) e.append("||");
2833				e.append(ts);
2834				e.append("==");
2835				e.append(cs);
2836			}
2837			return e.toString();
2838		}
2839		/** Return an expression for testing a contiguous renage of elements
2840		 * @param k The lookahead level
2841		 * @param elems The elements representing the set, usually from BitSet.toArray().
2842		 * @return String containing test expression.
2843		 */
2844		public String getRangeExpression(int k, int[] elems) {
2845			if (!elementsAreRange(elems)) {
2846				tool.panic("getRangeExpression called with non-range");
2847			}
2848			int begin = elems[0];
2849			int end = elems[elems.length-1];
2850			return 
2851				"(" + lookaheadString(k) + " >= " + getValueString(begin) + " && " + 
2852				lookaheadString(k) + " <= " + getValueString(end) + ")";
2853		}
2854		/** getValueString: get a string representation of a token or char value
2855		 * @param value The token or char value
2856		 */
2857		private String getValueString(int value) {
2858			String cs;
2859			if ( grammar instanceof LexerGrammar ) {
2860				cs = charFormatter.literalChar(value);
2861				return cs;
2862			}
2863			else {
2864				String t = (String)grammar.tokenManager.getTokenStringAt(value);
2865				if ( t == null ) {
2866					tool.panic("vocabulary for token type " + value + " is null");
2867				}
2868				if ( t.equals("EOF") ) {
2869					// nasty hack to handle EOF case
2870					cs = "Token::EOF_TYPE";
2871				}
2872				else
2873	
2874				if ( t.startsWith("\"") ) {
2875					cs = mangleLiteral(t);
2876					if (cs == null) {
2877						cs = String.valueOf(value);
2878					}
2879				}
2880				else {
2881					cs = t;
2882				}
2883			}
2884			return cs; // + "_";
2885		}
2886		/**Is the lookahead for this alt empty? */
2887		protected boolean lookaheadIsEmpty(Alternative alt, int maxDepth) {
2888			int depth = alt.lookaheadDepth;
2889			if ( depth == GrammarAnalyzer.NONDETERMINISTIC ) {
2890				depth = grammar.maxk;
2891			}
2892			for (int i=1; i<=depth && i<=maxDepth; i++) {
2893				BitSet p = alt.cache[i].fset;
2894				if (p.degree() != 0) {
2895					return false;
2896				}
2897			}
2898			return true;
2899		}
2900		private String lookaheadString(int k) {
2901			if (grammar instanceof TreeWalkerGrammar) {
2902				return "_t->getType()";
2903			} 
2904			return "LA(" + k + ")";
2905		}
2906		/** Mangle a string literal into a meaningful token name.  This is
2907		  * only possible for literals that are all characters.  The resulting
2908		  * mangled literal name is literalsPrefix with the text of the literal
2909		  * appended.
2910		  * @return A string representing the mangled literal, or null if not possible.
2911		  */
2912		private String mangleLiteral(String s) {
2913			String mangled = antlr.Tool.literalsPrefix;
2914			for (int i = 1; i < s.length()-1; i++) {
2915				if (!Character.isLetter(s.charAt(i)) &&
2916					 s.charAt(i) != '_') {
2917					return null;
2918				}
2919				mangled += s.charAt(i);
2920			}
2921			if ( antlr.Tool.upperCaseMangledLiterals ) {
2922				mangled = mangled.toUpperCase();
2923			}
2924			return mangled;
2925		}
2926		/** Map an identifier to it's corresponding tree-node variable.
2927		  * This is context-sensitive, depending on the rule and alternative
2928		  * being generated
2929		  * @param idParam The identifier name to map
2930		  * @return The mapped id (which may be the same as the input), or null if the mapping is invalid due to duplicates
2931		  */
2932		public String mapTreeId(String idParam, ActionTransInfo transInfo) {
2933			// if not in an action of a rule, nothing to map.
2934			if ( currentRule==null ) return idParam;
2935	
2936			boolean in_var = false;
2937			String id = idParam;
2938			if (grammar instanceof TreeWalkerGrammar) {
2939				// If the id ends with "_in", then map it to the input variable
2940				if (id.length() > 3 && id.lastIndexOf("_in") == id.length()-3) {
2941					// Strip off the "_in"
2942					id = id.substring(0, id.length()-3);
2943					in_var = true;
2944				}
2945			}
2946	
2947			// Check the rule labels.  If id is a label, then the output
2948			// variable is label_AST, and the input variable is plain label.
2949			for (int i = 0; i < currentRule.labeledElements.size(); i++) {
2950				AlternativeElement elt = (AlternativeElement)currentRule.labeledElements.elementAt(i);
2951				if (elt.getLabel().equals(id)) {
2952					return in_var ? id : id + "_AST";
2953				}
2954			}
2955	
2956			// Failing that, check the id-to-variable map for the alternative.
2957			// If the id is in the map, then output variable is the name in the
2958			// map, and input variable is name_in
2959			String s = (String)treeVariableMap.get(id);
2960			if (s != null) {
2961				if (s == NONUNIQUE) {
2962					// There is more than one element with this id
2963					return null;
2964				} else if (s.equals(currentRule.getRuleName())) {
2965					// a recursive call to the enclosing rule is 
2966					// ambiguous with the rule itself.
2967					return null;
2968				} else {
2969					return in_var ? s + "_in" : s;
2970				}
2971			}
2972	
2973			// Failing that, check the rule name itself.  Output variable
2974			// is rule_AST; input variable is rule_AST_in (treeparsers).
2975			if (id.equals(currentRule.getRuleName())) {
2976				String r = in_var ? id + "_AST_in" : id + "_AST";
2977				if ( transInfo!=null ) {
2978					if ( !in_var ) {
2979						transInfo.refRuleRoot = r;
2980					}
2981				}
2982				return r;
2983			} else {
2984				// id does not map to anything -- return itself.
2985				return id;
2986			}
2987		}
2988		/** Given an element and the name of an associated AST variable,
2989		  * create a mapping between the element "name" and the variable name.
2990		  */
2991		private void mapTreeVariable(AlternativeElement e, String name)
2992		{
2993			// For tree elements, defer to the root
2994			if (e instanceof TreeElement) {
2995				mapTreeVariable( ((TreeElement)e).root, name);
2996				return;
2997			}
2998	
2999			// Determine the name of the element, if any, for mapping purposes
3000			String elName = null;
3001	
3002			// Don't map labeled items
3003			if (e.getLabel() == null) {
3004				if (e instanceof TokenRefElement) {
3005					// use the token id
3006					elName = ((TokenRefElement)e).atomText;
3007				}
3008				else if (e instanceof RuleRefElement) {
3009					// use the rule name
3010					elName = ((RuleRefElement)e).targetRule;
3011				}
3012			}
3013			// Add the element to the tree variable map if it has a name
3014			if (elName != null) {
3015				if (treeVariableMap.get(elName) != null) {
3016					// Name is already in the map -- mark it as duplicate
3017					treeVariableMap.remove(elName);
3018					treeVariableMap.put(elName, NONUNIQUE);
3019				}
3020				else {
3021					treeVariableMap.put(elName, name);
3022				}
3023			}
3024		}
3025		private void setupGrammarParameters(Grammar g) {
3026			if (g instanceof ParserGrammar) {
3027				labeledElementASTType = "RefAST";
3028				if ( g.hasOption("ASTLabelType") ) {
3029					Token tsuffix = g.getOption("ASTLabelType");
3030					if ( tsuffix != null ) {
3031						String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
3032						if ( suffix != null ) {
3033							labeledElementASTType = suffix;
3034						}
3035					}
3036				}
3037				labeledElementType = "RefToken ";
3038				labeledElementInit = "RefToken(0)"; //"null";
3039				commonExtraArgs = "";
3040				commonExtraParams = "";
3041				commonLocalVars = "";
3042				lt1Value = "LT(1)";
3043				exceptionThrown = "ParserException";
3044				throwNoViable = "throw NoViableAltException(LT(1));";
3045			}
3046			else if (g instanceof LexerGrammar) {
3047				labeledElementType = "char ";
3048				labeledElementInit = "'\\0'";
3049				commonExtraArgs = "";
3050				commonExtraParams = "bool _createToken";
3051				commonLocalVars = "int _ttype; RefToken _token; int _begin=text.length();";
3052				lt1Value = "LA(1)";
3053				exceptionThrown = "ScannerException";
3054				throwNoViable = "throw ScannerException(std::string(\"no viable alt for char: \")+charName(LA(1)),getLine());";
3055			}
3056			else if (g instanceof TreeWalkerGrammar) {
3057				labeledElementASTType = "RefAST";
3058				labeledElementType = "RefAST";
3059				if ( g.hasOption("ASTLabelType") ) {
3060					Token tsuffix = g.getOption("ASTLabelType");
3061					if ( tsuffix != null ) {
3062						String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
3063						if ( suffix != null ) {
3064							labeledElementASTType = suffix;
3065							labeledElementType = suffix;
3066						}
3067					}
3068				}
3069				if ( !g.hasOption("ASTLabelType") ) {
3070					g.setOption("ASTLabelType", new Token(ANTLRTokenTypes.STRING_LITERAL,"RefAST"));
3071				}
3072				labeledElementInit = "nullAST";
3073				commonExtraArgs = "_t";
3074				commonExtraParams = "RefAST _t";
3075				commonLocalVars = "";
3076				lt1Value = "_t";
3077				exceptionThrown = "ParserException";
3078				throwNoViable = "throw NoViableAltException();";
3079			}
3080			else {
3081				tool.panic("Unknown grammar type");
3082			}
3083		}
3084	}
3085