KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > persistence > antlr > HTMLCodeGenerator


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 P.html, a cross-linked representation of P with or without actions */
19 public class HTMLCodeGenerator 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     protected boolean firstElementInAlt;
27
28     protected AlternativeElement prevAltElem = null; // what was generated last?
29

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

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

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

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

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

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

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

120     public void gen(CharLiteralElement atom) {
121         if (atom.not) {
122             _print("~");
123         }
124         _print(HTMLEncode(atom.atomText) + " ");
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(r.beginText + ".." + r.endText + " ");
132     }
133
134     /** Generate the lexer HTML file */
135     public void gen(LexerGrammar g) throws IOException JavaDoc {
136         setGrammar(g);
137         antlrTool.reportProgress("Generating " + grammar.getClassName() + TokenTypesFileExt);
138         currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt);
139         //SAS: changed for proper text file io
140

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

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

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

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

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

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

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

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

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

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

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

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

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

371 // println("");
372
// println("*** End of tree-walker");
373

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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