KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > antlr > HTMLCodeGenerator


1 package antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/RIGHTS.html
6  *
7  * $Id: //depot/code/org.antlr/main/main/antlr/HTMLCodeGenerator.java#9 $
8  */

9
10 import java.util.Enumeration JavaDoc;
11
12 import antlr.collections.impl.BitSet;
13 import antlr.collections.impl.Vector;
14
15 import java.io.PrintWriter JavaDoc; //SAS: changed for proper text file io
16
import java.io.IOException JavaDoc;
17 import java.io.FileWriter JavaDoc;
18
19 /**Generate P.html, a cross-linked representation of P with or without actions */
20 public class HTMLCodeGenerator extends CodeGenerator {
21     /** non-zero if inside syntactic predicate generation */
22     protected int syntacticPredLevel = 0;
23
24     /** true during lexer generation, false during parser generation */
25     protected boolean doingLexRules = false;
26
27     protected boolean firstElementInAlt;
28
29     protected AlternativeElement prevAltElem = null; // what was generated last?
30

31     /** Create a Diagnostic code-generator using the given Grammar
32      * The caller must still call setTool, setBehavior, and setAnalyzer
33      * before generating code.
34      */

35     public HTMLCodeGenerator() {
36         super();
37         charFormatter = new JavaCharFormatter();
38     }
39
40     /** Encode a string for printing in a HTML document..
41      * e.g. encode '<' '>' and similar stuff
42      * @param s the string to encode
43      */

44     static String JavaDoc HTMLEncode(String JavaDoc s) {
45         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
46
47         for (int i = 0, len = s.length(); i < len; i++) {
48             char c = s.charAt(i);
49             if (c == '&')
50                 buf.append("&amp;");
51             else if (c == '\"')
52                 buf.append("&quot;");
53             else if (c == '\'')
54                 buf.append("&#039;");
55             else if (c == '<')
56                 buf.append("&lt;");
57             else if (c == '>')
58                 buf.append("&gt;");
59             else
60                 buf.append(c);
61         }
62         return buf.toString();
63     }
64
65     public void gen() {
66         // Do the code generation
67
try {
68             // Loop over all grammars
69
Enumeration JavaDoc grammarIter = behavior.grammars.elements();
70             while (grammarIter.hasMoreElements()) {
71                 Grammar g = (Grammar)grammarIter.nextElement();
72
73                 // Connect all the components to each other
74
/*
75                 g.setGrammarAnalyzer(analyzer);
76                 analyzer.setGrammar(g);
77                 */

78                 g.setCodeGenerator(this);
79
80                 // To get right overloading behavior across hetrogeneous grammars
81
g.generate();
82
83                 if (antlrTool.hasError()) {
84                     System.out.println("Exiting due to errors.");
85                     System.exit(1);
86                 }
87
88             }
89
90         }
91         catch (IOException JavaDoc e) {
92             System.out.println(e.getMessage());
93         }
94     }
95
96     /** Generate code for the given grammar element.
97      * @param blk The {...} action to generate
98      */

99     public void gen(ActionElement action) {
100         // no-op
101
}
102
103     /** Generate code for the given grammar element.
104      * @param blk The "x|y|z|..." block to generate
105      */

106     public void gen(AlternativeBlock blk) {
107         genGenericBlock(blk, "");
108     }
109
110     /** Generate code for the given grammar element.
111      * @param blk The block-end element to generate. Block-end
112      * elements are synthesized by the grammar parser to represent
113      * the end of a block.
114      */

115     public void gen(BlockEndElement end) {
116         // no-op
117
}
118
119     /** Generate code for the given grammar element.
120      * @param blk The character literal reference to generate
121      */

122     public void gen(CharLiteralElement atom) {
123         if (atom.not) {
124             _print("~");
125         }
126         _print(HTMLEncode(atom.atomText) + " ");
127     }
128
129     /** Generate code for the given grammar element.
130      * @param blk The character-range reference to generate
131      */

132     public void gen(CharRangeElement r) {
133         print(r.beginText + ".." + r.endText + " ");
134     }
135
136     /** Generate the lexer HTML file */
137     public void gen(LexerGrammar g) throws IOException JavaDoc {
138         setGrammar(g);
139         System.out.println("Generating " + grammar.getClassName() + TokenTypesFileExt);
140         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt);
141         //SAS: changed for proper text file io
142

143         tabs = 0;
144         doingLexRules = true;
145
146         // Generate header common to all TXT output files
147
genHeader();
148
149         // Output the user-defined lexer premamble
150
// RK: guess not..
151
// println(grammar.preambleAction.getText());
152

153         // Generate lexer class definition
154
println("");
155
156         // print javadoc comment if any
157
if (grammar.comment != null) {
158             _println(HTMLEncode(grammar.comment));
159         }
160
161         println("Definition of lexer " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".");
162
163         // Generate user-defined parser class members
164
// printAction(grammar.classMemberAction.getText());
165

166         /*
167         // Generate string literals
168         println("");
169         println("*** String literals used in the parser");
170         println("The following string literals were used in the parser.");
171         println("An actual code generator would arrange to place these literals");
172         println("into a table in the generated lexer, so that actions in the");
173         println("generated lexer could match token text against the literals.");
174         println("String literals used in the lexer are not listed here, as they");
175         println("are incorporated into the mainstream lexer processing.");
176         tabs++;
177         // Enumerate all of the symbols and look for string literal symbols
178         Enumeration ids = grammar.getSymbols();
179         while ( ids.hasMoreElements() ) {
180             GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
181             // Only processing string literals -- reject other symbol entries
182             if ( sym instanceof StringLiteralSymbol ) {
183                 StringLiteralSymbol s = (StringLiteralSymbol)sym;
184                 println(s.getId() + " = " + s.getTokenType());
185             }
186         }
187         tabs--;
188         println("*** End of string literals used by the parser");
189         */

190
191         // Generate nextToken() rule.
192
// nextToken() is a synthetic lexer rule that is the implicit OR of all
193
// user-defined lexer rules.
194
genNextToken();
195
196         // Generate code for each rule in the lexer
197

198         Enumeration JavaDoc ids = grammar.rules.elements();
199         while (ids.hasMoreElements()) {
200             RuleSymbol rs = (RuleSymbol)ids.nextElement();
201             if (!rs.id.equals("mnextToken")) {
202                 genRule(rs);
203             }
204         }
205
206         // Close the lexer output file
207
currentOutput.close();
208         currentOutput = null;
209         doingLexRules = false;
210     }
211
212     /** Generate code for the given grammar element.
213      * @param blk The (...)+ block to generate
214      */

215     public void gen(OneOrMoreBlock blk) {
216         genGenericBlock(blk, "+");
217     }
218
219     /** Generate the parser HTML file */
220     public void gen(ParserGrammar g) throws IOException JavaDoc {
221         setGrammar(g);
222         // Open the output stream for the parser and set the currentOutput
223
System.out.println("Generating " + grammar.getClassName() + ".html");
224         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".html");
225
226         tabs = 0;
227
228         // Generate the header common to all output files.
229
genHeader();
230
231         // Generate parser class definition
232
println("");
233
234         // print javadoc comment if any
235
if (grammar.comment != null) {
236             _println(HTMLEncode(grammar.comment));
237         }
238
239         println("Definition of parser " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".");
240
241         // Enumerate the parser rules
242
Enumeration JavaDoc rules = grammar.rules.elements();
243         while (rules.hasMoreElements()) {
244             println("");
245             // Get the rules from the list and downcast it to proper type
246
GrammarSymbol sym = (GrammarSymbol)rules.nextElement();
247             // Only process parser rules
248
if (sym instanceof RuleSymbol) {
249                 genRule((RuleSymbol)sym);
250             }
251         }
252         tabs--;
253         println("");
254
255         genTail();
256
257         // Close the parser output stream
258
currentOutput.close();
259         currentOutput = null;
260     }
261
262     /** Generate code for the given grammar element.
263      * @param blk The rule-reference to generate
264      */

265     public void gen(RuleRefElement rr) {
266         RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
267
268         // Generate the actual rule description
269
_print("<a HREF=\"" + grammar.getClassName() + ".html#" + rr.targetRule + "\">");
270         _print(rr.targetRule);
271         _print("</a>");
272         // RK: Leave out args..
273
// if (rr.args != null) {
274
// _print("["+rr.args+"]");
275
// }
276
_print(" ");
277     }
278
279     /** Generate code for the given grammar element.
280      * @param blk The string-literal reference to generate
281      */

282     public void gen(StringLiteralElement atom) {
283         if (atom.not) {
284             _print("~");
285         }
286         _print(HTMLEncode(atom.atomText));
287         _print(" ");
288     }
289
290     /** Generate code for the given grammar element.
291      * @param blk The token-range reference to generate
292      */

293     public void gen(TokenRangeElement r) {
294         print(r.beginText + ".." + r.endText + " ");
295     }
296
297     /** Generate code for the given grammar element.
298      * @param blk The token-reference to generate
299      */

300     public void gen(TokenRefElement atom) {
301         if (atom.not) {
302             _print("~");
303         }
304         _print(atom.atomText);
305         _print(" ");
306     }
307
308     public void gen(TreeElement t) {
309         print(t + " ");
310     }
311
312     /** Generate the tree-walker TXT file */
313     public void gen(TreeWalkerGrammar g) throws IOException JavaDoc {
314         setGrammar(g);
315         // Open the output stream for the parser and set the currentOutput
316
System.out.println("Generating " + grammar.getClassName() + ".html");
317         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".html");
318         //SAS: changed for proper text file io
319

320         tabs = 0;
321
322         // Generate the header common to all output files.
323
genHeader();
324
325         // Output the user-defined parser premamble
326
println("");
327 // println("*** Tree-walker Preamble Action.");
328
// println("This action will appear before the declaration of your tree-walker class:");
329
// tabs++;
330
// println(grammar.preambleAction.getText());
331
// tabs--;
332
// println("*** End of tree-walker Preamble Action");
333

334         // Generate tree-walker class definition
335
println("");
336
337         // print javadoc comment if any
338
if (grammar.comment != null) {
339             _println(HTMLEncode(grammar.comment));
340         }
341
342         println("Definition of tree parser " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".");
343
344         // Generate user-defined tree-walker class members
345
// println("");
346
// println("*** User-defined tree-walker class members:");
347
// println("These are the member declarations that you defined for your class:");
348
// tabs++;
349
// printAction(grammar.classMemberAction.getText());
350
// tabs--;
351
// println("*** End of user-defined tree-walker class members");
352

353         // Generate code for each rule in the grammar
354
println("");
355 // println("*** tree-walker rules:");
356
tabs++;
357
358         // Enumerate the tree-walker rules
359
Enumeration JavaDoc rules = grammar.rules.elements();
360         while (rules.hasMoreElements()) {
361             println("");
362             // Get the rules from the list and downcast it to proper type
363
GrammarSymbol sym = (GrammarSymbol)rules.nextElement();
364             // Only process tree-walker rules
365
if (sym instanceof RuleSymbol) {
366                 genRule((RuleSymbol)sym);
367             }
368         }
369         tabs--;
370         println("");
371 // println("*** End of tree-walker rules");
372

373 // println("");
374
// println("*** End of tree-walker");
375

376         // Close the tree-walker output stream
377
currentOutput.close();
378         currentOutput = null;
379     }
380
381     /** Generate a wildcard element */
382     public void gen(WildcardElement wc) {
383         /*
384         if ( wc.getLabel()!=null ) {
385             _print(wc.getLabel()+"=");
386         }
387         */

388         _print(". ");
389     }
390
391     /** Generate code for the given grammar element.
392      * @param blk The (...)* block to generate
393      */

394     public void gen(ZeroOrMoreBlock blk) {
395         genGenericBlock(blk, "*");
396     }
397
398     protected void genAlt(Alternative alt) {
399         if (alt.getTreeSpecifier() != null) {
400             _print(alt.getTreeSpecifier().getText());
401         }
402         prevAltElem = null;
403         for (AlternativeElement elem = alt.head;
404              !(elem instanceof BlockEndElement);
405              elem = elem.next) {
406             elem.generate();
407             firstElementInAlt = false;
408             prevAltElem = elem;
409         }
410     }
411     /** Generate the header for a block, which may be a RuleBlock or a
412      * plain AlternativeBLock. This generates any variable declarations,
413      * init-actions, and syntactic-predicate-testing variables.
414      * @blk The block for which the preamble is to be generated.
415      */

416 // protected void genBlockPreamble(AlternativeBlock blk) {
417
// RK: don't dump out init actions
418
// dump out init action
419
// if ( blk.initAction!=null ) {
420
// printAction("{" + blk.initAction + "}");
421
// }
422
// }
423
/**Generate common code for a block of alternatives; return a postscript
424      * that needs to be generated at the end of the block. Other routines
425      * may append else-clauses and such for error checking before the postfix
426      * is generated.
427      */

428     public void genCommonBlock(AlternativeBlock blk) {
429         for (int i = 0; i < blk.alternatives.size(); i++) {
430             Alternative alt = blk.getAlternativeAt(i);
431             AlternativeElement elem = alt.head;
432
433             // dump alt operator |
434
if (i > 0 && blk.alternatives.size() > 1) {
435                 _println("");
436                 print("|\t");
437             }
438
439             // Dump the alternative, starting with predicates
440
//
441
boolean save = firstElementInAlt;
442             firstElementInAlt = true;
443             tabs++; // in case we do a newline in alt, increase the tab indent
444

445             // RK: don't dump semantic/syntactic predicates
446
// only obscures grammar.
447
//
448
// Dump semantic predicates
449
//
450
// if (alt.semPred != null) {
451
// println("{" + alt.semPred + "}?");
452
// }
453
// Dump syntactic predicate
454
// if (alt.synPred != null) {
455
// genSynPred(alt.synPred);
456
// }
457
genAlt(alt);
458             tabs--;
459             firstElementInAlt = save;
460         }
461     }
462
463     /** Generate a textual representation of the follow set
464      * for a block.
465      * @param blk The rule block of interest
466      */

467     public void genFollowSetForRuleBlock(RuleBlock blk) {
468         Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1, blk.endNode);
469         printSet(grammar.maxk, 1, follow);
470     }
471
472     protected void genGenericBlock(AlternativeBlock blk, String JavaDoc blkOp) {
473         if (blk.alternatives.size() > 1) {
474             // make sure we start on a new line
475
if (!firstElementInAlt) {
476                 // only do newline if the last element wasn't a multi-line block
477
if (prevAltElem == null ||
478                     !(prevAltElem instanceof AlternativeBlock) ||
479                     ((AlternativeBlock)prevAltElem).alternatives.size() == 1) {
480                     _println("");
481                     print("(\t");
482                 }
483                 else {
484                     _print("(\t");
485                 }
486                 // _println("");
487
// print("(\t");
488
}
489             else {
490                 _print("(\t");
491             }
492         }
493         else {
494             _print("( ");
495         }
496         // RK: don't dump init actions
497
// genBlockPreamble(blk);
498
genCommonBlock(blk);
499         if (blk.alternatives.size() > 1) {
500             _println("");
501             print(")" + blkOp + " ");
502             // if not last element of alt, need newline & to indent
503
if (!(blk.next instanceof BlockEndElement)) {
504                 _println("");
505                 print("");
506             }
507         }
508         else {
509             _print(")" + blkOp + " ");
510         }
511     }
512
513     /** Generate a header that is common to all TXT files */
514     protected void genHeader() {
515         println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
516         println("<HTML>");
517         println("<HEAD>");
518         println("<TITLE>Grammar " + antlrTool.grammarFile + "</TITLE>");
519         println("</HEAD>");
520         println("<BODY>");
521         println("<table summary=\"\" border=\"1\" cellpadding=\"5\">");
522         println("<tr>");
523         println("<td>");
524         println("<font size=\"+2\">Grammar " + grammar.getClassName() + "</font><br>");
525         println("<a HREF=\"http://www.ANTLR.org\">ANTLR</a>-generated HTML file from " + antlrTool.grammarFile);
526         println("<p>");
527         println("Terence Parr, <a HREF=\"http://www.magelang.com\">MageLang Institute</a>");
528         println("<br>ANTLR Version " + antlrTool.version + "; 1989-1999");
529         println("</td>");
530         println("</tr>");
531         println("</table>");
532         println("<PRE>");
533         // RK: see no reason for printing include files and stuff...
534
// tabs++;
535
// printAction(behavior.getHeaderAction(""));
536
// tabs--;
537
}
538
539     /**Generate the lookahead set for an alternate. */
540     protected void genLookaheadSetForAlt(Alternative alt) {
541         if (doingLexRules && alt.cache[1].containsEpsilon()) {
542             println("MATCHES ALL");
543             return;
544         }
545         int depth = alt.lookaheadDepth;
546         if (depth == GrammarAnalyzer.NONDETERMINISTIC) {
547             // if the decision is nondeterministic, do the best we can: LL(k)
548
// any predicates that are around will be generated later.
549
depth = grammar.maxk;
550         }
551         for (int i = 1; i <= depth; i++) {
552             Lookahead lookahead = alt.cache[i];
553             printSet(depth, i, lookahead);
554         }
555     }
556
557     /** Generate a textual representation of the lookahead set
558      * for a block.
559      * @param blk The block of interest
560      */

561     public void genLookaheadSetForBlock(AlternativeBlock blk) {
562         // Find the maximal lookahead depth over all alternatives
563
int depth = 0;
564         for (int i = 0; i < blk.alternatives.size(); i++) {
565             Alternative alt = blk.getAlternativeAt(i);
566             if (alt.lookaheadDepth == GrammarAnalyzer.NONDETERMINISTIC) {
567                 depth = grammar.maxk;
568                 break;
569             }
570             else if (depth < alt.lookaheadDepth) {
571                 depth = alt.lookaheadDepth;
572             }
573         }
574
575         for (int i = 1; i <= depth; i++) {
576             Lookahead lookahead = grammar.theLLkAnalyzer.look(i, blk);
577             printSet(depth, i, lookahead);
578         }
579     }
580
581     /** Generate the nextToken rule.
582      * nextToken is a synthetic lexer rule that is the implicit OR of all
583      * user-defined lexer rules.
584      */

585     public void genNextToken() {
586         println("");
587         println("/** Lexer nextToken rule:");
588         println(" * The lexer nextToken rule is synthesized from all of the user-defined");
589         println(" * lexer rules. It logically consists of one big alternative block with");
590         println(" * each user-defined rule being an alternative.");
591         println(" */");
592
593         // Create the synthesized rule block for nextToken consisting
594
// of an alternate block containing all the user-defined lexer rules.
595
RuleBlock blk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");
596
597         // Define the nextToken rule symbol
598
RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
599         nextTokenRs.setDefined();
600         nextTokenRs.setBlock(blk);
601         nextTokenRs.access = "private";
602         grammar.define(nextTokenRs);
603
604         /*
605         // Analyze the synthesized block
606         if (!grammar.theLLkAnalyzer.deterministic(blk))
607         {
608             println("The grammar analyzer has determined that the synthesized");
609             println("nextToken rule is non-deterministic (i.e., it has ambiguities)");
610             println("This means that there is some overlap of the character");
611             println("lookahead for two or more of your lexer rules.");
612         }
613         */

614
615         genCommonBlock(blk);
616     }
617
618     /** Generate code for a named rule block
619      * @param s The RuleSymbol describing the rule to generate
620      */

621     public void genRule(RuleSymbol s) {
622         if (s == null || !s.isDefined()) return; // undefined rule
623
println("");
624         if (s.comment != null) {
625             _println(HTMLEncode(s.comment));
626         }
627         if (s.access.length() != 0) {
628             if (!s.access.equals("public")) {
629                 _print(s.access + " ");
630             }
631         }
632         _print("<a name=\"" + s.getId() + "\">");
633         _print(s.getId());
634         _print("</a>");
635
636         // Get rule return type and arguments
637
RuleBlock rblk = s.getBlock();
638
639         // RK: for HTML output not of much value...
640
// Gen method return value(s)
641
// if (rblk.returnAction != null) {
642
// _print("["+rblk.returnAction+"]");
643
// }
644
// Gen arguments
645
// if (rblk.argAction != null)
646
// {
647
// _print(" returns [" + rblk.argAction+"]");
648
// }
649
_println("");
650         tabs++;
651         print(":\t");
652
653         // Dump any init-action
654
// genBlockPreamble(rblk);
655

656         // Dump the alternates of the rule
657
genCommonBlock(rblk);
658
659         _println("");
660         println(";");
661         tabs--;
662     }
663
664     /** Generate the syntactic predicate. This basically generates
665      * the alternative block, buts tracks if we are inside a synPred
666      * @param blk The syntactic predicate block
667      */

668     protected void genSynPred(SynPredBlock blk) {
669         syntacticPredLevel++;
670         genGenericBlock(blk, " =>");
671         syntacticPredLevel--;
672     }
673
674     public void genTail() {
675         println("</PRE>");
676         println("</BODY>");
677         println("</HTML>");
678     }
679
680     /** Generate the token types TXT file */
681     protected void genTokenTypes(TokenManager tm) throws IOException JavaDoc {
682         // Open the token output TXT file and set the currentOutput stream
683
System.out.println("Generating " + tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt);
684         currentOutput = antlrTool.openOutputFile(tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt);
685         //SAS: changed for proper text file io
686
tabs = 0;
687
688         // Generate the header common to all diagnostic files
689
genHeader();
690
691         // Generate a string for each token. This creates a static
692
// array of Strings indexed by token type.
693
println("");
694         println("*** Tokens used by the parser");
695         println("This is a list of the token numeric values and the corresponding");
696         println("token identifiers. Some tokens are literals, and because of that");
697         println("they have no identifiers. Literals are double-quoted.");
698         tabs++;
699
700         // Enumerate all the valid token types
701
Vector v = tm.getVocabulary();
702         for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) {
703             String JavaDoc s = (String JavaDoc)v.elementAt(i);
704             if (s != null) {
705                 println(s + " = " + i);
706             }
707         }
708
709         // Close the interface
710
tabs--;
711         println("*** End of tokens used by the parser");
712
713         // Close the tokens output file
714
currentOutput.close();
715         currentOutput = null;
716     }
717
718     /** Get a string for an expression to generate creation of an AST subtree.
719      * @param v A Vector of String, where each element is an expression in the target language yielding an AST node.
720      */

721     public String JavaDoc getASTCreateString(Vector v) {
722         return null;
723     }
724
725     /** Get a string for an expression to generate creating of an AST node
726      * @param str The arguments to the AST constructor
727      */

728     public String JavaDoc getASTCreateString(GrammarAtom atom, String JavaDoc str) {
729         return null;
730     }
731
732     /** Map an identifier to it's corresponding tree-node variable.
733      * This is context-sensitive, depending on the rule and alternative
734      * being generated
735      * @param id The identifier name to map
736      * @param forInput true if the input tree node variable is to be returned, otherwise the output variable is returned.
737      */

738     public String JavaDoc mapTreeId(String JavaDoc id, ActionTransInfo tInfo) {
739         return id;
740     }
741
742     /// unused.
743
protected String JavaDoc processActionForTreeSpecifiers(String JavaDoc actionStr,
744                                                     int line,
745                                                     RuleBlock currentRule,
746                                                     ActionTransInfo tInfo) {
747         return actionStr;
748     }
749
750     /** Format a lookahead or follow set.
751      * @param depth The depth of the entire lookahead/follow
752      * @param k The lookahead level to print
753      * @param lookahead The lookahead/follow set to print
754      */

755     public void printSet(int depth, int k, Lookahead lookahead) {
756         int numCols = 5;
757
758         int[] elems = lookahead.fset.toArray();
759
760         if (depth != 1) {
761             print("k==" + k + ": {");
762         }
763         else {
764             print("{ ");
765         }
766         if (elems.length > numCols) {
767             _println("");
768             tabs++;
769             print("");
770         }
771
772         int column = 0;
773         for (int i = 0; i < elems.length; i++) {
774             column++;
775             if (column > numCols) {
776                 _println("");
777                 print("");
778                 column = 0;
779             }
780             if (doingLexRules) {
781                 _print(charFormatter.literalChar(elems[i]));
782             }
783             else {
784                 _print((String JavaDoc)grammar.tokenManager.getVocabulary().elementAt(elems[i]));
785             }
786             if (i != elems.length - 1) {
787                 _print(", ");
788             }
789         }
790
791         if (elems.length > numCols) {
792             _println("");
793             tabs--;
794             print("");
795         }
796         _println(" }");
797     }
798 }
799
Popular Tags