1 package antlr; 2 3 9 10 import java.util.Enumeration ; 11 12 import antlr.collections.impl.BitSet; 13 import antlr.collections.impl.Vector; 14 15 import java.io.PrintWriter ; import java.io.IOException ; 17 import java.io.FileWriter ; 18 19 20 public class HTMLCodeGenerator extends CodeGenerator { 21 22 protected int syntacticPredLevel = 0; 23 24 25 protected boolean doingLexRules = false; 26 27 protected boolean firstElementInAlt; 28 29 protected AlternativeElement prevAltElem = null; 31 35 public HTMLCodeGenerator() { 36 super(); 37 charFormatter = new JavaCharFormatter(); 38 } 39 40 44 static String HTMLEncode(String s) { 45 StringBuffer buf = new StringBuffer (); 46 47 for (int i = 0, len = s.length(); i < len; i++) { 48 char c = s.charAt(i); 49 if (c == '&') 50 buf.append("&"); 51 else if (c == '\"') 52 buf.append("""); 53 else if (c == '\'') 54 buf.append("'"); 55 else if (c == '<') 56 buf.append("<"); 57 else if (c == '>') 58 buf.append(">"); 59 else 60 buf.append(c); 61 } 62 return buf.toString(); 63 } 64 65 public void gen() { 66 try { 68 Enumeration grammarIter = behavior.grammars.elements(); 70 while (grammarIter.hasMoreElements()) { 71 Grammar g = (Grammar)grammarIter.nextElement(); 72 73 78 g.setCodeGenerator(this); 79 80 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 e) { 92 System.out.println(e.getMessage()); 93 } 94 } 95 96 99 public void gen(ActionElement action) { 100 } 102 103 106 public void gen(AlternativeBlock blk) { 107 genGenericBlock(blk, ""); 108 } 109 110 115 public void gen(BlockEndElement end) { 116 } 118 119 122 public void gen(CharLiteralElement atom) { 123 if (atom.not) { 124 _print("~"); 125 } 126 _print(HTMLEncode(atom.atomText) + " "); 127 } 128 129 132 public void gen(CharRangeElement r) { 133 print(r.beginText + ".." + r.endText + " "); 134 } 135 136 137 public void gen(LexerGrammar g) throws IOException { 138 setGrammar(g); 139 System.out.println("Generating " + grammar.getClassName() + TokenTypesFileExt); 140 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt); 141 143 tabs = 0; 144 doingLexRules = true; 145 146 genHeader(); 148 149 153 println(""); 155 156 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 166 190 191 genNextToken(); 195 196 198 Enumeration 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 currentOutput.close(); 208 currentOutput = null; 209 doingLexRules = false; 210 } 211 212 215 public void gen(OneOrMoreBlock blk) { 216 genGenericBlock(blk, "+"); 217 } 218 219 220 public void gen(ParserGrammar g) throws IOException { 221 setGrammar(g); 222 System.out.println("Generating " + grammar.getClassName() + ".html"); 224 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".html"); 225 226 tabs = 0; 227 228 genHeader(); 230 231 println(""); 233 234 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 Enumeration rules = grammar.rules.elements(); 243 while (rules.hasMoreElements()) { 244 println(""); 245 GrammarSymbol sym = (GrammarSymbol)rules.nextElement(); 247 if (sym instanceof RuleSymbol) { 249 genRule((RuleSymbol)sym); 250 } 251 } 252 tabs--; 253 println(""); 254 255 genTail(); 256 257 currentOutput.close(); 259 currentOutput = null; 260 } 261 262 265 public void gen(RuleRefElement rr) { 266 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule); 267 268 _print("<a HREF=\"" + grammar.getClassName() + ".html#" + rr.targetRule + "\">"); 270 _print(rr.targetRule); 271 _print("</a>"); 272 _print(" "); 277 } 278 279 282 public void gen(StringLiteralElement atom) { 283 if (atom.not) { 284 _print("~"); 285 } 286 _print(HTMLEncode(atom.atomText)); 287 _print(" "); 288 } 289 290 293 public void gen(TokenRangeElement r) { 294 print(r.beginText + ".." + r.endText + " "); 295 } 296 297 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 313 public void gen(TreeWalkerGrammar g) throws IOException { 314 setGrammar(g); 315 System.out.println("Generating " + grammar.getClassName() + ".html"); 317 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".html"); 318 320 tabs = 0; 321 322 genHeader(); 324 325 println(""); 327 334 println(""); 336 337 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 353 println(""); 355 tabs++; 357 358 Enumeration rules = grammar.rules.elements(); 360 while (rules.hasMoreElements()) { 361 println(""); 362 GrammarSymbol sym = (GrammarSymbol)rules.nextElement(); 364 if (sym instanceof RuleSymbol) { 366 genRule((RuleSymbol)sym); 367 } 368 } 369 tabs--; 370 println(""); 371 373 376 currentOutput.close(); 378 currentOutput = null; 379 } 380 381 382 public void gen(WildcardElement wc) { 383 388 _print(". "); 389 } 390 391 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 416 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 if (i > 0 && blk.alternatives.size() > 1) { 435 _println(""); 436 print("|\t"); 437 } 438 439 boolean save = firstElementInAlt; 442 firstElementInAlt = true; 443 tabs++; 445 genAlt(alt); 458 tabs--; 459 firstElementInAlt = save; 460 } 461 } 462 463 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 blkOp) { 473 if (blk.alternatives.size() > 1) { 474 if (!firstElementInAlt) { 476 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 } 489 else { 490 _print("(\t"); 491 } 492 } 493 else { 494 _print("( "); 495 } 496 genCommonBlock(blk); 499 if (blk.alternatives.size() > 1) { 500 _println(""); 501 print(")" + blkOp + " "); 502 if (!(blk.next instanceof BlockEndElement)) { 504 _println(""); 505 print(""); 506 } 507 } 508 else { 509 _print(")" + blkOp + " "); 510 } 511 } 512 513 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 } 538 539 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 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 561 public void genLookaheadSetForBlock(AlternativeBlock blk) { 562 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 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 RuleBlock blk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken"); 596 597 RuleSymbol nextTokenRs = new RuleSymbol("mnextToken"); 599 nextTokenRs.setDefined(); 600 nextTokenRs.setBlock(blk); 601 nextTokenRs.access = "private"; 602 grammar.define(nextTokenRs); 603 604 614 615 genCommonBlock(blk); 616 } 617 618 621 public void genRule(RuleSymbol s) { 622 if (s == null || !s.isDefined()) return; 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 RuleBlock rblk = s.getBlock(); 638 639 _println(""); 650 tabs++; 651 print(":\t"); 652 653 656 genCommonBlock(rblk); 658 659 _println(""); 660 println(";"); 661 tabs--; 662 } 663 664 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 681 protected void genTokenTypes(TokenManager tm) throws IOException { 682 System.out.println("Generating " + tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt); 684 currentOutput = antlrTool.openOutputFile(tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt); 685 tabs = 0; 687 688 genHeader(); 690 691 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 Vector v = tm.getVocabulary(); 702 for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) { 703 String s = (String )v.elementAt(i); 704 if (s != null) { 705 println(s + " = " + i); 706 } 707 } 708 709 tabs--; 711 println("*** End of tokens used by the parser"); 712 713 currentOutput.close(); 715 currentOutput = null; 716 } 717 718 721 public String getASTCreateString(Vector v) { 722 return null; 723 } 724 725 728 public String getASTCreateString(GrammarAtom atom, String str) { 729 return null; 730 } 731 732 738 public String mapTreeId(String id, ActionTransInfo tInfo) { 739 return id; 740 } 741 742 protected String processActionForTreeSpecifiers(String actionStr, 744 int line, 745 RuleBlock currentRule, 746 ActionTransInfo tInfo) { 747 return actionStr; 748 } 749 750 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 )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
|