1 package antlr; 2 3 9 10 import java.io.PrintWriter ; 11 import java.io.IOException ; 12 import java.io.FileWriter ; 13 14 import antlr.collections.impl.Vector; 15 import antlr.collections.impl.BitSet; 16 17 50 public abstract class CodeGenerator { 51 protected antlr.Tool antlrTool; 52 53 54 protected int tabs = 0; 55 56 57 transient protected PrintWriter currentOutput; 59 60 protected Grammar grammar = null; 61 62 63 protected Vector bitsetsUsed; 64 65 66 protected DefineGrammarSymbols behavior; 67 68 69 protected LLkGrammarAnalyzer analyzer; 70 71 74 protected CharFormatter charFormatter; 75 76 77 protected boolean DEBUG_CODE_GENERATOR = false; 78 79 80 protected static final int DEFAULT_MAKE_SWITCH_THRESHOLD = 2; 81 protected static final int DEFAULT_BITSET_TEST_THRESHOLD = 4; 82 83 86 protected static final int BITSET_OPTIMIZE_INIT_THRESHOLD = 8; 87 88 94 protected int makeSwitchThreshold = DEFAULT_MAKE_SWITCH_THRESHOLD; 95 96 102 protected int bitsetTestThreshold = DEFAULT_BITSET_TEST_THRESHOLD; 103 104 private static boolean OLD_ACTION_TRANSLATOR = true; 105 106 public static String TokenTypesFileSuffix = "TokenTypes"; 107 public static String TokenTypesFileExt = ".txt"; 108 109 110 public CodeGenerator() { 111 } 112 113 117 protected void _print(String s) { 118 if (s != null) { 119 currentOutput.print(s); 120 } 121 } 122 123 128 protected void _printAction(String s) { 129 if (s == null) { 130 return; 131 } 132 133 int start = 0; 135 while (start < s.length() && Character.isSpaceChar(s.charAt(start))) { 136 start++; 137 } 138 139 int end = s.length() - 1; 141 while (end > start && Character.isSpaceChar(s.charAt(end))) { 142 end--; 143 } 144 145 char c = 0; 146 for (int i = start; i <= end;) { 147 c = s.charAt(i); 148 i++; 149 boolean newline = false; 150 switch (c) { 151 case '\n': 152 newline = true; 153 break; 154 case '\r': 155 if (i <= end && s.charAt(i) == '\n') { 156 i++; 157 } 158 newline = true; 159 break; 160 default: 161 currentOutput.print(c); 162 break; 163 } 164 if (newline) { 165 currentOutput.println(); 166 printTabs(); 167 while (i <= end && Character.isSpaceChar(s.charAt(i))) { 169 i++; 170 } 171 newline = false; 172 } 173 } 174 currentOutput.println(); 175 } 176 177 181 protected void _println(String s) { 182 if (s != null) { 183 currentOutput.println(s); 184 } 185 } 186 187 191 public static boolean elementsAreRange(int[] elems) { 192 if (elems.length == 0) { 193 return false; 194 } 195 int begin = elems[0]; 196 int end = elems[elems.length - 1]; 197 if (elems.length <= 2) { 198 return false; 200 } 201 if (end - begin + 1 > elems.length) { 202 return false; 204 } 205 int v = begin + 1; 206 for (int i = 1; i < elems.length - 1; i++) { 207 if (v != elems[i]) { 208 return false; 210 } 211 v++; 212 } 213 return true; 214 } 215 216 223 protected String extractIdOfAction(Token t) { 224 return extractIdOfAction(t.getText(), t.getLine(), t.getColumn()); 225 } 226 227 236 protected String extractIdOfAction(String s, int line, int column) { 237 s = removeAssignmentFromDeclaration(s); 238 for (int i = s.length() - 2; i >= 0; i--) { 241 if (!Character.isLetterOrDigit(s.charAt(i)) && s.charAt(i) != '_') { 243 return s.substring(i + 1); 245 } 246 } 247 antlrTool.warning("Ill-formed action", grammar.getFilename(), line, column); 250 return ""; 251 } 252 253 260 protected String extractTypeOfAction(Token t) { 261 return extractTypeOfAction(t.getText(), t.getLine(), t.getColumn()); 262 } 263 264 272 protected String extractTypeOfAction(String s, int line, int column) { 273 s = removeAssignmentFromDeclaration(s); 274 for (int i = s.length() - 2; i >= 0; i--) { 277 if (!Character.isLetterOrDigit(s.charAt(i)) && s.charAt(i) != '_') { 279 return s.substring(0, i + 1); 281 } 282 } 283 antlrTool.warning("Ill-formed action", grammar.getFilename(), line, column); 286 return ""; 287 } 288 289 291 public abstract void gen(); 292 293 296 public abstract void gen(ActionElement action); 297 298 301 public abstract void gen(AlternativeBlock blk); 302 303 308 public abstract void gen(BlockEndElement end); 309 310 313 public abstract void gen(CharLiteralElement atom); 314 315 318 public abstract void gen(CharRangeElement r); 319 320 321 public abstract void gen(LexerGrammar g) throws IOException ; 322 323 326 public abstract void gen(OneOrMoreBlock blk); 327 328 329 public abstract void gen(ParserGrammar g) throws IOException ; 330 331 334 public abstract void gen(RuleRefElement rr); 335 336 339 public abstract void gen(StringLiteralElement atom); 340 341 344 public abstract void gen(TokenRangeElement r); 345 346 349 public abstract void gen(TokenRefElement atom); 350 351 354 public abstract void gen(TreeElement t); 355 356 357 public abstract void gen(TreeWalkerGrammar g) throws IOException ; 358 359 362 public abstract void gen(WildcardElement wc); 363 364 367 public abstract void gen(ZeroOrMoreBlock blk); 368 369 370 protected void genTokenInterchange(TokenManager tm) throws IOException { 371 String fName = tm.getName() + TokenTypesFileSuffix + TokenTypesFileExt; 373 currentOutput = antlrTool.openOutputFile(fName); 374 375 println("// $ANTLR " + antlrTool.version + ": " + 376 antlrTool.fileMinusPath(antlrTool.grammarFile) + 377 " -> " + 378 fName + 379 "$"); 380 381 tabs = 0; 382 383 println(tm.getName() + " // output token vocab name"); 385 386 Vector v = tm.getVocabulary(); 388 for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) { 389 String s = (String )v.elementAt(i); 390 if (DEBUG_CODE_GENERATOR) { 391 System.out.println("gen persistence file entry for: " + s); 392 } 393 if (s != null && !s.startsWith("<")) { 394 if (s.startsWith("\"")) { 396 StringLiteralSymbol sl = (StringLiteralSymbol)tm.getTokenSymbol(s); 397 if (sl != null && sl.label != null) { 398 print(sl.label + "="); 399 } 400 println(s + "=" + i); 401 } 402 else { 403 print(s); 404 TokenSymbol ts = (TokenSymbol)tm.getTokenSymbol(s); 406 if (ts == null) { 407 antlrTool.warning("undefined token symbol: " + s); 408 } 409 else { 410 if (ts.getParaphrase() != null) { 411 print("(" + ts.getParaphrase() + ")"); 412 } 413 } 414 println("=" + i); 415 } 416 } 417 } 418 419 currentOutput.close(); 421 currentOutput = null; 422 } 423 424 429 public String processStringForASTConstructor(String str) { 430 return str; 431 } 432 433 436 public abstract String getASTCreateString(Vector v); 437 438 441 public abstract String getASTCreateString(GrammarAtom atom, String str); 442 443 448 protected String getBitsetName(int index) { 449 return "_tokenSet_" + index; 450 } 451 452 public static String encodeLexerRuleName(String id) { 453 return "m" + id; 454 } 455 456 public static String decodeLexerRuleName(String id) { 457 if ( id==null ) { 458 return null; 459 } 460 return id.substring(1,id.length()); 461 } 462 463 470 public abstract String mapTreeId(String id, ActionTransInfo tInfo); 471 472 482 protected int markBitsetForGen(BitSet p) { 483 for (int i = 0; i < bitsetsUsed.size(); i++) { 485 BitSet set = (BitSet)bitsetsUsed.elementAt(i); 486 if (p.equals(set)) { 487 return i; 489 } 490 } 491 492 bitsetsUsed.appendElement(p.clone()); 494 return bitsetsUsed.size() - 1; 495 } 496 497 501 protected void print(String s) { 502 if (s != null) { 503 printTabs(); 504 currentOutput.print(s); 505 } 506 } 507 508 513 protected void printAction(String s) { 514 if (s != null) { 515 printTabs(); 516 _printAction(s); 517 } 518 } 519 520 524 protected void println(String s) { 525 if (s != null) { 526 printTabs(); 527 currentOutput.println(s); 528 } 529 } 530 531 534 protected void printTabs() { 535 for (int i = 1; i <= tabs; i++) { 536 currentOutput.print("\t"); 537 } 538 } 539 540 544 protected abstract String processActionForTreeSpecifiers(String actionStr, int line, RuleBlock currentRule, ActionTransInfo tInfo); 545 546 551 protected String removeAssignmentFromDeclaration(String d) { 552 if (d.indexOf('=') >= 0) d = d.substring(0, d.indexOf('=')).trim(); 555 return d; 556 } 557 558 559 private void reset() { 560 tabs = 0; 561 bitsetsUsed = new Vector(); 563 currentOutput = null; 564 grammar = null; 565 DEBUG_CODE_GENERATOR = false; 566 makeSwitchThreshold = DEFAULT_MAKE_SWITCH_THRESHOLD; 567 bitsetTestThreshold = DEFAULT_BITSET_TEST_THRESHOLD; 568 } 569 570 public static String reverseLexerRuleName(String id) { 571 return id.substring(1, id.length()); 572 } 573 574 public void setAnalyzer(LLkGrammarAnalyzer analyzer_) { 575 analyzer = analyzer_; 576 } 577 578 public void setBehavior(DefineGrammarSymbols behavior_) { 579 behavior = behavior_; 580 } 581 582 583 protected void setGrammar(Grammar g) { 584 reset(); 585 grammar = g; 586 if (grammar.hasOption("codeGenMakeSwitchThreshold")) { 588 try { 589 makeSwitchThreshold = grammar.getIntegerOption("codeGenMakeSwitchThreshold"); 590 } 592 catch (NumberFormatException e) { 593 Token tok = grammar.getOption("codeGenMakeSwitchThreshold"); 594 antlrTool.error( 595 "option 'codeGenMakeSwitchThreshold' must be an integer", 596 grammar.getClassName(), 597 tok.getLine(), tok.getColumn() 598 ); 599 } 600 } 601 602 if (grammar.hasOption("codeGenBitsetTestThreshold")) { 604 try { 605 bitsetTestThreshold = grammar.getIntegerOption("codeGenBitsetTestThreshold"); 606 } 608 catch (NumberFormatException e) { 609 Token tok = grammar.getOption("codeGenBitsetTestThreshold"); 610 antlrTool.error( 611 "option 'codeGenBitsetTestThreshold' must be an integer", 612 grammar.getClassName(), 613 tok.getLine(), tok.getColumn() 614 ); 615 } 616 } 617 618 if (grammar.hasOption("codeGenDebug")) { 620 Token t = grammar.getOption("codeGenDebug"); 621 if (t.getText().equals("true")) { 622 DEBUG_CODE_GENERATOR = true; 624 } 625 else if (t.getText().equals("false")) { 626 DEBUG_CODE_GENERATOR = false; 628 } 629 else { 630 antlrTool.error("option 'codeGenDebug' must be true or false", grammar.getClassName(), t.getLine(), t.getColumn()); 631 } 632 } 633 } 634 635 public void setTool(Tool tool) { 636 antlrTool = tool; 637 } 638 } 639 | Popular Tags |