1 package persistence.antlr; 2 3 8 9 import java.io.PrintWriter ; 10 import java.io.IOException ; 11 import java.io.FileWriter ; 12 13 import persistence.antlr.collections.impl.Vector; 14 import persistence.antlr.collections.impl.BitSet; 15 16 49 public abstract class CodeGenerator { 50 protected persistence.antlr.Tool antlrTool; 51 52 53 protected int tabs = 0; 54 55 56 transient protected PrintWriter currentOutput; 58 59 protected Grammar grammar = null; 60 61 62 protected Vector bitsetsUsed; 63 64 65 protected DefineGrammarSymbols behavior; 66 67 68 protected LLkGrammarAnalyzer analyzer; 69 70 73 protected CharFormatter charFormatter; 74 75 76 protected boolean DEBUG_CODE_GENERATOR = false; 77 78 79 protected static final int DEFAULT_MAKE_SWITCH_THRESHOLD = 2; 80 protected static final int DEFAULT_BITSET_TEST_THRESHOLD = 4; 81 82 85 protected static final int BITSET_OPTIMIZE_INIT_THRESHOLD = 8; 86 87 93 protected int makeSwitchThreshold = DEFAULT_MAKE_SWITCH_THRESHOLD; 94 95 101 protected int bitsetTestThreshold = DEFAULT_BITSET_TEST_THRESHOLD; 102 103 private static boolean OLD_ACTION_TRANSLATOR = true; 104 105 public static String TokenTypesFileSuffix = "TokenTypes"; 106 public static String TokenTypesFileExt = ".txt"; 107 108 109 public CodeGenerator() { 110 } 111 112 116 protected void _print(String s) { 117 if (s != null) { 118 currentOutput.print(s); 119 } 120 } 121 122 127 protected void _printAction(String s) { 128 if (s == null) { 129 return; 130 } 131 132 int start = 0; 134 while (start < s.length() && Character.isSpaceChar(s.charAt(start))) { 135 start++; 136 } 137 138 int end = s.length() - 1; 140 while (end > start && Character.isSpaceChar(s.charAt(end))) { 141 end--; 142 } 143 144 char c = 0; 145 for (int i = start; i <= end;) { 146 c = s.charAt(i); 147 i++; 148 boolean newline = false; 149 switch (c) { 150 case '\n': 151 newline = true; 152 break; 153 case '\r': 154 if (i <= end && s.charAt(i) == '\n') { 155 i++; 156 } 157 newline = true; 158 break; 159 default: 160 currentOutput.print(c); 161 break; 162 } 163 if (newline) { 164 currentOutput.println(); 165 printTabs(); 166 while (i <= end && Character.isSpaceChar(s.charAt(i))) { 168 i++; 169 } 170 newline = false; 171 } 172 } 173 currentOutput.println(); 174 } 175 176 180 protected void _println(String s) { 181 if (s != null) { 182 currentOutput.println(s); 183 } 184 } 185 186 190 public static boolean elementsAreRange(int[] elems) { 191 if (elems.length == 0) { 192 return false; 193 } 194 int begin = elems[0]; 195 int end = elems[elems.length - 1]; 196 if (elems.length <= 2) { 197 return false; 199 } 200 if (end - begin + 1 > elems.length) { 201 return false; 203 } 204 int v = begin + 1; 205 for (int i = 1; i < elems.length - 1; i++) { 206 if (v != elems[i]) { 207 return false; 209 } 210 v++; 211 } 212 return true; 213 } 214 215 222 protected String extractIdOfAction(Token t) { 223 return extractIdOfAction(t.getText(), t.getLine(), t.getColumn()); 224 } 225 226 235 protected String extractIdOfAction(String s, int line, int column) { 236 s = removeAssignmentFromDeclaration(s); 237 for (int i = s.length() - 2; i >= 0; i--) { 240 if (!Character.isLetterOrDigit(s.charAt(i)) && s.charAt(i) != '_') { 242 return s.substring(i + 1); 244 } 245 } 246 antlrTool.warning("Ill-formed action", grammar.getFilename(), line, column); 249 return ""; 250 } 251 252 259 protected String extractTypeOfAction(Token t) { 260 return extractTypeOfAction(t.getText(), t.getLine(), t.getColumn()); 261 } 262 263 271 protected String extractTypeOfAction(String s, int line, int column) { 272 s = removeAssignmentFromDeclaration(s); 273 for (int i = s.length() - 2; i >= 0; i--) { 276 if (!Character.isLetterOrDigit(s.charAt(i)) && s.charAt(i) != '_') { 278 return s.substring(0, i + 1); 280 } 281 } 282 antlrTool.warning("Ill-formed action", grammar.getFilename(), line, column); 285 return ""; 286 } 287 288 290 public abstract void gen(); 291 292 295 public abstract void gen(ActionElement action); 296 297 300 public abstract void gen(AlternativeBlock blk); 301 302 307 public abstract void gen(BlockEndElement end); 308 309 312 public abstract void gen(CharLiteralElement atom); 313 314 317 public abstract void gen(CharRangeElement r); 318 319 320 public abstract void gen(LexerGrammar g) throws IOException ; 321 322 325 public abstract void gen(OneOrMoreBlock blk); 326 327 328 public abstract void gen(ParserGrammar g) throws IOException ; 329 330 333 public abstract void gen(RuleRefElement rr); 334 335 338 public abstract void gen(StringLiteralElement atom); 339 340 343 public abstract void gen(TokenRangeElement r); 344 345 348 public abstract void gen(TokenRefElement atom); 349 350 353 public abstract void gen(TreeElement t); 354 355 356 public abstract void gen(TreeWalkerGrammar g) throws IOException ; 357 358 361 public abstract void gen(WildcardElement wc); 362 363 366 public abstract void gen(ZeroOrMoreBlock blk); 367 368 369 protected void genTokenInterchange(TokenManager tm) throws IOException { 370 String fName = tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt; 372 currentOutput = antlrTool.openOutputFile(fName); 373 374 println("// $ANTLR " + antlrTool.version + ": " + 375 antlrTool.fileMinusPath(antlrTool.grammarFile) + 376 " -> " + 377 fName + 378 "$"); 379 380 tabs = 0; 381 382 println(tm.getName() + " // output token vocab name"); 384 385 Vector v = tm.getVocabulary(); 387 for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) { 388 String s = (String )v.elementAt(i); 389 if (DEBUG_CODE_GENERATOR) { 390 System.out.println("gen persistence file entry for: " + s); 391 } 392 if (s != null && !s.startsWith("<")) { 393 if (s.startsWith("\"")) { 395 StringLiteralSymbol sl = (StringLiteralSymbol)tm.getTokenSymbol(s); 396 if (sl != null && sl.label != null) { 397 print(sl.label + "="); 398 } 399 println(s + "=" + i); 400 } 401 else { 402 print(s); 403 TokenSymbol ts = (TokenSymbol)tm.getTokenSymbol(s); 405 if (ts == null) { 406 antlrTool.warning("undefined token symbol: " + s); 407 } 408 else { 409 if (ts.getParaphrase() != null) { 410 print("(" + ts.getParaphrase() + ")"); 411 } 412 } 413 println("=" + i); 414 } 415 } 416 } 417 418 currentOutput.close(); 420 currentOutput = null; 421 } 422 423 428 public String processStringForASTConstructor(String str) { 429 return str; 430 } 431 432 435 public abstract String getASTCreateString(Vector v); 436 437 440 public abstract String getASTCreateString(GrammarAtom atom, String str); 441 442 447 protected String getBitsetName(int index) { 448 return "_tokenSet_" + index; 449 } 450 451 public static String encodeLexerRuleName(String id) { 452 return "m" + id; 453 } 454 455 public static String decodeLexerRuleName(String id) { 456 if ( id==null ) { 457 return null; 458 } 459 return id.substring(1,id.length()); 460 } 461 462 469 public abstract String mapTreeId(String id, ActionTransInfo tInfo); 470 471 481 protected int markBitsetForGen(BitSet p) { 482 for (int i = 0; i < bitsetsUsed.size(); i++) { 484 BitSet set = (BitSet)bitsetsUsed.elementAt(i); 485 if (p.equals(set)) { 486 return i; 488 } 489 } 490 491 bitsetsUsed.appendElement(p.clone()); 493 return bitsetsUsed.size() - 1; 494 } 495 496 500 protected void print(String s) { 501 if (s != null) { 502 printTabs(); 503 currentOutput.print(s); 504 } 505 } 506 507 512 protected void printAction(String s) { 513 if (s != null) { 514 printTabs(); 515 _printAction(s); 516 } 517 } 518 519 523 protected void println(String s) { 524 if (s != null) { 525 printTabs(); 526 currentOutput.println(s); 527 } 528 } 529 530 533 protected void printTabs() { 534 for (int i = 1; i <= tabs; i++) { 535 currentOutput.print("\t"); 536 } 537 } 538 539 543 protected abstract String processActionForSpecialSymbols(String actionStr, 544 int line, 545 RuleBlock currentRule, 546 ActionTransInfo tInfo); 547 548 public String getFOLLOWBitSet(String ruleName, int k) { 549 GrammarSymbol rs = grammar.getSymbol(ruleName); 550 if ( !(rs instanceof RuleSymbol) ) { 551 return null; 552 } 553 RuleBlock blk = ((RuleSymbol)rs).getBlock(); 554 Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(k, blk.endNode); 555 String followSetName = getBitsetName(markBitsetForGen(follow.fset)); 556 return followSetName; 557 } 558 559 public String getFIRSTBitSet(String ruleName, int k) { 560 GrammarSymbol rs = grammar.getSymbol(ruleName); 561 if ( !(rs instanceof RuleSymbol) ) { 562 return null; 563 } 564 RuleBlock blk = ((RuleSymbol)rs).getBlock(); 565 Lookahead first = grammar.theLLkAnalyzer.look(k, blk); 566 String firstSetName = getBitsetName(markBitsetForGen(first.fset)); 567 return firstSetName; 568 } 569 570 575 protected String removeAssignmentFromDeclaration(String d) { 576 if (d.indexOf('=') >= 0) d = d.substring(0, d.indexOf('=')).trim(); 579 return d; 580 } 581 582 583 private void reset() { 584 tabs = 0; 585 bitsetsUsed = new Vector(); 587 currentOutput = null; 588 grammar = null; 589 DEBUG_CODE_GENERATOR = false; 590 makeSwitchThreshold = DEFAULT_MAKE_SWITCH_THRESHOLD; 591 bitsetTestThreshold = DEFAULT_BITSET_TEST_THRESHOLD; 592 } 593 594 public static String reverseLexerRuleName(String id) { 595 return id.substring(1, id.length()); 596 } 597 598 public void setAnalyzer(LLkGrammarAnalyzer analyzer_) { 599 analyzer = analyzer_; 600 } 601 602 public void setBehavior(DefineGrammarSymbols behavior_) { 603 behavior = behavior_; 604 } 605 606 607 protected void setGrammar(Grammar g) { 608 reset(); 609 grammar = g; 610 if (grammar.hasOption("codeGenMakeSwitchThreshold")) { 612 try { 613 makeSwitchThreshold = grammar.getIntegerOption("codeGenMakeSwitchThreshold"); 614 } 616 catch (NumberFormatException e) { 617 Token tok = grammar.getOption("codeGenMakeSwitchThreshold"); 618 antlrTool.error( 619 "option 'codeGenMakeSwitchThreshold' must be an integer", 620 grammar.getClassName(), 621 tok.getLine(), tok.getColumn() 622 ); 623 } 624 } 625 626 if (grammar.hasOption("codeGenBitsetTestThreshold")) { 628 try { 629 bitsetTestThreshold = grammar.getIntegerOption("codeGenBitsetTestThreshold"); 630 } 632 catch (NumberFormatException e) { 633 Token tok = grammar.getOption("codeGenBitsetTestThreshold"); 634 antlrTool.error( 635 "option 'codeGenBitsetTestThreshold' must be an integer", 636 grammar.getClassName(), 637 tok.getLine(), tok.getColumn() 638 ); 639 } 640 } 641 642 if (grammar.hasOption("codeGenDebug")) { 644 Token t = grammar.getOption("codeGenDebug"); 645 if (t.getText().equals("true")) { 646 DEBUG_CODE_GENERATOR = true; 648 } 649 else if (t.getText().equals("false")) { 650 DEBUG_CODE_GENERATOR = false; 652 } 653 else { 654 antlrTool.error("option 'codeGenDebug' must be true or false", grammar.getClassName(), t.getLine(), t.getColumn()); 655 } 656 } 657 } 658 659 public void setTool(Tool tool) { 660 antlrTool = tool; 661 } 662 } 663 | Popular Tags |