1 package antlr;
2
3 * <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; import java.io.IOException;
40 import java.io.FileWriter;
41
42
43 public class CppCodeGenerator extends CodeGenerator {
44 protected int syntacticPredLevel = 0;
46
47 protected boolean genAST = false;
49
50 protected boolean saveText = false;
52
53 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 RuleBlock currentRule;
67 String currentASTResult;
69 Hashtable treeVariableMap = new Hashtable();
72 int astVarNumber = 1;
74 protected static final String NONUNIQUE = new String();
76
77
78 * 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
93 public void gen() {
94 try {
96 Enumeration grammarIter = behavior.grammars.elements();
98 while (grammarIter.hasMoreElements()) {
99 Grammar g = (Grammar)grammarIter.nextElement();
100 g.setGrammarAnalyzer(analyzer);
102 g.setCodeGenerator(this);
103 analyzer.setGrammar(g);
104 setupGrammarParameters(g);
106 g.generate();
107 exitIfError();
108 }
109
110 Enumeration tmIter = behavior.tokenManagers.elements();
112 while (tmIter.hasMoreElements()) {
113 TokenManager tm = (TokenManager)tmIter.nextElement();
114 if (!tm.isReadOnly()) {
115 genTokenTypes(tm);
119 genTokenInterchange(tm);
121 }
122 exitIfError();
123 }
124 }
125 catch (IOException e) {
126 System.out.println(e.getMessage());
127 }
128 }
129 * @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 println(tInfo.refRuleRoot + " = currentAST.root;");
152 }
153
154 printAction(actionStr);
156
157 if ( tInfo.assignToRoot ) {
158 println("currentAST.root = "+tInfo.refRuleRoot+";");
160 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 * @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 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 currentASTResult = saveCurrentASTResult;
197 }
198 * @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 * @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 * @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
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 * @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 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 currentASTResult = saveCurrentASTResult;
287 }
288
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 * @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 tool.error("Rule '" + rr.targetRule + "' is not defined", rr.getLine());
308 return;
309 }
310 if (!(rs instanceof RuleSymbol))
311 {
312 tool.error("'" + rr.targetRule + "' does not name a grammar rule", rr.getLine());
314 return;
315 }
316
317 genErrorTryForElement(rr);
318
319 if ( grammar instanceof TreeWalkerGrammar &&
322 rr.getLabel() != null &&
323 syntacticPredLevel == 0 )
324 {
325 println(rr.getLabel() + " = _t==ASTNULL ? nullAST : "+lt1Value+";");
326 }
327
328 if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
330 println("_saveIndex=text.length();");
331 }
332
333 printTabs();
335 if (rr.idAssign != null)
336 {
337 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 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 GenRuleInvocation(rr);
353
354 if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
356 println("text.erase(_saveIndex);");
357 }
358
359 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 println(rr.getLabel() + "_AST = returnAST;");
376 }
377 if (genAST) {
378 switch (rr.getAutoGenType()) {
379 case GrammarElement.AUTO_GEN_NONE:
380 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 ( 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 * @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 if (atom.getLabel()!=null && syntacticPredLevel == 0) {
411 println(atom.getLabel() + " = " + lt1Value + ";");
412 }
413
414 genElementAST(atom);
416
417 boolean oldsaveText = saveText;
419 saveText = saveText && atom.getAutoGenType()==GrammarElement.AUTO_GEN_NONE;
420
421 genMatch(atom);
423
424 saveText = oldsaveText;
425
426 if (grammar instanceof TreeWalkerGrammar) {
428 println("_t = _t->getNextSibling();");
429 }
430 }
431 * @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 genElementAST(r);
442
443 println("matchRange("+r.beginText+","+r.endText+");");
445 genErrorCatchForElement(r);
446 }
447 * @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 if ( atom.getLabel()!=null && syntacticPredLevel == 0) {
458 println(atom.getLabel() + " = " + lt1Value + ";");
459 }
460
461 genElementAST(atom);
463 genMatch(atom);
465 genErrorCatchForElement(atom);
466
467 if (grammar instanceof TreeWalkerGrammar) {
469 println("_t = _t->getNextSibling();");
470 }
471 }
472 public void gen(TreeElement t) {
473 println("RefAST __t" + t.ID + " = _t;");
475
476 if (t.root.getLabel() != null) {
478 println(t.root.getLabel() + " = _t==ASTNULL ? nullAST :_t;");
479 }
480
481 genElementAST(t.root);
483 if (grammar.buildAST) {
484 println("ASTPair __currentAST" + t.ID + " = currentAST;");
486 println("currentAST.root = currentAST.child;");
488 println("currentAST.child = nullAST;");
489 }
490
491 genMatch(t.root);
493 println("_t = _t->getFirstChild();");
495
496 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 println("currentAST = __currentAST" + t.ID + ";");
510 }
511 println("_t = __t" + t.ID + ";");
513 println("_t = _t->getNextSibling();");
515 }
516
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 * @param wc The wildcard element to generate
528 */
529 public void gen(WildcardElement wc) {
530 if (wc.getLabel()!=null && syntacticPredLevel == 0) {
532 println(wc.getLabel() + " = " + lt1Value + ";");
533 }
534
535 genElementAST(wc);
537 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 if (grammar instanceof TreeWalkerGrammar) {
550 println("_t = _t->getNextSibling();");
551 }
552 }
553 * @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 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 currentASTResult = saveCurrentASTResult;
588 }
589 * @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 boolean savegenAST = genAST;
596 genAST = genAST && alt.getAutoGen();
597
598 boolean oldsaveTest = saveText;
599 saveText = saveText && alt.getAutoGen();
600
601 Hashtable saveMap = treeVariableMap;
603 treeVariableMap = new Hashtable();
604
605 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(); elem = elem.next;
615 }
616
617 if ( genAST) {
618 if (blk instanceof RuleBlock) {
619 RuleBlock rblk = (RuleBlock)blk;
621 println(rblk.getRuleName() + "_AST = currentAST.root;");
622 }
623 else if (blk.getLabel() != null) {
624 }
627 }
628
629 if (alt.exceptionSpec != null) {
630 tabs--;
632 println("}");
633 genErrorHandler(alt.exceptionSpec);
634 }
635
636 genAST = savegenAST;
637 saveText = oldsaveTest;
638
639 treeVariableMap = saveMap;
640 }
641 * 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 p.growToInclude(maxVocabulary);
662 println(
664 "const unsigned long " + prefix + getBitsetName(i) + "_data_" + "[] = { " +
665 p.toStringOfHalfWords() +
666 " };"
667 );
668 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 p.growToInclude(maxVocabulary);
686 println("static const unsigned long " + getBitsetName(i) + "_data_" + "[];");
688 println("static const BitSet " + getBitsetName(i) + ";");
690 }
691 }
692 * 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 * 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 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 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 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 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 println(labeledElementType + " " + a.getLabel() + " = " + labeledElementInit + ";");
767 }
768 }
769 }
770 else {
771 println(labeledElementType + " " + a.getLabel() + " = " + labeledElementInit + ";");
774 if (grammar.buildAST) {
776 println(labeledElementASTType+" " + a.getLabel() + "_AST = nullAST;");
777 }
778 }
779 }
780 }
781 }
782
783 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
794 genAST = false; saveText = true;
797 tabs=0;
798
799 genHeader();
801 println(behavior.headerAction);
803
804 String charBufferName = "CharBuffer";
806
807 println(grammar.preambleAction);
809
810 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 String sup=null;
817 if ( grammar.superClass!=null ) {
818 sup = grammar.superClass;
819 }
820 else {
821 sup = grammar.getSuperClass();
822 }
823
824
829 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 tabs--;
842 println("}"+System.getProperty("line.separator"));
843
844 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 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 tabs--;
872 println("}");
873
874 println("bool " + grammar.getClassName() + "::getCaseSensitiveLiterals() const");
876 println("{");
877 tabs++;
878 println("return "+g.caseSensitiveLiterals + ";");
879 tabs--;
880 println("}");
881
882 genNextToken();
887
888 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 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 genBitsets(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size(), grammar.getClassName() + "::");
910
911 println("");
912
913 currentOutput.close();
915 currentOutput = null;
916 }
917 public void genBody(ParserGrammar g) throws IOException {
918 currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".cpp");
920
922 genAST = grammar.buildAST;
923
924 tabs = 0;
925
926 genHeader();
928 println(behavior.headerAction);
930
931 println(grammar.preambleAction);
933
934 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
945 String sup=null;
946 if ( grammar.superClass!=null ) {
947 sup = grammar.superClass;
948 }
949 else {
950 sup = grammar.getSuperClass();
951 }
952
953
956 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 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 tabs--;
981 println("}"+System.getProperty("line.separator"));
982
983 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 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 tabs--;
1010 println("}"+System.getProperty("line.separator"));
1011
1012 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 genTokenStrings(grammar.getClassName() + "::");
1034
1035 genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType(), grammar.getClassName() + "::");
1037
1038 println("");
1040 println("");
1041
1042 currentOutput.close();
1044 currentOutput = null;
1045 }
1046 public void genBody(TreeWalkerGrammar g) throws IOException {
1047 currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".cpp");
1049
1051 genAST = grammar.buildAST;
1052 tabs = 0;
1053
1054 genHeader();
1056 println(behavior.headerAction);
1058
1059 println(grammar.preambleAction);
1061
1062 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
1077 String sup=null;
1079 if ( grammar.superClass!=null ) {
1080 sup = grammar.superClass;
1081 }
1082 else {
1083 sup = grammar.getSuperClass();
1084 }
1085
1086
1091 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 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
1115 genTokenStrings(grammar.getClassName() + "::");
1117
1118 genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType(), grammar.getClassName() + "::");
1120
1121 println("");
1123 println("");
1124
1125 currentOutput.close();
1127 currentOutput = null;
1128 }
1129 * @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 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 * 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 boolean savegenAST = genAST;
1185 genAST = genAST && blk.getAutoGen();
1186
1187 boolean oldsaveTest = saveText;
1188 saveText = saveText && blk.getAutoGen();
1189
1190 if (
1192 blk.not &&
1193 analyzer.subruleCanBeInverted(blk, grammar instanceof LexerGrammar)
1194 ) {
1195 Lookahead p = analyzer.look(1, blk);
1196 if (blk.getLabel() != null && syntacticPredLevel == 0) {
1198 println(blk.getLabel() + " = " + lt1Value + ";");
1199 }
1200
1201 genElementAST(blk);
1203
1204 String astArgs="";
1205 if (grammar instanceof TreeWalkerGrammar) {
1206 astArgs="_t,";
1207 }
1208
1209 println("match(" + astArgs + getBitsetName(markBitsetForGen(p.fset)) + ");");
1211
1212 if (grammar instanceof TreeWalkerGrammar) {
1214 println("_t = _t->getNextSibling();");
1215 }
1216 return finishingInfo;
1217 }
1218
1219 if (blk.getAlternatives().size() == 1) {
1221 Alternative alt = blk.getAlternativeAt(0);
1222 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 genSemPred(alt.semPred);
1234 }
1235 genAlt(alt, blk);
1236 return finishingInfo;
1237 }
1238 }
1239
1240 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 if ( nLL1 >= makeSwitchThreshold) {
1256 String testExpr = lookaheadString(1);
1258 createdLL1Switch = true;
1259 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 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 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 ( 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 int effectiveDepth = alt.lookaheadDepth;
1327 if (effectiveDepth == GrammarAnalyzer.NONDETERMINISTIC) {
1328 effectiveDepth = grammar.maxk;
1330 }
1331 while (
1332 effectiveDepth >= 1 &&
1333 alt.cache[effectiveDepth].containsEpsilon()
1334 )
1335 {
1336 effectiveDepth--;
1337 }
1338 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 if ( nIF==0 ) {
1357 println("{");
1358 }
1359 else {
1360 println("else {");
1361 }
1362 finishingInfo.needAnErrorClause = false;
1363 }
1365 else {
1367 if ( alt.semPred != null ) {
1369 e = "("+e+"&&("+alt.semPred +"))";
1370 }
1371
1372 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 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 genAST = savegenAST;
1415
1416 saveText=oldsaveTest;
1418
1419 if ( createdLL1Switch ) {
1421 tabs--;
1422 finishingInfo.postscript = ps+"}";
1423 finishingInfo.generatedSwitch = true;
1424 finishingInfo.generatedAnIf = nIF>0;
1425
1427 }
1428 else {
1429 finishingInfo.postscript = ps;
1430 finishingInfo.generatedSwitch = false;
1431 finishingInfo.generatedAnIf = nIF>0;
1432 }
1434 return finishingInfo;
1435 }
1436
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 if (el.getLabel() != null) {
1452 elementRef = el.getLabel();
1453 astName = el.getLabel() + "_AST";
1454 } else {
1455 elementRef = lt1Value;
1456 astName = "tmp" + astVarNumber + "_AST";
1458 astVarNumber++;
1459 println(labeledElementASTType+" " + astName + " = nullAST;");
1461 mapTreeVariable(el, astName);
1463 if (grammar instanceof TreeWalkerGrammar) {
1464 println(labeledElementASTType+" " + astName + "_in = nullAST;");
1466 }
1467 }
1468
1469 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 if (grammar instanceof TreeWalkerGrammar) {
1482 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 * 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
1526 private void genErrorHandler(ExceptionSpec ex) {
1527 for (int i = 0; i < ex.handlers.size(); i++)
1529 {
1530 ExceptionHandler handler = (ExceptionHandler)ex.handlers.elementAt(i);
1531 println("catch (" + handler.exceptionTypeAndName.getText() + ") {");
1533 tabs++;
1534 if (grammar.hasSyntacticPredicate) {
1535 println("if (guessing==0) {");
1536 tabs++;
1537 }
1538
1539 printAction(
1541 processActionForTreeSpecifiers(handler.action, 0, currentRule, null)
1542 );
1543
1544 if (grammar.hasSyntacticPredicate) {
1545 tabs--;
1546 println("} else {");
1547 tabs++;
1548 println(
1550 "throw " +
1551 extractIdOfAction(handler.exceptionTypeAndName) +
1552 ";"
1553 );
1554 tabs--;
1555 println("}");
1556 }
1557 tabs--;
1559 println("}");
1560 }
1561 }
1562
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
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
1593 public void genInclude(LexerGrammar g) throws IOException {
1594 currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1595
1597 genAST = false; saveText = true;
1600 tabs=0;
1601
1602 println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1604 println("#define INC_"+grammar.getClassName()+"_hpp_");
1605 println("");
1606 println("#include \"antlr/config.hpp\"");
1607
1608 genHeader();
1610 println(behavior.headerAction);
1612
1613 String charBufferName = "CharBuffer";
1615
1616 println("#include \"antlr/CommonToken.hpp\"");
1618 println("#include \"antlr/"+charBufferName+".hpp\"");
1619 println("#include \"antlr/BitSet.hpp\"");
1620
1622 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 println(grammar.preambleAction);
1635
1636 println("class " + grammar.getClassName() + " : public " + sup);
1638 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
1659 print(
1661 processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1662 );
1663
1664 tabs=0;
1666 println("private:");
1667 tabs=1;
1668 println("void initLiterals();");
1669
1670 tabs=0;
1672 println("public:");
1673 tabs=1;
1674 println("bool getCaseSensitiveLiterals() const;");
1675
1676 tabs=0;
1678 println("public:");
1679 tabs=1;
1680
1681 println(grammar.getClassName() + "(std::istream& in);");
1683
1684 println(grammar.getClassName() + "(" + charBufferName + "& cb);");
1686
1687 println("RefToken nextToken();");
1691
1692 Enumeration ids = grammar.rules.elements();
1694 int ruleNum=0;
1695 while ( ids.hasMoreElements() ) {
1696 RuleSymbol sym = (RuleSymbol) ids.nextElement();
1697 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 tabs=0;
1712 println("private:");
1713 tabs=1;
1714
1715 genBitsetsHeader(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size());
1717
1718 tabs=0;
1719 println("};");
1720 println("");
1721
1722 println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1724
1725 currentOutput.close();
1727 currentOutput = null;
1728 }
1729
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741 public void genInclude(ParserGrammar g) throws IOException {
1742 currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1744
1746 genAST = grammar.buildAST;
1747
1748 tabs = 0;
1749
1750 println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1752 println("#define INC_"+grammar.getClassName()+"_hpp_");
1753 println("");
1754 println("#include \"antlr/config.hpp\"");
1755
1756 genHeader();
1758 println(behavior.headerAction);
1760
1761 println("#include \"antlr/Tokenizer.hpp\"");
1764 println("#include \"antlr/TokenBuffer.hpp\"");
1765 println("#include \"antlr/"+grammar.getSuperClass()+".hpp\"");
1766 println("");
1774
1775
1778 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 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 print(
1800 processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1801 );
1802
1803 println("public:");
1805 tabs=1;
1806
1807 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 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 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 tabs=0;
1843 println("private:");
1844 tabs=1;
1845
1846 println("static const char* _tokenNames[];");
1848
1849 genBitsetsHeader(bitsetsUsed, grammar.tokenManager.maxTokenType());
1851
1852 tabs=0;
1854 println("};");
1855 println("");
1856
1857 println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1859
1860 currentOutput.close();
1862 currentOutput = null;
1863
1864 }
1874 public void genInclude(TreeWalkerGrammar g) throws IOException {
1875 currentOutput = antlr.Tool.openOutputFile(grammar.getClassName() + ".hpp");
1877
1879 genAST = grammar.buildAST;
1880 tabs = 0;
1881
1882 println("#ifndef INC_"+grammar.getClassName()+"_hpp_");
1884 println("#define INC_"+grammar.getClassName()+"_hpp_");
1885 println("");
1886 println("#include \"antlr/config.hpp\"");
1887
1888 genHeader();
1890 println(behavior.headerAction);
1892
1893 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
1906 println(grammar.preambleAction);
1908
1909 print(System.getProperty("line.separator")+
1911 "class " + grammar.getClassName() + " : public "+sup);
1912 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 print(
1926 processActionForTreeSpecifiers(grammar.classMemberAction, 0, currentRule, null)
1927 );
1928
1929 tabs=0;
1931 println("public:");
1932 tabs=1;
1933 println(grammar.getClassName() + "();");
1934
1935 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
1951 tabs=0;
1953 println("private:");
1954 tabs=1;
1955
1956 println("static const char* _tokenNames[];");
1958
1959 genBitsetsHeader(bitsetsUsed, grammar.tokenManager.maxTokenType());
1961
1962 tabs=0;
1964 println("};");
1965 println("");
1966
1967 println("#endif /*INC_"+grammar.getClassName()+"_hpp_*/");
1969
1970 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 String astArgs="";
2003 if (grammar instanceof TreeWalkerGrammar) {
2004 astArgs="_t,";
2005 }
2006
2007 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 if (atom.atomText.equals("EOF")) {
2017 _print("Token::EOF_TYPE");
2019 }
2020 else {
2021 _print(atom.atomText);
2023 }
2027 _println(");");
2028
2029 if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
2030 println("text.erase(_saveIndex);"); }
2032 }
2033 protected void genMatchUsingAtomTokenType(GrammarAtom atom) {
2034 String astArgs="";
2036 if (grammar instanceof TreeWalkerGrammar) {
2037 astArgs="_t,";
2038 }
2039
2040 String mangledName = null;
2042 String s = astArgs + getValueString(atom.tokenType);
2043
2044 println( (atom.not ? "matchNot(" : "match(") + s + ");");
2046 }
2047 * 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 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 RuleBlock nextTokenBlk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");
2072 RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
2074 nextTokenRs.setDefined();
2075 nextTokenRs.setBlock(nextTokenBlk);
2076 nextTokenRs.access = "private";
2077 grammar.define(nextTokenRs);
2078 boolean ok = grammar.theLLkAnalyzer.deterministic(nextTokenBlk);
2080
2081 println(System.getProperty("line.separator")+"RefToken "+grammar.getClassName()+"::nextToken()");
2083 println("{");
2084 tabs++;
2085 println("RefToken _rettoken;");
2086 println("for (;;) {");
2087 tabs++;
2088 println("RefToken _rettoken;");
2090 println("int _ttype = Token::INVALID_TYPE;");
2091 println("resetText();");
2092
2093 println("try { // for error handling");
2095 tabs++;
2096
2097 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 CppBlockFinishingInfo howToFinish = genCommonBlock(nextTokenBlk, false);
2107 genBlockFinish(
2108 howToFinish,
2109 "if (LA(1)!=EOF) " + throwNoViable +
2110 "_returnToken = makeToken(Token::EOF_TYPE);"
2111 );
2112
2113 println("_ttype = _returnToken->getType();");
2117 if ( ((LexerGrammar)grammar).getTestLiterals()) {
2118 genLiteralsTest();
2119 }
2120
2121 println("if ( _ttype!=Token::SKIP ) {");
2123 tabs++;
2124 println("_returnToken->setType(_ttype);");
2125 println("return _returnToken;");
2126 tabs--;
2127 println("}");
2128
2129 tabs--;
2131 println("}");
2132 println("catch (ScannerException& e) {");
2133 tabs++;
2134 println("consume();");
2135 println("reportError(e);");
2136 tabs--;
2137 println("}");
2138
2139 tabs--;
2141 println("}");
2142
2143 tabs--;
2145 println("}"+System.getProperty("line.separator"));
2146 }
2147 * 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 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 RuleBlock rblk = s.getBlock();
2173 currentRule = rblk;
2174 currentASTResult = s.getId();
2175
2176 boolean savegenAST = genAST;
2178 genAST = genAST && rblk.getAutoGen();
2179
2180 saveText = rblk.getAutoGen();
2182
2183
2187 if (rblk.returnAction != null)
2189 {
2190 _print(extractTypeOfAction(rblk.returnAction, rblk.getLine()) + " ");
2192 } else {
2193 _print("void ");
2195 }
2196
2197 _print(prefix + s.getId() + "(");
2199
2200 _print(commonExtraParams);
2202 if (commonExtraParams.length() != 0 && rblk.argAction != null ) {
2203 _print(",");
2204 }
2205
2206 if (rblk.argAction != null)
2208 {
2209 _println("");
2211 tabs++;
2212 println(rblk.argAction);
2213 tabs--;
2214 print(")");
2215 } else {
2216 _print(")");
2218 }
2219
2220 _println(" {");
2223 tabs++;
2224
2225 if (rblk.returnAction != null)
2227 {
2228 println(rblk.returnAction + ";");
2229 }
2230
2231 println(commonLocalVars);
2233
2234 // 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 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
2255 if ( grammar instanceof LexerGrammar ) {
2256 if (s.getId().equals("mEOF")) {
2259 println("_ttype = Token::EOF_TYPE;");
2260 }
2261 else {
2262 println("_ttype = "+ s.getId().substring(1)+";");
2264 }
2265 println("int _saveIndex;"); 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
2280 if (grammar.buildAST) {
2282 println("returnAST = nullAST;");
2284 println("ASTPair currentAST;"); println(labeledElementASTType+" " + s.getId() + "_AST = nullAST;");
2288 if (grammar instanceof TreeWalkerGrammar) {
2289 println(labeledElementASTType+" " + s.getId() + "_AST_in = _t;");
2291 }
2292 }
2293
2294 genBlockPreamble(rblk);
2295 println("");
2296
2297 ExceptionSpec unlabeledUserSpec = rblk.findExceptionSpec("");
2299
2300 if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler() ) {
2302 println("try { // for error handling");
2303 tabs++;
2304 }
2305
2306 if ( rblk.alternatives.size()==1 ) {
2308 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 boolean ok = grammar.theLLkAnalyzer.deterministic(rblk);
2325
2326 CppBlockFinishingInfo howToFinish = genCommonBlock(rblk, false);
2327 genBlockFinish(howToFinish, throwNoViable);
2328 }
2329
2330 if (unlabeledUserSpec != null || rblk.getDefaultErrorHandler() ) {
2332 tabs--;
2334 println("}");
2335 }
2336
2337 if (unlabeledUserSpec != null) {
2339 genErrorHandler(unlabeledUserSpec);
2340 }
2341 else if (rblk.getDefaultErrorHandler()) {
2342 println("catch (" + exceptionThrown + "& ex) {");
2344 tabs++;
2345 if (grammar.hasSyntacticPredicate) {
2347 println("if (guessing==0) {");
2348 tabs++;
2349 }
2350 println("reportError(ex.toString());");
2351 if ( !(grammar instanceof TreeWalkerGrammar) ) {
2352 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 println("if (_t!=nullAST) {_t = _t->getNextSibling();}");
2360 }
2361 if (grammar.hasSyntacticPredicate) {
2362 tabs--;
2363 println("} else {");
2365 tabs++;
2366 println("throw ex;");
2367 tabs--;
2368 println("}");
2369 }
2370 tabs--;
2372 println("}");
2373 }
2374
2375 if (grammar.buildAST) {
2377 println("returnAST = " + s.getId() + "_AST;");
2378 }
2379
2380 if ( grammar instanceof TreeWalkerGrammar ) {
2382 println("_retTree = _t;");
2383 }
2384
2385 if (rblk.getTestLiterals()) {
2387 genLiteralsTest();
2388 }
2389
2390 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 if ( saveText ) {
2399 println("saveConsumedInput=old_saveConsumedInput;");
2400 }
2401 */
2402 }
2403
2404 if (rblk.returnAction != null) {
2406 println("return " + extractIdOfAction(rblk.returnAction, rblk.getLine()) + ";");
2407 }
2408
2409
2432 tabs--;
2433 println("}"+System.getProperty("line.separator"));
2434
2435 genAST = savegenAST;
2437
2438 }
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 RuleBlock rblk = s.getBlock();
2451 currentRule = rblk;
2452 currentASTResult = s.getId();
2453
2454 boolean savegenAST = genAST;
2456 genAST = genAST && rblk.getAutoGen();
2457
2458 saveText = rblk.getAutoGen();
2460
2461 print(s.access + ": ");
2463
2464 if (rblk.returnAction != null)
2466 {
2467 _print(extractTypeOfAction(rblk.returnAction, rblk.getLine()) + " ");
2469 } else {
2470 _print("void ");
2472 }
2473
2474 _print(s.getId() + "(");
2476
2477 _print(commonExtraParams);
2479 if (commonExtraParams.length() != 0 && rblk.argAction != null ) {
2480 _print(",");
2481 }
2482
2483 if (rblk.argAction != null)
2485 {
2486 _println("");
2488 tabs++;
2489 println(rblk.argAction);
2490 tabs--;
2491 print(")");
2492 } else {
2493 _print(")");
2495 }
2496 _println(";");
2497
2498 tabs--;
2499
2500 genAST = savegenAST;
2502
2503 }
2506 private void GenRuleInvocation(RuleRefElement rr) {
2507 _print(rr.targetRule + "(");
2509
2510 if ( grammar instanceof LexerGrammar ) {
2512 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 _print(commonExtraArgs);
2526 if (commonExtraArgs.length() != 0 && rr.args!=null ) {
2527 _print(",");
2528 }
2529
2530 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
2532 if (rr.args != null)
2533 {
2534 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 if (rs.block.argAction == null)
2545 {
2546 tool.warning("Rule '" + rr.targetRule + "' accepts no arguments", rr.getLine());
2547 }
2548 } else {
2549 }
2552 _println(");");
2553
2554 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 println("bool synPredMatched" + blk.ID + " = false;");
2571 println("if (" + lookaheadExpr + ") {");
2573 tabs++;
2574
2575 if ( grammar instanceof TreeWalkerGrammar ) {
2577 println("RefAST __t" + blk.ID + " = _t;");
2578 }
2579 else {
2580 println("int _m" + blk.ID + " = mark();");
2581 }
2582
2583 println("synPredMatched" + blk.ID + " = true;");
2585 println("guessing++;");
2586 syntacticPredLevel++;
2587 println("try {");
2588 tabs++;
2589 gen((AlternativeBlock)blk); tabs--;
2591 println("}");
2593 println("catch (" + exceptionThrown + "& pe) {");
2594 tabs++;
2595 println("synPredMatched"+blk.ID+" = false;");
2596 tabs--;
2598 println("}");
2599
2600 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 println("}");
2613
2614 println("if ( synPredMatched"+blk.ID+" ) {");
2616 }
2617 * 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 println("const char* " + prefix + "_tokenNames[] = {");
2630 tabs++;
2631
2632 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 tabs--;
2655 println("};");
2656 }
2657
2658 protected void genTokenTypes(TokenManager tm) throws IOException {
2659 currentOutput = antlr.Tool.openOutputFile(tm.getName() + "TokenTypes.hpp");
2661
2663 tabs = 0;
2664
2665 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 genHeader();
2673 println(behavior.headerAction);
2675
2676 println("enum " + tm.getName() + "TokenTypes {");
2679 tabs++;
2680
2681
2682 Vector v = tm.getVocabulary();
2684
2685 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 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 + ",");
2701 }
2702 else {
2703 String mangledName = mangleLiteral(s);
2704 if (mangledName != null) {
2705 println(mangledName + " = " + i + ",");
2708 sl.label = mangledName;
2710 }
2711 else {
2712 println("// " + s + " = " + i);
2714 }
2715 }
2716 }
2717 else if ( !s.startsWith("<") ) {
2718 println(s + " = " + i + ",");
2720 }
2721 }
2722 }
2723
2724 tabs--;
2726 println("};");
2727
2728 println("#endif /*INC_"+tm.getName()+"TokenTypes_hpp_*/");
2730
2731 currentOutput.close();
2733 currentOutput = null;
2734 exitIfError();
2735 }
2736 * @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 * @param str The arguments to the AST constructor
2753 */
2754 public String getASTCreateString(String str) {
2755 return "astFactory.create(" + str + ")";
2756 }
2757 * 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 depth = grammar.maxk;
2769 }
2770
2771 if ( maxDepth==0 ) {
2772 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 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 * 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 String ts = lookaheadString(k);
2811
2812 int[] elems = p.toArray();
2814 if (elementsAreRange(elems)) {
2815 return getRangeExpression(k, elems);
2816 }
2817
2818 StringBuffer e;
2820 if (p.degree() >= bitsetTestThreshold) {
2821 int bitsetIdx = markBitsetForGen(p);
2822 return getBitsetName(bitsetIdx) + ".member(" + ts + ")";
2823 }
2824
2825 e = new StringBuffer();
2827 for (int i = 0; i < elems.length; i++) {
2828 String cs = getValueString(elems[i]);
2830
2831 if ( i>0 ) e.append("||");
2833 e.append(ts);
2834 e.append("==");
2835 e.append(cs);
2836 }
2837 return e.toString();
2838 }
2839 * @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 * @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 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; }
2886
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 * 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 * 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 ( currentRule==null ) return idParam;
2935
2936 boolean in_var = false;
2937 String id = idParam;
2938 if (grammar instanceof TreeWalkerGrammar) {
2939 if (id.length() > 3 && id.lastIndexOf("_in") == id.length()-3) {
2941 id = id.substring(0, id.length()-3);
2943 in_var = true;
2944 }
2945 }
2946
2947 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 String s = (String)treeVariableMap.get(id);
2960 if (s != null) {
2961 if (s == NONUNIQUE) {
2962 return null;
2964 } else if (s.equals(currentRule.getRuleName())) {
2965 return null;
2968 } else {
2969 return in_var ? s + "_in" : s;
2970 }
2971 }
2972
2973 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 return id;
2986 }
2987 }
2988 * create a mapping between the element "name" and the variable name.
2990 */
2991 private void mapTreeVariable(AlternativeElement e, String name)
2992 {
2993 if (e instanceof TreeElement) {
2995 mapTreeVariable( ((TreeElement)e).root, name);
2996 return;
2997 }
2998
2999 String elName = null;
3001
3002 if (e.getLabel() == null) {
3004 if (e instanceof TokenRefElement) {
3005 elName = ((TokenRefElement)e).atomText;
3007 }
3008 else if (e instanceof RuleRefElement) {
3009 elName = ((RuleRefElement)e).targetRule;
3011 }
3012 }
3013 if (elName != null) {
3015 if (treeVariableMap.get(elName) != null) {
3016 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)"; 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