KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > persistence > antlr > DiagnosticCodeGenerator


1 package persistence.antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/license.html
6  *
7  */

8
9 import java.util.Enumeration JavaDoc;
10
11 import persistence.antlr.collections.impl.BitSet;
12 import persistence.antlr.collections.impl.Vector;
13
14 import java.io.PrintWriter JavaDoc; //SAS: changed for proper text file io
15
import java.io.IOException JavaDoc;
16 import java.io.FileWriter JavaDoc;
17
18 /**Generate MyParser.txt, MyLexer.txt and MyParserTokenTypes.txt */
19 public class DiagnosticCodeGenerator extends CodeGenerator {
20     /** non-zero if inside syntactic predicate generation */
21     protected int syntacticPredLevel = 0;
22
23     /** true during lexer generation, false during parser generation */
24     protected boolean doingLexRules = false;
25
26     /** Create a Diagnostic code-generator using the given Grammar
27      * The caller must still call setTool, setBehavior, and setAnalyzer
28      * before generating code.
29      */

30     public DiagnosticCodeGenerator() {
31         super();
32         charFormatter = new JavaCharFormatter();
33     }
34
35     /**Generate the parser, lexer, and token types documentation */
36     public void gen() {
37
38         // Do the code generation
39
try {
40             // Loop over all grammars
41
Enumeration JavaDoc grammarIter = behavior.grammars.elements();
42             while (grammarIter.hasMoreElements()) {
43                 Grammar g = (Grammar)grammarIter.nextElement();
44
45                 // Connect all the components to each other
46
g.setGrammarAnalyzer(analyzer);
47                 g.setCodeGenerator(this);
48                 analyzer.setGrammar(g);
49
50                 // To get right overloading behavior across hetrogeneous grammars
51
g.generate();
52
53                 if (antlrTool.hasError()) {
54                     antlrTool.panic("Exiting due to errors.");
55                 }
56
57             }
58
59             // Loop over all token managers (some of which are lexers)
60
Enumeration JavaDoc tmIter = behavior.tokenManagers.elements();
61             while (tmIter.hasMoreElements()) {
62                 TokenManager tm = (TokenManager)tmIter.nextElement();
63                 if (!tm.isReadOnly()) {
64                     // Write the token manager tokens as Java
65
genTokenTypes(tm);
66                 }
67             }
68         }
69         catch (IOException JavaDoc e) {
70             antlrTool.reportException(e, null);
71         }
72     }
73
74     /** Generate code for the given grammar element.
75      * @param blk The {...} action to generate
76      */

77     public void gen(ActionElement action) {
78         if (action.isSemPred) {
79             // handled elsewhere
80
}
81         else {
82             print("ACTION: ");
83             _printAction(action.actionText);
84         }
85     }
86
87     /** Generate code for the given grammar element.
88      * @param blk The "x|y|z|..." block to generate
89      */

90     public void gen(AlternativeBlock blk) {
91         println("Start of alternative block.");
92         tabs++;
93         genBlockPreamble(blk);
94
95         boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
96         if (!ok) {
97             println("Warning: This alternative block is non-deterministic");
98         }
99         genCommonBlock(blk);
100         tabs--;
101     }
102
103     /** Generate code for the given grammar element.
104      * @param blk The block-end element to generate. Block-end
105      * elements are synthesized by the grammar parser to represent
106      * the end of a block.
107      */

108     public void gen(BlockEndElement end) {
109         // no-op
110
}
111
112     /** Generate code for the given grammar element.
113      * @param blk The character literal reference to generate
114      */

115     public void gen(CharLiteralElement atom) {
116         print("Match character ");
117         if (atom.not) {
118             _print("NOT ");
119         }
120         _print(atom.atomText);
121         if (atom.label != null) {
122             _print(", label=" + atom.label);
123         }
124         _println("");
125     }
126
127     /** Generate code for the given grammar element.
128      * @param blk The character-range reference to generate
129      */

130     public void gen(CharRangeElement r) {
131         print("Match character range: " + r.beginText + ".." + r.endText);
132         if (r.label != null) {
133             _print(", label = " + r.label);
134         }
135         _println("");
136     }
137
138     /** Generate the lexer TXT file */
139     public void gen(LexerGrammar g) throws IOException JavaDoc {
140         setGrammar(g);
141         antlrTool.reportProgress("Generating " + grammar.getClassName() + TokenTypesFileExt);
142         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt);
143         //SAS: changed for proper text file io
144

145         tabs = 0;
146         doingLexRules = true;
147
148         // Generate header common to all TXT output files
149
genHeader();
150
151         // Output the user-defined lexer premamble
152
println("");
153         println("*** Lexer Preamble Action.");
154         println("This action will appear before the declaration of your lexer class:");
155         tabs++;
156         println(grammar.preambleAction.getText());
157         tabs--;
158         println("*** End of Lexer Preamble Action");
159
160         // Generate lexer class definition
161
println("");
162         println("*** Your lexer class is called '" + grammar.getClassName() + "' and is a subclass of '" + grammar.getSuperClass() + "'.");
163
164         // Generate user-defined parser class members
165
println("");
166         println("*** User-defined lexer class members:");
167         println("These are the member declarations that you defined for your class:");
168         tabs++;
169         printAction(grammar.classMemberAction.getText());
170         tabs--;
171         println("*** End of user-defined lexer class members");
172
173         // Generate string literals
174
println("");
175         println("*** String literals used in the parser");
176         println("The following string literals were used in the parser.");
177         println("An actual code generator would arrange to place these literals");
178         println("into a table in the generated lexer, so that actions in the");
179         println("generated lexer could match token text against the literals.");
180         println("String literals used in the lexer are not listed here, as they");
181         println("are incorporated into the mainstream lexer processing.");
182         tabs++;
183         // Enumerate all of the symbols and look for string literal symbols
184
Enumeration JavaDoc ids = grammar.getSymbols();
185         while (ids.hasMoreElements()) {
186             GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
187             // Only processing string literals -- reject other symbol entries
188
if (sym instanceof StringLiteralSymbol) {
189                 StringLiteralSymbol s = (StringLiteralSymbol)sym;
190                 println(s.getId() + " = " + s.getTokenType());
191             }
192         }
193         tabs--;
194         println("*** End of string literals used by the parser");
195
196         // Generate nextToken() rule.
197
// nextToken() is a synthetic lexer rule that is the implicit OR of all
198
// user-defined lexer rules.
199
genNextToken();
200
201         // Generate code for each rule in the lexer
202
println("");
203         println("*** User-defined Lexer rules:");
204         tabs++;
205
206         ids = grammar.rules.elements();
207         while (ids.hasMoreElements()) {
208             RuleSymbol rs = (RuleSymbol)ids.nextElement();
209             if (!rs.id.equals("mnextToken")) {
210                 genRule(rs);
211             }
212         }
213
214         tabs--;
215         println("");
216         println("*** End User-defined Lexer rules:");
217
218         // Close the lexer output file
219
currentOutput.close();
220         currentOutput = null;
221         doingLexRules = false;
222     }
223
224     /** Generate code for the given grammar element.
225      * @param blk The (...)+ block to generate
226      */

227     public void gen(OneOrMoreBlock blk) {
228         println("Start ONE-OR-MORE (...)+ block:");
229         tabs++;
230         genBlockPreamble(blk);
231         boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
232         if (!ok) {
233             println("Warning: This one-or-more block is non-deterministic");
234         }
235         genCommonBlock(blk);
236         tabs--;
237         println("End ONE-OR-MORE block.");
238     }
239
240     /** Generate the parser TXT file */
241     public void gen(ParserGrammar g) throws IOException JavaDoc {
242         setGrammar(g);
243         // Open the output stream for the parser and set the currentOutput
244
antlrTool.reportProgress("Generating " + grammar.getClassName() + TokenTypesFileExt);
245         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt);
246         //SAS: changed for proper text file io
247

248         tabs = 0;
249
250         // Generate the header common to all output files.
251
genHeader();
252
253         // Output the user-defined parser premamble
254
println("");
255         println("*** Parser Preamble Action.");
256         println("This action will appear before the declaration of your parser class:");
257         tabs++;
258         println(grammar.preambleAction.getText());
259         tabs--;
260         println("*** End of Parser Preamble Action");
261
262         // Generate parser class definition
263
println("");
264         println("*** Your parser class is called '" + grammar.getClassName() + "' and is a subclass of '" + grammar.getSuperClass() + "'.");
265
266         // Generate user-defined parser class members
267
println("");
268         println("*** User-defined parser class members:");
269         println("These are the member declarations that you defined for your class:");
270         tabs++;
271         printAction(grammar.classMemberAction.getText());
272         tabs--;
273         println("*** End of user-defined parser class members");
274
275         // Generate code for each rule in the grammar
276
println("");
277         println("*** Parser rules:");
278         tabs++;
279
280         // Enumerate the parser rules
281
Enumeration JavaDoc rules = grammar.rules.elements();
282         while (rules.hasMoreElements()) {
283             println("");
284             // Get the rules from the list and downcast it to proper type
285
GrammarSymbol sym = (GrammarSymbol)rules.nextElement();
286             // Only process parser rules
287
if (sym instanceof RuleSymbol) {
288                 genRule((RuleSymbol)sym);
289             }
290         }
291         tabs--;
292         println("");
293         println("*** End of parser rules");
294
295         println("");
296         println("*** End of parser");
297
298         // Close the parser output stream
299
currentOutput.close();
300         currentOutput = null;
301     }
302
303     /** Generate code for the given grammar element.
304      * @param blk The rule-reference to generate
305      */

306     public void gen(RuleRefElement rr) {
307         RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
308
309         // Generate the actual rule description
310
print("Rule Reference: " + rr.targetRule);
311         if (rr.idAssign != null) {
312             _print(", assigned to '" + rr.idAssign + "'");
313         }
314         if (rr.args != null) {
315             _print(", arguments = " + rr.args);
316         }
317         _println("");
318
319         // Perform diagnostics
320
if (rs == null || !rs.isDefined()) {
321             println("Rule '" + rr.targetRule + "' is referenced, but that rule is not defined.");
322             println("\tPerhaps the rule is misspelled, or you forgot to define it.");
323             return;
324         }
325         if (!(rs instanceof RuleSymbol)) {
326             // Should this ever happen??
327
println("Rule '" + rr.targetRule + "' is referenced, but that is not a grammar rule.");
328             return;
329         }
330         if (rr.idAssign != null) {
331             // Warn if the rule has no return type
332
if (rs.block.returnAction == null) {
333                 println("Error: You assigned from Rule '" + rr.targetRule + "', but that rule has no return type.");
334             }
335         }
336         else {
337             // Warn about return value if any, but not inside syntactic predicate
338
if (!(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null) {
339                 println("Warning: Rule '" + rr.targetRule + "' returns a value");
340             }
341         }
342         if (rr.args != null && rs.block.argAction == null) {
343             println("Error: Rule '" + rr.targetRule + "' accepts no arguments.");
344         }
345     }
346
347     /** Generate code for the given grammar element.
348      * @param blk The string-literal reference to generate
349      */

350     public void gen(StringLiteralElement atom) {
351         print("Match string literal ");
352         _print(atom.atomText);
353         if (atom.label != null) {
354             _print(", label=" + atom.label);
355         }
356         _println("");
357     }
358
359     /** Generate code for the given grammar element.
360      * @param blk The token-range reference to generate
361      */

362     public void gen(TokenRangeElement r) {
363         print("Match token range: " + r.beginText + ".." + r.endText);
364         if (r.label != null) {
365             _print(", label = " + r.label);
366         }
367         _println("");
368     }
369
370     /** Generate code for the given grammar element.
371      * @param blk The token-reference to generate
372      */

373     public void gen(TokenRefElement atom) {
374         print("Match token ");
375         if (atom.not) {
376             _print("NOT ");
377         }
378         _print(atom.atomText);
379         if (atom.label != null) {
380             _print(", label=" + atom.label);
381         }
382         _println("");
383     }
384
385     public void gen(TreeElement t) {
386         print("Tree reference: " + t);
387     }
388
389     /** Generate the tree-walker TXT file */
390     public void gen(TreeWalkerGrammar g) throws IOException JavaDoc {
391         setGrammar(g);
392         // Open the output stream for the parser and set the currentOutput
393
antlrTool.reportProgress("Generating " + grammar.getClassName() + TokenTypesFileExt);
394         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt);
395         //SAS: changed for proper text file io
396

397         tabs = 0;
398
399         // Generate the header common to all output files.
400
genHeader();
401
402         // Output the user-defined parser premamble
403
println("");
404         println("*** Tree-walker Preamble Action.");
405         println("This action will appear before the declaration of your tree-walker class:");
406         tabs++;
407         println(grammar.preambleAction.getText());
408         tabs--;
409         println("*** End of tree-walker Preamble Action");
410
411         // Generate tree-walker class definition
412
println("");
413         println("*** Your tree-walker class is called '" + grammar.getClassName() + "' and is a subclass of '" + grammar.getSuperClass() + "'.");
414
415         // Generate user-defined tree-walker class members
416
println("");
417         println("*** User-defined tree-walker class members:");
418         println("These are the member declarations that you defined for your class:");
419         tabs++;
420         printAction(grammar.classMemberAction.getText());
421         tabs--;
422         println("*** End of user-defined tree-walker class members");
423
424         // Generate code for each rule in the grammar
425
println("");
426         println("*** tree-walker rules:");
427         tabs++;
428
429         // Enumerate the tree-walker rules
430
Enumeration JavaDoc rules = grammar.rules.elements();
431         while (rules.hasMoreElements()) {
432             println("");
433             // Get the rules from the list and downcast it to proper type
434
GrammarSymbol sym = (GrammarSymbol)rules.nextElement();
435             // Only process tree-walker rules
436
if (sym instanceof RuleSymbol) {
437                 genRule((RuleSymbol)sym);
438             }
439         }
440         tabs--;
441         println("");
442         println("*** End of tree-walker rules");
443
444         println("");
445         println("*** End of tree-walker");
446
447         // Close the tree-walker output stream
448
currentOutput.close();
449         currentOutput = null;
450     }
451
452     /** Generate a wildcard element */
453     public void gen(WildcardElement wc) {
454         print("Match wildcard");
455         if (wc.getLabel() != null) {
456             _print(", label = " + wc.getLabel());
457         }
458         _println("");
459     }
460
461     /** Generate code for the given grammar element.
462      * @param blk The (...)* block to generate
463      */

464     public void gen(ZeroOrMoreBlock blk) {
465         println("Start ZERO-OR-MORE (...)+ block:");
466         tabs++;
467         genBlockPreamble(blk);
468         boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
469         if (!ok) {
470             println("Warning: This zero-or-more block is non-deterministic");
471         }
472         genCommonBlock(blk);
473         tabs--;
474         println("End ZERO-OR-MORE block.");
475     }
476
477     protected void genAlt(Alternative alt) {
478         for (
479             AlternativeElement elem = alt.head;
480             !(elem instanceof BlockEndElement);
481             elem = elem.next
482             ) {
483             elem.generate();
484         }
485         if (alt.getTreeSpecifier() != null) {
486             println("AST will be built as: " + alt.getTreeSpecifier().getText());
487         }
488     }
489
490     /** Generate the header for a block, which may be a RuleBlock or a
491      * plain AlternativeBLock. This generates any variable declarations,
492      * init-actions, and syntactic-predicate-testing variables.
493      * @blk The block for which the preamble is to be generated.
494      */

495     protected void genBlockPreamble(AlternativeBlock blk) {
496         // dump out init action
497
if (blk.initAction != null) {
498             printAction("Init action: " + blk.initAction);
499         }
500     }
501
502     /**Generate common code for a block of alternatives; return a postscript
503      * that needs to be generated at the end of the block. Other routines
504      * may append else-clauses and such for error checking before the postfix
505      * is generated.
506      */

507     public void genCommonBlock(AlternativeBlock blk) {
508         boolean singleAlt = (blk.alternatives.size() == 1);
509
510         println("Start of an alternative block.");
511         tabs++;
512         println("The lookahead set for this block is:");
513         tabs++;
514         genLookaheadSetForBlock(blk);
515         tabs--;
516
517         if (singleAlt) {
518             println("This block has a single alternative");
519             if (blk.getAlternativeAt(0).synPred != null) {
520                 // Generate a warning if there is one alt and it has a synPred
521
println("Warning: you specified a syntactic predicate for this alternative,");
522                 println("and it is the only alternative of a block and will be ignored.");
523             }
524         }
525         else {
526             println("This block has multiple alternatives:");
527             tabs++;
528         }
529
530         for (int i = 0; i < blk.alternatives.size(); i++) {
531             Alternative alt = blk.getAlternativeAt(i);
532             AlternativeElement elem = alt.head;
533
534             // Print lookahead set for alternate
535
println("");
536             if (i != 0) {
537                 print("Otherwise, ");
538             }
539             else {
540                 print("");
541             }
542             _println("Alternate(" + (i + 1) + ") will be taken IF:");
543             println("The lookahead set: ");
544             tabs++;
545             genLookaheadSetForAlt(alt);
546             tabs--;
547             if (alt.semPred != null || alt.synPred != null) {
548                 print("is matched, AND ");
549             }
550             else {
551                 println("is matched.");
552             }
553
554             // Dump semantic predicates
555
if (alt.semPred != null) {
556                 _println("the semantic predicate:");
557                 tabs++;
558                 println(alt.semPred);
559                 if (alt.synPred != null) {
560                     print("is true, AND ");
561                 }
562                 else {
563                     println("is true.");
564                 }
565             }
566
567             // Dump syntactic predicate
568
if (alt.synPred != null) {
569                 _println("the syntactic predicate:");
570                 tabs++;
571                 genSynPred(alt.synPred);
572                 tabs--;
573                 println("is matched.");
574             }
575
576             // Dump the alternative
577
genAlt(alt);
578         }
579         println("");
580         println("OTHERWISE, a NoViableAlt exception will be thrown");
581         println("");
582
583         if (!singleAlt) {
584             tabs--;
585             println("End of alternatives");
586         }
587         tabs--;
588         println("End of alternative block.");
589     }
590
591     /** Generate a textual representation of the follow set
592      * for a block.
593      * @param blk The rule block of interest
594      */

595     public void genFollowSetForRuleBlock(RuleBlock blk) {
596         Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1, blk.endNode);
597         printSet(grammar.maxk, 1, follow);
598     }
599
600     /** Generate a header that is common to all TXT files */
601     protected void genHeader() {
602         println("ANTLR-generated file resulting from grammar " + antlrTool.grammarFile);
603         println("Diagnostic output");
604         println("");
605         println("Terence Parr, MageLang Institute");
606         println("with John Lilley, Empathy Software");
607         println("ANTLR Version " + antlrTool.version + "; 1996,1997");
608         println("");
609         println("*** Header Action.");
610         println("This action will appear at the top of all generated files.");
611         tabs++;
612         printAction(behavior.getHeaderAction(""));
613         tabs--;
614         println("*** End of Header Action");
615         println("");
616     }
617
618     /**Generate the lookahead set for an alternate. */
619     protected void genLookaheadSetForAlt(Alternative alt) {
620         if (doingLexRules && alt.cache[1].containsEpsilon()) {
621             println("MATCHES ALL");
622             return;
623         }
624         int depth = alt.lookaheadDepth;
625         if (depth == GrammarAnalyzer.NONDETERMINISTIC) {
626             // if the decision is nondeterministic, do the best we can: LL(k)
627
// any predicates that are around will be generated later.
628
depth = grammar.maxk;
629         }
630         for (int i = 1; i <= depth; i++) {
631             Lookahead lookahead = alt.cache[i];
632             printSet(depth, i, lookahead);
633         }
634     }
635
636     /** Generate a textual representation of the lookahead set
637      * for a block.
638      * @param blk The block of interest
639      */

640     public void genLookaheadSetForBlock(AlternativeBlock blk) {
641         // Find the maximal lookahead depth over all alternatives
642
int depth = 0;
643         for (int i = 0; i < blk.alternatives.size(); i++) {
644             Alternative alt = blk.getAlternativeAt(i);
645             if (alt.lookaheadDepth == GrammarAnalyzer.NONDETERMINISTIC) {
646                 depth = grammar.maxk;
647                 break;
648             }
649             else if (depth < alt.lookaheadDepth) {
650                 depth = alt.lookaheadDepth;
651             }
652         }
653
654         for (int i = 1; i <= depth; i++) {
655             Lookahead lookahead = grammar.theLLkAnalyzer.look(i, blk);
656             printSet(depth, i, lookahead);
657         }
658     }
659
660     /** Generate the nextToken rule.
661      * nextToken is a synthetic lexer rule that is the implicit OR of all
662      * user-defined lexer rules.
663      */

664     public void genNextToken() {
665         println("");
666         println("*** Lexer nextToken rule:");
667         println("The lexer nextToken rule is synthesized from all of the user-defined");
668         println("lexer rules. It logically consists of one big alternative block with");
669         println("each user-defined rule being an alternative.");
670         println("");
671
672         // Create the synthesized rule block for nextToken consisting
673
// of an alternate block containing all the user-defined lexer rules.
674
RuleBlock blk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");
675
676         // Define the nextToken rule symbol
677
RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
678         nextTokenRs.setDefined();
679         nextTokenRs.setBlock(blk);
680         nextTokenRs.access = "private";
681         grammar.define(nextTokenRs);
682
683         // Analyze the synthesized block
684
if (!grammar.theLLkAnalyzer.deterministic(blk)) {
685             println("The grammar analyzer has determined that the synthesized");
686             println("nextToken rule is non-deterministic (i.e., it has ambiguities)");
687             println("This means that there is some overlap of the character");
688             println("lookahead for two or more of your lexer rules.");
689         }
690
691         genCommonBlock(blk);
692
693         println("*** End of nextToken lexer rule.");
694     }
695
696     /** Generate code for a named rule block
697      * @param s The RuleSymbol describing the rule to generate
698      */

699     public void genRule(RuleSymbol s) {
700         println("");
701         String JavaDoc ruleType = (doingLexRules ? "Lexer" : "Parser");
702         println("*** " + ruleType + " Rule: " + s.getId());
703         if (!s.isDefined()) {
704             println("This rule is undefined.");
705             println("This means that the rule was referenced somewhere in the grammar,");
706             println("but a definition for the rule was not encountered.");
707             println("It is also possible that syntax errors during the parse of");
708             println("your grammar file prevented correct processing of the rule.");
709             println("*** End " + ruleType + " Rule: " + s.getId());
710             return;
711         }
712         tabs++;
713
714         if (s.access.length() != 0) {
715             println("Access: " + s.access);
716         }
717
718         // Get rule return type and arguments
719
RuleBlock rblk = s.getBlock();
720
721         // Gen method return value(s)
722
if (rblk.returnAction != null) {
723             println("Return value(s): " + rblk.returnAction);
724             if (doingLexRules) {
725                 println("Error: you specified return value(s) for a lexical rule.");
726                 println("\tLexical rules have an implicit return type of 'int'.");
727             }
728         }
729         else {
730             if (doingLexRules) {
731                 println("Return value: lexical rule returns an implicit token type");
732             }
733             else {
734                 println("Return value: none");
735             }
736         }
737
738         // Gen arguments
739
if (rblk.argAction != null) {
740             println("Arguments: " + rblk.argAction);
741         }
742
743         // Dump any init-action
744
genBlockPreamble(rblk);
745
746         // Analyze the rule
747
boolean ok = grammar.theLLkAnalyzer.deterministic(rblk);
748         if (!ok) {
749             println("Error: This rule is non-deterministic");
750         }
751
752         // Dump the alternates of the rule
753
genCommonBlock(rblk);
754
755         // Search for an unlabeled exception specification attached to the rule
756
ExceptionSpec unlabeledUserSpec = rblk.findExceptionSpec("");
757
758         // Generate user-defined or default catch phrases
759
if (unlabeledUserSpec != null) {
760             println("You specified error-handler(s) for this rule:");
761             tabs++;
762             for (int i = 0; i < unlabeledUserSpec.handlers.size(); i++) {
763                 if (i != 0) {
764                     println("");
765                 }
766
767                 ExceptionHandler handler = (ExceptionHandler)unlabeledUserSpec.handlers.elementAt(i);
768                 println("Error-handler(" + (i + 1) + ") catches [" + handler.exceptionTypeAndName.getText() + "] and executes:");
769                 printAction(handler.action.getText());
770             }
771             tabs--;
772             println("End error-handlers.");
773         }
774         else if (!doingLexRules) {
775             println("Default error-handling will be generated, which catches all");
776             println("parser exceptions and consumes tokens until the follow-set is seen.");
777         }
778
779         // Dump the follow set
780
// Doesn't seem to work for lexical rules...
781
if (!doingLexRules) {
782             println("The follow set for this rule is:");
783             tabs++;
784             genFollowSetForRuleBlock(rblk);
785             tabs--;
786         }
787
788         tabs--;
789         println("*** End " + ruleType + " Rule: " + s.getId());
790     }
791
792     /** Generate the syntactic predicate. This basically generates
793      * the alternative block, buts tracks if we are inside a synPred
794      * @param blk The syntactic predicate block
795      */

796     protected void genSynPred(SynPredBlock blk) {
797         syntacticPredLevel++;
798         gen((AlternativeBlock)blk);
799         syntacticPredLevel--;
800     }
801
802     /** Generate the token types TXT file */
803     protected void genTokenTypes(TokenManager tm) throws IOException JavaDoc {
804         // Open the token output TXT file and set the currentOutput stream
805
antlrTool.reportProgress("Generating " + tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt);
806         currentOutput = antlrTool.openOutputFile(tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt);
807         //SAS: changed for proper text file io
808
tabs = 0;
809
810         // Generate the header common to all diagnostic files
811
genHeader();
812
813         // Generate a string for each token. This creates a static
814
// array of Strings indexed by token type.
815
println("");
816         println("*** Tokens used by the parser");
817         println("This is a list of the token numeric values and the corresponding");
818         println("token identifiers. Some tokens are literals, and because of that");
819         println("they have no identifiers. Literals are double-quoted.");
820         tabs++;
821
822         // Enumerate all the valid token types
823
Vector v = tm.getVocabulary();
824         for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) {
825             String JavaDoc s = (String JavaDoc)v.elementAt(i);
826             if (s != null) {
827                 println(s + " = " + i);
828             }
829         }
830
831         // Close the interface
832
tabs--;
833         println("*** End of tokens used by the parser");
834
835         // Close the tokens output file
836
currentOutput.close();
837         currentOutput = null;
838     }
839
840     /** Get a string for an expression to generate creation of an AST subtree.
841      * @param v A Vector of String, where each element is an expression in the target language yielding an AST node.
842      */

843     public String JavaDoc getASTCreateString(Vector v) {
844         return "***Create an AST from a vector here***" + System.getProperty("line.separator");
845     }
846
847     /** Get a string for an expression to generate creating of an AST node
848      * @param str The arguments to the AST constructor
849      */

850     public String JavaDoc getASTCreateString(GrammarAtom atom, String JavaDoc str) {
851         return "[" + str + "]";
852     }
853
854     /// unused.
855
protected String JavaDoc processActionForSpecialSymbols(String JavaDoc actionStr,
856                                                     int line,
857                                                     RuleBlock currentRule,
858                                                     ActionTransInfo tInfo) {
859         return actionStr;
860     }
861
862     /** Map an identifier to it's corresponding tree-node variable.
863      * This is context-sensitive, depending on the rule and alternative
864      * being generated
865      * @param id The identifier name to map
866      * @param forInput true if the input tree node variable is to be returned, otherwise the output variable is returned.
867      */

868     public String JavaDoc mapTreeId(String JavaDoc id, ActionTransInfo tInfo) {
869         return id;
870     }
871
872     /** Format a lookahead or follow set.
873      * @param depth The depth of the entire lookahead/follow
874      * @param k The lookahead level to print
875      * @param lookahead The lookahead/follow set to print
876      */

877     public void printSet(int depth, int k, Lookahead lookahead) {
878         int numCols = 5;
879
880         int[] elems = lookahead.fset.toArray();
881
882         if (depth != 1) {
883             print("k==" + k + ": {");
884         }
885         else {
886             print("{ ");
887         }
888         if (elems.length > numCols) {
889             _println("");
890             tabs++;
891             print("");
892         }
893
894         int column = 0;
895         for (int i = 0; i < elems.length; i++) {
896             column++;
897             if (column > numCols) {
898                 _println("");
899                 print("");
900                 column = 0;
901             }
902             if (doingLexRules) {
903                 _print(charFormatter.literalChar(elems[i]));
904             }
905             else {
906                 _print((String JavaDoc)grammar.tokenManager.getVocabulary().elementAt(elems[i]));
907             }
908             if (i != elems.length - 1) {
909                 _print(", ");
910             }
911         }
912
913         if (elems.length > numCols) {
914             _println("");
915             tabs--;
916             print("");
917         }
918         _println(" }");
919     }
920 }
921
Popular Tags