1 package antlr; 2 3 9 10 12 13 import java.util.Enumeration ; 14 15 import antlr.collections.impl.BitSet; 16 import antlr.collections.impl.Vector; 17 18 import java.io.PrintWriter ; import java.io.IOException ; 20 import java.io.FileWriter ; 21 22 23 public class DocBookCodeGenerator extends CodeGenerator { 24 25 protected int syntacticPredLevel = 0; 26 27 28 protected boolean doingLexRules = false; 29 30 protected boolean firstElementInAlt; 31 32 protected AlternativeElement prevAltElem = null; 34 38 public DocBookCodeGenerator() { 39 super(); 40 charFormatter = new JavaCharFormatter(); 41 } 42 43 47 static String HTMLEncode(String s) { 48 StringBuffer buf = new StringBuffer (); 49 50 for (int i = 0, len = s.length(); i < len; i++) { 51 char c = s.charAt(i); 52 if (c == '&') 53 buf.append("&"); 54 else if (c == '\"') 55 buf.append("""); 56 else if (c == '\'') 57 buf.append("'"); 58 else if (c == '<') 59 buf.append("<"); 60 else if (c == '>') 61 buf.append(">"); 62 else 63 buf.append(c); 64 } 65 return buf.toString(); 66 } 67 68 72 static String QuoteForId(String s) { 73 StringBuffer buf = new StringBuffer (); 74 75 for (int i = 0, len = s.length(); i < len; i++) { 76 char c = s.charAt(i); 77 if (c == '_') 78 buf.append("."); 79 else 80 buf.append(c); 81 } 82 return buf.toString(); 83 } 84 85 public void gen() { 86 try { 88 Enumeration grammarIter = behavior.grammars.elements(); 90 while (grammarIter.hasMoreElements()) { 91 Grammar g = (Grammar)grammarIter.nextElement(); 92 93 98 g.setCodeGenerator(this); 99 100 g.generate(); 102 103 if (antlrTool.hasError()) { 104 System.out.println("Exiting due to errors."); 105 System.exit(1); 106 } 107 108 } 109 110 } 111 catch (IOException e) { 112 System.out.println(e.getMessage()); 113 } 114 } 115 116 119 public void gen(ActionElement action) { 120 } 122 123 126 public void gen(AlternativeBlock blk) { 127 genGenericBlock(blk, ""); 128 } 129 130 135 public void gen(BlockEndElement end) { 136 } 138 139 142 public void gen(CharLiteralElement atom) { 143 if (atom.not) { 144 _print("~"); 145 } 146 _print(HTMLEncode(atom.atomText) + " "); 147 } 148 149 152 public void gen(CharRangeElement r) { 153 print(r.beginText + ".." + r.endText + " "); 154 } 155 156 157 public void gen(LexerGrammar g) throws IOException { 158 setGrammar(g); 159 System.out.println("Generating " + grammar.getClassName() + TokenTypesFileExt); 160 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + TokenTypesFileExt); 161 163 tabs = 0; 164 doingLexRules = true; 165 166 genHeader(); 168 169 173 println(""); 175 176 if (grammar.comment != null) { 178 _println(HTMLEncode(grammar.comment)); 179 } 180 181 println("<para>Definition of lexer " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".</para>"); 182 183 186 210 211 genNextToken(); 215 216 218 Enumeration ids = grammar.rules.elements(); 219 while (ids.hasMoreElements()) { 220 RuleSymbol rs = (RuleSymbol)ids.nextElement(); 221 if (!rs.id.equals("mnextToken")) { 222 genRule(rs); 223 } 224 } 225 226 currentOutput.close(); 228 currentOutput = null; 229 doingLexRules = false; 230 } 231 232 235 public void gen(OneOrMoreBlock blk) { 236 genGenericBlock(blk, "+"); 237 } 238 239 240 public void gen(ParserGrammar g) throws IOException { 241 setGrammar(g); 242 System.out.println("Generating " + grammar.getClassName() + ".sgml"); 244 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".sgml"); 245 246 tabs = 0; 247 248 genHeader(); 250 251 println(""); 253 254 if (grammar.comment != null) { 256 _println(HTMLEncode(grammar.comment)); 257 } 258 259 println("<para>Definition of parser " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".</para>"); 260 261 Enumeration rules = grammar.rules.elements(); 263 while (rules.hasMoreElements()) { 264 println(""); 265 GrammarSymbol sym = (GrammarSymbol)rules.nextElement(); 267 if (sym instanceof RuleSymbol) { 269 genRule((RuleSymbol)sym); 270 } 271 } 272 tabs--; 273 println(""); 274 275 genTail(); 276 277 currentOutput.close(); 279 currentOutput = null; 280 } 281 282 285 public void gen(RuleRefElement rr) { 286 RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule); 287 288 _print("<link linkend=\"" + QuoteForId(rr.targetRule) + "\">"); 290 _print(rr.targetRule); 291 _print("</link>"); 292 _print(" "); 297 } 298 299 302 public void gen(StringLiteralElement atom) { 303 if (atom.not) { 304 _print("~"); 305 } 306 _print(HTMLEncode(atom.atomText)); 307 _print(" "); 308 } 309 310 313 public void gen(TokenRangeElement r) { 314 print(r.beginText + ".." + r.endText + " "); 315 } 316 317 320 public void gen(TokenRefElement atom) { 321 if (atom.not) { 322 _print("~"); 323 } 324 _print(atom.atomText); 325 _print(" "); 326 } 327 328 public void gen(TreeElement t) { 329 print(t + " "); 330 } 331 332 333 public void gen(TreeWalkerGrammar g) throws IOException { 334 setGrammar(g); 335 System.out.println("Generating " + grammar.getClassName() + ".sgml"); 337 currentOutput = antlrTool.openOutputFile(grammar.getClassName() + ".sgml"); 338 340 tabs = 0; 341 342 genHeader(); 344 345 println(""); 347 354 println(""); 356 357 if (grammar.comment != null) { 359 _println(HTMLEncode(grammar.comment)); 360 } 361 362 println("<para>Definition of tree parser " + grammar.getClassName() + ", which is a subclass of " + grammar.getSuperClass() + ".</para>"); 363 364 373 println(""); 375 tabs++; 377 378 Enumeration rules = grammar.rules.elements(); 380 while (rules.hasMoreElements()) { 381 println(""); 382 GrammarSymbol sym = (GrammarSymbol)rules.nextElement(); 384 if (sym instanceof RuleSymbol) { 386 genRule((RuleSymbol)sym); 387 } 388 } 389 tabs--; 390 println(""); 391 393 396 currentOutput.close(); 398 currentOutput = null; 399 } 400 401 402 public void gen(WildcardElement wc) { 403 408 _print(". "); 409 } 410 411 414 public void gen(ZeroOrMoreBlock blk) { 415 genGenericBlock(blk, "*"); 416 } 417 418 protected void genAlt(Alternative alt) { 419 if (alt.getTreeSpecifier() != null) { 420 _print(alt.getTreeSpecifier().getText()); 421 } 422 prevAltElem = null; 423 for (AlternativeElement elem = alt.head; 424 !(elem instanceof BlockEndElement); 425 elem = elem.next) { 426 elem.generate(); 427 firstElementInAlt = false; 428 prevAltElem = elem; 429 } 430 } 431 436 448 public void genCommonBlock(AlternativeBlock blk) { 449 if (blk.alternatives.size() > 1) 450 println("<itemizedlist mark=\"none\">"); 451 for (int i = 0; i < blk.alternatives.size(); i++) { 452 Alternative alt = blk.getAlternativeAt(i); 453 AlternativeElement elem = alt.head; 454 455 if (blk.alternatives.size() > 1) 456 print("<listitem><para>"); 457 458 if (i > 0 && blk.alternatives.size() > 1) { 460 _print("| "); 461 } 462 463 boolean save = firstElementInAlt; 466 firstElementInAlt = true; 467 tabs++; 469 genAlt(alt); 470 tabs--; 471 firstElementInAlt = save; 472 if (blk.alternatives.size() > 1) 473 _println("</para></listitem>"); 474 } 475 if (blk.alternatives.size() > 1) 476 println("</itemizedlist>"); 477 } 478 479 483 public void genFollowSetForRuleBlock(RuleBlock blk) { 484 Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1, blk.endNode); 485 printSet(grammar.maxk, 1, follow); 486 } 487 488 protected void genGenericBlock(AlternativeBlock blk, String blkOp) { 489 if (blk.alternatives.size() > 1) { 490 _println(""); 492 if (!firstElementInAlt) { 493 _println("("); 499 } 507 else { 508 _print("("); 509 } 510 } 511 else { 512 _print("( "); 513 } 514 genCommonBlock(blk); 517 if (blk.alternatives.size() > 1) { 518 _println(""); 519 print(")" + blkOp + " "); 520 if (!(blk.next instanceof BlockEndElement)) { 522 _println(""); 523 print(""); 524 } 525 } 526 else { 527 _print(")" + blkOp + " "); 528 } 529 } 530 531 532 protected void genHeader() { 533 println("<?xml version=\"1.0\" standalone=\"no\"?>"); 534 println("<!DOCTYPE book PUBLIC \"-//OASIS//DTD DocBook V3.1//EN\">"); 535 println("<book lang=\"en\">"); 536 println("<bookinfo>"); 537 println("<title>Grammar " + grammar.getClassName() + "</title>"); 538 println(" <author>"); 539 println(" <firstname></firstname>"); 540 println(" <othername></othername>"); 541 println(" <surname></surname>"); 542 println(" <affiliation>"); 543 println(" <address>"); 544 println(" <email></email>"); 545 println(" </address>"); 546 println(" </affiliation>"); 547 println(" </author>"); 548 println(" <othercredit>"); 549 println(" <contrib>"); 550 println(" Generated by <ulink url=\"http://www.ANTLR.org/\">ANTLR</ulink>" + antlrTool.version); 551 println(" from " + antlrTool.grammarFile); 552 println(" </contrib>"); 553 println(" </othercredit>"); 554 println(" <pubdate></pubdate>"); 555 println(" <abstract>"); 556 println(" <para>"); 557 println(" </para>"); 558 println(" </abstract>"); 559 println("</bookinfo>"); 560 println("<chapter>"); 561 println("<title></title>"); 562 } 563 564 565 protected void genLookaheadSetForAlt(Alternative alt) { 566 if (doingLexRules && alt.cache[1].containsEpsilon()) { 567 println("MATCHES ALL"); 568 return; 569 } 570 int depth = alt.lookaheadDepth; 571 if (depth == GrammarAnalyzer.NONDETERMINISTIC) { 572 depth = grammar.maxk; 575 } 576 for (int i = 1; i <= depth; i++) { 577 Lookahead lookahead = alt.cache[i]; 578 printSet(depth, i, lookahead); 579 } 580 } 581 582 586 public void genLookaheadSetForBlock(AlternativeBlock blk) { 587 int depth = 0; 589 for (int i = 0; i < blk.alternatives.size(); i++) { 590 Alternative alt = blk.getAlternativeAt(i); 591 if (alt.lookaheadDepth == GrammarAnalyzer.NONDETERMINISTIC) { 592 depth = grammar.maxk; 593 break; 594 } 595 else if (depth < alt.lookaheadDepth) { 596 depth = alt.lookaheadDepth; 597 } 598 } 599 600 for (int i = 1; i <= depth; i++) { 601 Lookahead lookahead = grammar.theLLkAnalyzer.look(i, blk); 602 printSet(depth, i, lookahead); 603 } 604 } 605 606 610 public void genNextToken() { 611 println(""); 612 println("/** Lexer nextToken rule:"); 613 println(" * The lexer nextToken rule is synthesized from all of the user-defined"); 614 println(" * lexer rules. It logically consists of one big alternative block with"); 615 println(" * each user-defined rule being an alternative."); 616 println(" */"); 617 618 RuleBlock blk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken"); 621 622 RuleSymbol nextTokenRs = new RuleSymbol("mnextToken"); 624 nextTokenRs.setDefined(); 625 nextTokenRs.setBlock(blk); 626 nextTokenRs.access = "private"; 627 grammar.define(nextTokenRs); 628 629 639 640 genCommonBlock(blk); 641 } 642 643 646 public void genRule(RuleSymbol s) { 647 if (s == null || !s.isDefined()) return; println(""); 649 650 if (s.access.length() != 0) { 651 if (!s.access.equals("public")) { 652 _print("<para>" + s.access + " </para>"); 653 } 654 } 655 656 println("<section id=\"" + QuoteForId(s.getId()) + "\">"); 657 println("<title>" + s.getId() + "</title>"); 658 if (s.comment != null) { 659 _println("<para>" + HTMLEncode(s.comment) + "</para>"); 660 } 661 println("<para>"); 662 663 RuleBlock rblk = s.getBlock(); 665 666 _println(""); 677 print(s.getId() + ":\t"); 678 tabs++; 679 680 683 genCommonBlock(rblk); 685 686 _println(""); 687 tabs--; 689 _println("</para>"); 690 _println("</section><!-- section \"" + s.getId() + "\" -->"); 691 } 692 693 697 protected void genSynPred(SynPredBlock blk) { 698 } 700 701 public void genTail() { 702 println("</chapter>"); 703 println("</book>"); 704 } 705 706 707 protected void genTokenTypes(TokenManager tm) throws IOException { 708 System.out.println("Generating " + tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt); 710 currentOutput = antlrTool.openOutputFile(tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt); 711 tabs = 0; 713 714 genHeader(); 716 717 println(""); 720 println("*** Tokens used by the parser"); 721 println("This is a list of the token numeric values and the corresponding"); 722 println("token identifiers. Some tokens are literals, and because of that"); 723 println("they have no identifiers. Literals are double-quoted."); 724 tabs++; 725 726 Vector v = tm.getVocabulary(); 728 for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) { 729 String s = (String )v.elementAt(i); 730 if (s != null) { 731 println(s + " = " + i); 732 } 733 } 734 735 tabs--; 737 println("*** End of tokens used by the parser"); 738 739 currentOutput.close(); 741 currentOutput = null; 742 } 743 744 protected String processActionForTreeSpecifiers(String actionStr, 746 int line, 747 RuleBlock currentRule, 748 ActionTransInfo tInfo) { 749 return actionStr; 750 } 751 752 755 public String getASTCreateString(Vector v) { 756 return null; 757 } 758 759 762 public String getASTCreateString(GrammarAtom atom, String str) { 763 return null; 764 } 765 766 772 public String mapTreeId(String id, ActionTransInfo tInfo) { 773 return id; 774 } 775 776 781 public void printSet(int depth, int k, Lookahead lookahead) { 782 int numCols = 5; 783 784 int[] elems = lookahead.fset.toArray(); 785 786 if (depth != 1) { 787 print("k==" + k + ": {"); 788 } 789 else { 790 print("{ "); 791 } 792 if (elems.length > numCols) { 793 _println(""); 794 tabs++; 795 print(""); 796 } 797 798 int column = 0; 799 for (int i = 0; i < elems.length; i++) { 800 column++; 801 if (column > numCols) { 802 _println(""); 803 print(""); 804 column = 0; 805 } 806 if (doingLexRules) { 807 _print(charFormatter.literalChar(elems[i])); 808 } 809 else { 810 _print((String )grammar.tokenManager.getVocabulary().elementAt(elems[i])); 811 } 812 if (i != elems.length - 1) { 813 _print(", "); 814 } 815 } 816 817 if (elems.length > numCols) { 818 _println(""); 819 tabs--; 820 print(""); 821 } 822 _println(" }"); 823 } 824 } 825 | Popular Tags |