1 20 21 package JFlex; 22 23 import java.io.*; 24 import java.util.*; 25 import java.text.*; 26 27 36 final public class Emitter { 37 38 static final private int FINAL = 1; 40 static final private int PUSHBACK = 2; 41 static final private int LOOKEND = 4; 42 static final private int NOLOOK = 8; 43 44 static final private String date = (new SimpleDateFormat()).format(new Date()); 45 46 private File inputFile; 47 48 private PrintWriter out; 49 private Skeleton skel; 50 private LexScan scanner; 51 private LexParse parser; 52 private DFA dfa; 53 54 private CharSet table[][]; 57 58 private boolean isTransition[]; 59 60 private CharSet noTarget[]; 62 63 private int numRows; 65 private int [] rowMap; 66 private boolean [] rowKilled; 67 68 private int numCols; 70 private int [] colMap; 71 private boolean [] colKilled; 72 73 74 75 private Hashtable actionTable = new Hashtable(); 76 77 private CharClassInterval [] intervalls; 78 79 private String visibility = "public"; 80 81 public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException { 82 83 String name = parser.scanner.className+".java"; 84 85 File outputFile = normalize(name, inputFile); 86 87 Out.println("Writing code to \""+outputFile+"\""); 88 89 this.out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); 90 this.parser = parser; 91 this.scanner = parser.scanner; 92 this.visibility = scanner.visibility; 93 this.inputFile = inputFile; 94 this.dfa = dfa; 95 this.skel = new Skeleton(out); 96 } 97 98 99 108 public static File normalize(String name, File input) { 109 File outputFile; 110 111 if ( Options.getDir() == null ) 112 if ( input == null || input.getParent() == null ) 113 outputFile = new File(name); 114 else 115 outputFile = new File(input.getParent(), name); 116 else 117 outputFile = new File(Options.getDir(), name); 118 119 if ( outputFile.exists() && !Options.no_backup ) { 120 File backup = new File( outputFile.toString()+"~" ); 121 122 if ( backup.exists() ) backup.delete(); 123 124 if ( outputFile.renameTo( backup ) ) 125 Out.println("Old file \""+outputFile+"\" saved as \""+backup+"\""); 126 else 127 Out.println("Couldn't save old file \""+outputFile+"\", overwriting!"); 128 } 129 130 return outputFile; 131 } 132 133 private void println() { 134 out.println(); 135 } 136 137 private void println(String line) { 138 out.println(line); 139 } 140 141 private void println(int i) { 142 out.println(i); 143 } 144 145 private void print(String line) { 146 out.print(line); 147 } 148 149 private void print(int i) { 150 out.print(i); 151 } 152 153 private void print(int i, int tab) { 154 int exp; 155 156 if (i < 0) 157 exp = 1; 158 else 159 exp = 10; 160 161 while (tab-- > 1) { 162 if (Math.abs(i) < exp) print(" "); 163 exp*= 10; 164 } 165 166 print(i); 167 } 168 169 private void emitScanError() { 170 print(" private void zzScanError(int errorCode)"); 171 172 if (scanner.scanErrorException != null) 173 print(" throws "+scanner.scanErrorException); 174 175 println(" {"); 176 177 skel.emitNext(); 178 179 if (scanner.scanErrorException == null) 180 println(" throw new Error(message);"); 181 else 182 println(" throw new "+scanner.scanErrorException+"(message);"); 183 184 skel.emitNext(); 185 186 print(" "+visibility+" void yypushback(int number) "); 187 188 if (scanner.scanErrorException == null) 189 println(" {"); 190 else 191 println(" throws "+scanner.scanErrorException+" {"); 192 } 193 194 private void emitMain() { 195 if ( !(scanner.standalone || scanner.debugOption || scanner.cupDebug) ) return; 196 197 if ( scanner.cupDebug ) { 198 println(" /**"); 199 println(" * Converts an int token code into the name of the"); 200 println(" * token by reflection on the cup symbol class/interface "+scanner.cupSymbol); 201 println(" *"); 202 println(" * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); 203 println(" */"); 204 println(" private String getTokenName(int token) {"); 205 println(" try {"); 206 println(" java.lang.reflect.Field [] classFields = " + scanner.cupSymbol + ".class.getFields();"); 207 println(" for (int i = 0; i < classFields.length; i++) {"); 208 println(" if (classFields[i].getInt(null) == token) {"); 209 println(" return classFields[i].getName();"); 210 println(" }"); 211 println(" }"); 212 println(" } catch (Exception e) {"); 213 println(" e.printStackTrace(System.err);"); 214 println(" }"); 215 println(""); 216 println(" return \"UNKNOWN TOKEN\";"); 217 println(" }"); 218 println(""); 219 println(" /**"); 220 println(" * Same as "+scanner.functionName+" but also prints the token to standard out"); 221 println(" * for debugging."); 222 println(" *"); 223 println(" * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); 224 println(" */"); 225 226 print(" "+visibility+" "); 227 if ( scanner.tokenType == null ) { 228 if ( scanner.isInteger ) 229 print( "int" ); 230 else 231 if ( scanner.isIntWrap ) 232 print( "Integer" ); 233 else 234 print( "Yytoken" ); 235 } 236 else 237 print( scanner.tokenType ); 238 239 print(" debug_"); 240 241 print(scanner.functionName); 242 243 print("() throws java.io.IOException"); 244 245 if ( scanner.lexThrow != null ) { 246 print(", "); 247 print(scanner.lexThrow); 248 } 249 250 if ( scanner.scanErrorException != null ) { 251 print(", "); 252 print(scanner.scanErrorException); 253 } 254 255 println(" {"); 256 257 println(" java_cup.runtime.Symbol s = "+scanner.functionName+"();"); 258 print(" System.out.println( "); 259 if (scanner.lineCount) print("\"line:\" + (yyline+1) + "); 260 if (scanner.columnCount) print("\" col:\" + (yycolumn+1) + "); 261 println("\" --\"+ yytext() + \"--\" + getTokenName(s.sym) + \"--\");"); 262 println(" return s;"); 263 println(" }"); 264 println(""); 265 } 266 267 if ( scanner.standalone ) { 268 println(" /**"); 269 println(" * Runs the scanner on input files."); 270 println(" *"); 271 println(" * This is a standalone scanner, it will print any unmatched"); 272 println(" * text to System.out unchanged."); 273 println(" *"); 274 println(" * @param argv the command line, contains the filenames to run"); 275 println(" * the scanner on."); 276 println(" */"); 277 } 278 else { 279 println(" /**"); 280 println(" * Runs the scanner on input files."); 281 println(" *"); 282 println(" * This main method is the debugging routine for the scanner."); 283 println(" * It prints debugging information about each returned token to"); 284 println(" * System.out until the end of file is reached, or an error occured."); 285 println(" *"); 286 println(" * @param argv the command line, contains the filenames to run"); 287 println(" * the scanner on."); 288 println(" */"); 289 } 290 291 println(" public static void main(String argv[]) {"); 292 println(" if (argv.length == 0) {"); 293 println(" System.out.println(\"Usage : java "+scanner.className+" <inputfile>\");"); 294 println(" }"); 295 println(" else {"); 296 println(" for (int i = 0; i < argv.length; i++) {"); 297 println(" "+scanner.className+" scanner = null;"); 298 println(" try {"); 299 println(" scanner = new "+scanner.className+"( new java.io.FileReader(argv[i]) );"); 300 301 if ( scanner.standalone ) { 302 println(" while ( !scanner.zzAtEOF ) scanner."+scanner.functionName+"();"); 303 } 304 else if (scanner.cupDebug ) { 305 println(" while ( !scanner.zzAtEOF ) scanner.debug_"+scanner.functionName+"();"); 306 } 307 else { 308 println(" do {"); 309 println(" System.out.println(scanner."+scanner.functionName+"());"); 310 println(" } while (!scanner.zzAtEOF);"); 311 println(""); 312 } 313 314 println(" }"); 315 println(" catch (java.io.FileNotFoundException e) {"); 316 println(" System.out.println(\"File not found : \\\"\"+argv[i]+\"\\\"\");"); 317 println(" }"); 318 println(" catch (java.io.IOException e) {"); 319 println(" System.out.println(\"IO error scanning file \\\"\"+argv[i]+\"\\\"\");"); 320 println(" System.out.println(e);"); 321 println(" }"); 322 println(" catch (Exception e) {"); 323 println(" System.out.println(\"Unexpected exception:\");"); 324 println(" e.printStackTrace();"); 325 println(" }"); 326 println(" }"); 327 println(" }"); 328 println(" }"); 329 println(""); 330 } 331 332 private void emitNoMatch() { 333 println(" zzScanError(ZZ_NO_MATCH);"); 334 } 335 336 private void emitNextInput() { 337 println(" if (zzCurrentPosL < zzEndReadL)"); 338 println(" zzInput = zzBufferL[zzCurrentPosL++];"); 339 println(" else if (zzAtEOF) {"); 340 println(" zzInput = YYEOF;"); 341 println(" break zzForAction;"); 342 println(" }"); 343 println(" else {"); 344 println(" // store back cached positions"); 345 println(" zzCurrentPos = zzCurrentPosL;"); 346 println(" zzMarkedPos = zzMarkedPosL;"); 347 if ( scanner.lookAheadUsed ) 348 println(" zzPushbackPos = zzPushbackPosL;"); 349 println(" boolean eof = zzRefill();"); 350 println(" // get translated positions and possibly new buffer"); 351 println(" zzCurrentPosL = zzCurrentPos;"); 352 println(" zzMarkedPosL = zzMarkedPos;"); 353 println(" zzBufferL = zzBuffer;"); 354 println(" zzEndReadL = zzEndRead;"); 355 if ( scanner.lookAheadUsed ) 356 println(" zzPushbackPosL = zzPushbackPos;"); 357 println(" if (eof) {"); 358 println(" zzInput = YYEOF;"); 359 println(" break zzForAction;"); 360 println(" }"); 361 println(" else {"); 362 println(" zzInput = zzBufferL[zzCurrentPosL++];"); 363 println(" }"); 364 println(" }"); 365 } 366 367 private void emitHeader() { 368 println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */"); 369 println(""); 370 } 371 372 private void emitUserCode() { 373 if ( scanner.userCode.length() > 0 ) 374 println(scanner.userCode.toString()); 375 } 376 377 private void emitClassName() { 378 if (!endsWithJavadoc(scanner.userCode)) { 379 String path = inputFile.toString(); 380 if (File.separatorChar != '/') { 382 path = path.replace(File.separatorChar, '/'); 383 } 384 385 println("/**"); 386 println(" * This class is a scanner generated by "); 387 println(" * <a HREF=\"http://www.jflex.de/\">JFlex</a> "+Main.version); 388 println(" * on "+date+" from the specification file"); 389 println(" * <tt>"+path+"</tt>"); 390 println(" */"); 391 } 392 393 if ( scanner.isPublic ) print("public "); 394 395 if ( scanner.isAbstract) print("abstract "); 396 397 if ( scanner.isFinal ) print("final "); 398 399 print("class "); 400 print(scanner.className); 401 402 if ( scanner.isExtending != null ) { 403 print(" extends "); 404 print(scanner.isExtending); 405 } 406 407 if ( scanner.isImplementing != null ) { 408 print(" implements "); 409 print(scanner.isImplementing); 410 } 411 412 println(" {"); 413 } 414 415 421 public static boolean endsWithJavadoc(StringBuffer usercode) { 422 String s = usercode.toString().trim(); 423 424 if (!s.endsWith("*/")) return false; 425 426 int i = s.lastIndexOf("/**"); 428 if (i < 0) return false; 429 430 return s.substring(i,s.length()-2).indexOf("*/") < 0; 432 } 433 434 435 private void emitLexicalStates() { 436 Enumeration stateNames = scanner.states.names(); 437 438 while ( stateNames.hasMoreElements() ) { 439 String name = (String ) stateNames.nextElement(); 440 441 int num = scanner.states.getNumber(name).intValue(); 442 443 if (scanner.bolUsed) 444 println(" "+visibility+" static final int "+name+" = "+2*num+";"); 445 else 446 println(" "+visibility+" static final int "+name+" = "+dfa.lexState[2*num]+";"); 447 } 448 449 if (scanner.bolUsed) { 450 println(""); 451 println(" /**"); 452 println(" * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l"); 453 println(" * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l"); 454 println(" * at the beginning of a line"); 455 println(" * l is of the form l = 2*k, k a non negative integer"); 456 println(" */"); 457 println(" private static final int ZZ_LEXSTATE[] = { "); 458 459 int i, j = 0; 460 print(" "); 461 462 for (i = 0; i < dfa.lexState.length-1; i++) { 463 print( dfa.lexState[i], 2 ); 464 465 print(", "); 466 467 if (++j >= 16) { 468 println(); 469 print(" "); 470 j = 0; 471 } 472 } 473 474 println( dfa.lexState[i] ); 475 println(" };"); 476 477 } 478 } 479 480 private void emitDynamicInit() { 481 int count = 0; 482 int value = dfa.table[0][0]; 483 484 println(" /** "); 485 println(" * The transition table of the DFA"); 486 println(" */"); 487 488 CountEmitter e = new CountEmitter("Trans"); 489 e.setValTranslation(+1); e.emitInit(); 491 492 for (int i = 0; i < dfa.numStates; i++) { 493 if ( !rowKilled[i] ) { 494 for (int c = 0; c < dfa.numInput; c++) { 495 if ( !colKilled[c] ) { 496 if (dfa.table[i][c] == value) { 497 count++; 498 } 499 else { 500 e.emit(count, value); 501 502 count = 1; 503 value = dfa.table[i][c]; 504 } 505 } 506 } 507 } 508 } 509 510 e.emit(count, value); 511 e.emitUnpack(); 512 513 println(e.toString()); 514 } 515 516 517 private void emitCharMapInitFunction() { 518 519 CharClasses cl = parser.getCharClasses(); 520 521 if ( cl.getMaxCharCode() < 256 ) return; 522 523 println(""); 524 println(" /** "); 525 println(" * Unpacks the compressed character translation table."); 526 println(" *"); 527 println(" * @param packed the packed character translation table"); 528 println(" * @return the unpacked character translation table"); 529 println(" */"); 530 println(" private static char [] zzUnpackCMap(String packed) {"); 531 println(" char [] map = new char[0x10000];"); 532 println(" int i = 0; /* index in packed string */"); 533 println(" int j = 0; /* index in unpacked array */"); 534 println(" while (i < "+2*intervalls.length+") {"); 535 println(" int count = packed.charAt(i++);"); 536 println(" char value = packed.charAt(i++);"); 537 println(" do map[j++] = value; while (--count > 0);"); 538 println(" }"); 539 println(" return map;"); 540 println(" }"); 541 } 542 543 private void emitZZTrans() { 544 545 int i,c; 546 int n = 0; 547 548 println(" /** "); 549 println(" * The transition table of the DFA"); 550 println(" */"); 551 println(" private static final int ZZ_TRANS [] = {"); 553 print(" "); 554 for (i = 0; i < dfa.numStates; i++) { 555 556 if ( !rowKilled[i] ) { 557 for (c = 0; c < dfa.numInput; c++) { 558 if ( !colKilled[c] ) { 559 if (n >= 10) { 560 println(); 561 print(" "); 562 n = 0; 563 } 564 print( dfa.table[i][c] ); 565 if (i != dfa.numStates-1 || c != dfa.numInput-1) 566 print( ", "); 567 n++; 568 } 569 } 570 } 571 } 572 573 println(); 574 println(" };"); 575 } 576 577 private void emitCharMapArrayUnPacked() { 578 579 CharClasses cl = parser.getCharClasses(); 580 intervalls = cl.getIntervalls(); 581 582 println(""); 583 println(" /** "); 584 println(" * Translates characters to character classes"); 585 println(" */"); 586 println(" private static final char [] ZZ_CMAP = {"); 587 588 int n = 0; print(" "); 590 591 int max = cl.getMaxCharCode(); 592 int i = 0; 593 while ( i < intervalls.length && intervalls[i].start <= max ) { 594 595 int end = Math.min(intervalls[i].end, max); 596 for (int c = intervalls[i].start; c <= end; c++) { 597 598 print(colMap[intervalls[i].charClass], 2); 599 600 if (c < max) { 601 print(", "); 602 if ( ++n >= 16 ) { 603 println(); 604 print(" "); 605 n = 0; 606 } 607 } 608 } 609 610 i++; 611 } 612 613 println(); 614 println(" };"); 615 println(); 616 } 617 618 private void emitCharMapArray() { 619 CharClasses cl = parser.getCharClasses(); 620 621 if ( cl.getMaxCharCode() < 256 ) { 622 emitCharMapArrayUnPacked(); 623 return; 624 } 625 626 628 intervalls = cl.getIntervalls(); 629 630 println(""); 631 println(" /** "); 632 println(" * Translates characters to character classes"); 633 println(" */"); 634 println(" private static final String ZZ_CMAP_PACKED = "); 635 636 int n = 0; print(" \""); 638 639 int i = 0; 640 while ( i < intervalls.length-1 ) { 641 int count = intervalls[i].end-intervalls[i].start+1; 642 int value = colMap[intervalls[i].charClass]; 643 644 printUC(count); 645 printUC(value); 646 647 if ( ++n >= 10 ) { 648 println("\"+"); 649 print(" \""); 650 n = 0; 651 } 652 653 i++; 654 } 655 656 printUC(intervalls[i].end-intervalls[i].start+1); 657 printUC(colMap[intervalls[i].charClass]); 658 659 println("\";"); 660 println(); 661 662 println(" /** "); 663 println(" * Translates characters to character classes"); 664 println(" */"); 665 println(" private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);"); 666 println(); 667 } 668 669 670 676 private void printUC(int c) { 677 if (c > 255) { 678 out.print("\\u"); 679 if (c < 0x1000) out.print("0"); 680 out.print(Integer.toHexString(c)); 681 } 682 else { 683 out.print("\\"); 684 out.print(Integer.toOctalString(c)); 685 } 686 } 687 688 689 private void emitRowMapArray() { 690 println(""); 691 println(" /** "); 692 println(" * Translates a state to a row index in the transition table"); 693 println(" */"); 694 695 HiLowEmitter e = new HiLowEmitter("RowMap"); 696 e.emitInit(); 697 for (int i = 0; i < dfa.numStates; i++) { 698 e.emit(rowMap[i]*numCols); 699 } 700 e.emitUnpack(); 701 println(e.toString()); 702 } 703 704 705 private void emitAttributes() { 706 println(" /**"); 707 println(" * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>"); 708 println(" */"); 709 710 CountEmitter e = new CountEmitter("Attribute"); 711 e.emitInit(); 712 713 int count = 1; 714 int value = 0; 715 if ( dfa.isFinal[0] ) value = FINAL; 716 if ( dfa.isPushback[0] ) value|= PUSHBACK; 717 if ( dfa.isLookEnd[0] ) value|= LOOKEND; 718 if ( !isTransition[0] ) value|= NOLOOK; 719 720 for (int i = 1; i < dfa.numStates; i++) { 721 int attribute = 0; 722 if ( dfa.isFinal[i] ) attribute = FINAL; 723 if ( dfa.isPushback[i] ) attribute|= PUSHBACK; 724 if ( dfa.isLookEnd[i] ) attribute|= LOOKEND; 725 if ( !isTransition[i] ) attribute|= NOLOOK; 726 727 if (value == attribute) { 728 count++; 729 } 730 else { 731 e.emit(count, value); 732 count = 1; 733 value = attribute; 734 } 735 } 736 737 e.emit(count, value); 738 e.emitUnpack(); 739 740 println(e.toString()); 741 } 742 743 744 private void emitClassCode() { 745 if ( scanner.eofCode != null ) { 746 println(" /** denotes if the user-EOF-code has already been executed */"); 747 println(" private boolean zzEOFDone;"); 748 println(""); 749 } 750 751 if ( scanner.classCode != null ) { 752 println(" /* user code: */"); 753 println(scanner.classCode); 754 } 755 } 756 757 private void emitConstructorDecl() { 758 759 print(" "); 760 761 if ( scanner.isPublic ) print("public "); 762 print( scanner.className ); 763 print("(java.io.Reader in)"); 764 765 if ( scanner.initThrow != null ) { 766 print(" throws "); 767 print( scanner.initThrow ); 768 } 769 770 println(" {"); 771 772 if ( scanner.initCode != null ) { 773 print(" "); 774 print( scanner.initCode ); 775 } 776 777 println(" this.zzReader = in;"); 778 779 println(" }"); 780 println(); 781 782 783 println(" /**"); 784 println(" * Creates a new scanner."); 785 println(" * There is also java.io.Reader version of this constructor."); 786 println(" *"); 787 println(" * @param in the java.io.Inputstream to read input from."); 788 println(" */"); 789 790 print(" "); 791 if ( scanner.isPublic ) print("public "); 792 print( scanner.className ); 793 print("(java.io.InputStream in)"); 794 795 if ( scanner.initThrow != null ) { 796 print(" throws "); 797 print( scanner.initThrow ); 798 } 799 800 println(" {"); 801 println(" this(new java.io.InputStreamReader(in));"); 802 println(" }"); 803 } 804 805 806 private void emitDoEOF() { 807 if ( scanner.eofCode == null ) return; 808 809 println(" /**"); 810 println(" * Contains user EOF-code, which will be executed exactly once,"); 811 println(" * when the end of file is reached"); 812 println(" */"); 813 814 print(" private void zzDoEOF()"); 815 816 if ( scanner.eofThrow != null ) { 817 print(" throws "); 818 print(scanner.eofThrow); 819 } 820 821 println(" {"); 822 823 println(" if (!zzEOFDone) {"); 824 println(" zzEOFDone = true;"); 825 println(" "+scanner.eofCode ); 826 println(" }"); 827 println(" }"); 828 println(""); 829 println(""); 830 } 831 832 private void emitLexFunctHeader() { 833 834 if (scanner.cupCompatible) { 835 print(" public "); 837 } 838 else { 839 print(" "+visibility+" "); 840 } 841 842 if ( scanner.tokenType == null ) { 843 if ( scanner.isInteger ) 844 print( "int" ); 845 else 846 if ( scanner.isIntWrap ) 847 print( "Integer" ); 848 else 849 print( "Yytoken" ); 850 } 851 else 852 print( scanner.tokenType ); 853 854 print(" "); 855 856 print(scanner.functionName); 857 858 print("() throws java.io.IOException"); 859 860 if ( scanner.lexThrow != null ) { 861 print(", "); 862 print(scanner.lexThrow); 863 } 864 865 if ( scanner.scanErrorException != null ) { 866 print(", "); 867 print(scanner.scanErrorException); 868 } 869 870 println(" {"); 871 872 skel.emitNext(); 873 874 if ( scanner.useRowMap ) { 875 println(" int [] zzTransL = ZZ_TRANS;"); 876 println(" int [] zzRowMapL = ZZ_ROWMAP;"); 877 println(" int [] zzAttrL = ZZ_ATTRIBUTE;"); 878 879 } 880 881 if ( scanner.lookAheadUsed ) { 882 println(" int zzPushbackPosL = zzPushbackPos = -1;"); 883 println(" boolean zzWasPushback;"); 884 } 885 886 skel.emitNext(); 887 888 if ( scanner.charCount ) { 889 println(" yychar+= zzMarkedPosL-zzStartRead;"); 890 println(""); 891 } 892 893 if ( scanner.lineCount || scanner.columnCount ) { 894 println(" boolean zzR = false;"); 895 println(" for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;"); 896 println(" zzCurrentPosL++) {"); 897 println(" switch (zzBufferL[zzCurrentPosL]) {"); 898 println(" case '\\u000B':"); 899 println(" case '\\u000C':"); 900 println(" case '\\u0085':"); 901 println(" case '\\u2028':"); 902 println(" case '\\u2029':"); 903 if ( scanner.lineCount ) 904 println(" yyline++;"); 905 if ( scanner.columnCount ) 906 println(" yycolumn = 0;"); 907 println(" zzR = false;"); 908 println(" break;"); 909 println(" case '\\r':"); 910 if ( scanner.lineCount ) 911 println(" yyline++;"); 912 if ( scanner.columnCount ) 913 println(" yycolumn = 0;"); 914 println(" zzR = true;"); 915 println(" break;"); 916 println(" case '\\n':"); 917 println(" if (zzR)"); 918 println(" zzR = false;"); 919 println(" else {"); 920 if ( scanner.lineCount ) 921 println(" yyline++;"); 922 if ( scanner.columnCount ) 923 println(" yycolumn = 0;"); 924 println(" }"); 925 println(" break;"); 926 println(" default:"); 927 println(" zzR = false;"); 928 if ( scanner.columnCount ) 929 println(" yycolumn++;"); 930 println(" }"); 931 println(" }"); 932 println(); 933 934 if ( scanner.lineCount ) { 935 println(" if (zzR) {"); 936 println(" // peek one character ahead if it is \\n (if we have counted one line too much)"); 937 println(" boolean zzPeek;"); 938 println(" if (zzMarkedPosL < zzEndReadL)"); 939 println(" zzPeek = zzBufferL[zzMarkedPosL] == '\\n';"); 940 println(" else if (zzAtEOF)"); 941 println(" zzPeek = false;"); 942 println(" else {"); 943 println(" boolean eof = zzRefill();"); 944 println(" zzEndReadL = zzEndRead;"); 945 println(" zzMarkedPosL = zzMarkedPos;"); 946 println(" zzBufferL = zzBuffer;"); 947 println(" if (eof) "); 948 println(" zzPeek = false;"); 949 println(" else "); 950 println(" zzPeek = zzBufferL[zzMarkedPosL] == '\\n';"); 951 println(" }"); 952 println(" if (zzPeek) yyline--;"); 953 println(" }"); 954 } 955 } 956 957 if ( scanner.bolUsed ) { 958 println(" if (zzMarkedPosL > zzStartRead) {"); 962 println(" switch (zzBufferL[zzMarkedPosL-1]) {"); 963 println(" case '\\n':"); 964 println(" case '\\u000B':"); 965 println(" case '\\u000C':"); 966 println(" case '\\u0085':"); 967 println(" case '\\u2028':"); 968 println(" case '\\u2029':"); 969 println(" zzAtBOL = true;"); 970 println(" break;"); 971 println(" case '\\r': "); 972 println(" if (zzMarkedPosL < zzEndReadL)"); 973 println(" zzAtBOL = zzBufferL[zzMarkedPosL] != '\\n';"); 974 println(" else if (zzAtEOF)"); 975 println(" zzAtBOL = false;"); 976 println(" else {"); 977 println(" boolean eof = zzRefill();"); 978 println(" zzMarkedPosL = zzMarkedPos;"); 979 println(" zzEndReadL = zzEndRead;"); 980 println(" zzBufferL = zzBuffer;"); 981 println(" if (eof) "); 982 println(" zzAtBOL = false;"); 983 println(" else "); 984 println(" zzAtBOL = zzBufferL[zzMarkedPosL] != '\\n';"); 985 println(" }"); 986 println(" break;"); 987 println(" default:"); 988 println(" zzAtBOL = false;"); 989 println(" }"); 990 println(" }"); 991 } 992 993 skel.emitNext(); 994 995 if (scanner.bolUsed) { 996 println(" if (zzAtBOL)"); 997 println(" zzState = ZZ_LEXSTATE[zzLexicalState+1];"); 998 println(" else"); 999 println(" zzState = ZZ_LEXSTATE[zzLexicalState];"); 1000 println(); 1001 } 1002 else { 1003 println(" zzState = zzLexicalState;"); 1004 println(); 1005 } 1006 1007 if (scanner.lookAheadUsed) 1008 println(" zzWasPushback = false;"); 1009 1010 skel.emitNext(); 1011 } 1012 1013 1014 private void emitGetRowMapNext() { 1015 println(" int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];"); 1016 println(" if (zzNext == "+DFA.NO_TARGET+") break zzForAction;"); 1017 println(" zzState = zzNext;"); 1018 println(); 1019 1020 println(" int zzAttributes = zzAttrL[zzState];"); 1021 1022 if ( scanner.lookAheadUsed ) { 1023 println(" if ( (zzAttributes & "+PUSHBACK+") == "+PUSHBACK+" )"); 1024 println(" zzPushbackPosL = zzCurrentPosL;"); 1025 println(); 1026 } 1027 1028 println(" if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {"); 1029 if ( scanner.lookAheadUsed ) 1030 println(" zzWasPushback = (zzAttributes & "+LOOKEND+") == "+LOOKEND+";"); 1031 1032 skel.emitNext(); 1033 1034 println(" if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;"); 1035 1036 skel.emitNext(); 1037 } 1038 1039 private void emitTransitionTable() { 1040 transformTransitionTable(); 1041 1042 println(" zzInput = zzCMapL[zzInput];"); 1043 println(); 1044 1045 if ( scanner.lookAheadUsed ) 1046 println(" boolean zzPushback = false;"); 1047 1048 println(" boolean zzIsFinal = false;"); 1049 println(" boolean zzNoLookAhead = false;"); 1050 println(); 1051 1052 println(" zzForNext: { switch (zzState) {"); 1053 1054 for (int state = 0; state < dfa.numStates; state++) 1055 if (isTransition[state]) emitState(state); 1056 1057 println(" default:"); 1058 println(" // if this is ever reached, there is a serious bug in JFlex"); 1059 println(" zzScanError(ZZ_UNKNOWN_ERROR);"); 1060 println(" break;"); 1061 println(" } }"); 1062 println(); 1063 1064 println(" if ( zzIsFinal ) {"); 1065 1066 if ( scanner.lookAheadUsed ) 1067 println(" zzWasPushback = zzPushback;"); 1068 1069 skel.emitNext(); 1070 1071 println(" if ( zzNoLookAhead ) break zzForAction;"); 1072 1073 skel.emitNext(); 1074 } 1075 1076 1077 1080 private String escapify(String s) { 1081 StringBuffer result = new StringBuffer (s.length()*2); 1082 1083 for (int i = 0; i < s.length(); i++) { 1084 char c = s.charAt(i); 1085 switch (c) { 1086 case '\'': result.append("\\\'"); break; 1087 case '\"': result.append("\\\""); break; 1088 case '\\': result.append("\\\\"); break; 1089 case '\t': result.append("\\t"); break; 1090 case '\r': if (i+1 == s.length() || s.charAt(i+1) != '\n') result.append("\"+ZZ_NL+\""); 1091 break; 1092 case '\n': result.append("\"+ZZ_NL+\""); break; 1093 default: result.append(c); 1094 } 1095 } 1096 1097 return result.toString(); 1098 } 1099 1100 public void emitActionTable() { 1101 int lastAction = 1; 1102 int count = 0; 1103 int value = 0; 1104 1105 println(" /** "); 1106 println(" * Translates DFA states to action switch labels."); 1107 println(" */"); 1108 CountEmitter e = new CountEmitter("Action"); 1109 e.emitInit(); 1110 1111 for (int i = 0; i < dfa.numStates; i++) { 1112 int newVal; 1113 if ( dfa.isFinal[i] ) { 1114 Action action = dfa.action[i]; 1115 Integer stored = (Integer ) actionTable.get(action); 1116 if ( stored == null ) { 1117 stored = new Integer (lastAction++); 1118 actionTable.put(action, stored); 1119 } 1120 newVal = stored.intValue(); 1121 } 1122 else { 1123 newVal = 0; 1124 } 1125 1126 if (value == newVal) { 1127 count++; 1128 } 1129 else { 1130 if (count > 0) e.emit(count,value); 1131 count = 1; 1132 value = newVal; 1133 } 1134 } 1135 1136 if (count > 0) e.emit(count,value); 1137 1138 e.emitUnpack(); 1139 println(e.toString()); 1140 } 1141 1142 private void emitActions() { 1143 println(" switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {"); 1144 1145 int i = actionTable.size()+1; 1146 Enumeration actions = actionTable.keys(); 1147 while ( actions.hasMoreElements() ) { 1148 Action action = (Action) actions.nextElement(); 1149 int label = ((Integer ) actionTable.get(action)).intValue(); 1150 1151 println(" case "+label+": "); 1152 1153 if ( scanner.debugOption ) { 1154 print(" System.out.println("); 1155 if ( scanner.lineCount ) 1156 print("\"line: \"+(yyline+1)+\" \"+"); 1157 if ( scanner.columnCount ) 1158 print("\"col: \"+(yycolumn+1)+\" \"+"); 1159 println("\"match: --\"+yytext()+\"--\");"); 1160 print(" System.out.println(\"action ["+action.priority+"] { "); 1161 print(escapify(action.content)); 1162 println(" }\");"); 1163 } 1164 1165 println(" { "+action.content); 1166 println(" }"); 1167 println(" case "+(i++)+": break;"); 1168 } 1169 } 1170 1171 private void emitEOFVal() { 1172 EOFActions eofActions = parser.getEOFActions(); 1173 1174 if ( scanner.eofCode != null ) 1175 println(" zzDoEOF();"); 1176 1177 if ( eofActions.numActions() > 0 ) { 1178 println(" switch (zzLexicalState) {"); 1179 1180 Enumeration stateNames = scanner.states.names(); 1181 1182 Hashtable used = new Hashtable(); 1184 1185 int last = dfa.numStates; 1188 1189 while ( stateNames.hasMoreElements() ) { 1190 String name = (String ) stateNames.nextElement(); 1191 int num = scanner.states.getNumber(name).intValue(); 1192 Action action = eofActions.getAction(num); 1193 1194 boolean unused = true; 1201 if (!scanner.bolUsed) { 1202 Integer key = new Integer (dfa.lexState[2*num]); 1203 unused = used.get(key) == null; 1204 1205 if (!unused) 1206 Out.warning("Lexical states <"+name+"> and <"+used.get(key)+"> are equivalent."); 1207 else 1208 used.put(key,name); 1209 } 1210 1211 if (action != null && unused) { 1212 println(" case "+name+": {"); 1213 if ( scanner.debugOption ) { 1214 print(" System.out.println("); 1215 if ( scanner.lineCount ) 1216 print("\"line: \"+(yyline+1)+\" \"+"); 1217 if ( scanner.columnCount ) 1218 print("\"col: \"+(yycolumn+1)+\" \"+"); 1219 println("\"match: <<EOF>>\");"); 1220 print(" System.out.println(\"action ["+action.priority+"] { "); 1221 print(escapify(action.content)); 1222 println(" }\");"); 1223 } 1224 println(" "+action.content); 1225 println(" }"); 1226 println(" case "+(++last)+": break;"); 1227 } 1228 } 1229 1230 println(" default:"); 1231 } 1232 1233 Action defaultAction = eofActions.getDefault(); 1234 1235 if (defaultAction != null) { 1236 println(" {"); 1237 if ( scanner.debugOption ) { 1238 print(" System.out.println("); 1239 if ( scanner.lineCount ) 1240 print("\"line: \"+(yyline+1)+\" \"+"); 1241 if ( scanner.columnCount ) 1242 print("\"col: \"+(yycolumn+1)+\" \"+"); 1243 println("\"match: <<EOF>>\");"); 1244 print(" System.out.println(\"action ["+defaultAction.priority+"] { "); 1245 print(escapify(defaultAction.content)); 1246 println(" }\");"); 1247 } 1248 println(" " + defaultAction.content); 1249 println(" }"); 1250 } 1251 else if ( scanner.eofVal != null ) 1252 println(" { " + scanner.eofVal + " }"); 1253 else if ( scanner.isInteger ) 1254 println(" return YYEOF;"); 1255 else 1256 println(" return null;"); 1257 1258 if (eofActions.numActions() > 0) 1259 println(" }"); 1260 } 1261 1262 private void emitState(int state) { 1263 1264 println(" case "+state+":"); 1265 println(" switch (zzInput) {"); 1266 1267 int defaultTransition = getDefaultTransition(state); 1268 1269 for (int next = 0; next < dfa.numStates; next++) { 1270 1271 if ( next != defaultTransition && table[state][next] != null ) { 1272 emitTransition(state, next); 1273 } 1274 } 1275 1276 if ( defaultTransition != DFA.NO_TARGET && noTarget[state] != null ) { 1277 emitTransition(state, DFA.NO_TARGET); 1278 } 1279 1280 emitDefaultTransition(state, defaultTransition); 1281 1282 println(" }"); 1283 println(""); 1284 } 1285 1286 private void emitTransition(int state, int nextState) { 1287 1288 CharSetEnumerator chars; 1289 1290 if (nextState != DFA.NO_TARGET) 1291 chars = table[state][nextState].characters(); 1292 else 1293 chars = noTarget[state].characters(); 1294 1295 print(" case "); 1296 print((int)chars.nextElement()); 1297 print(": "); 1298 1299 while ( chars.hasMoreElements() ) { 1300 println(); 1301 print(" case "); 1302 print((int)chars.nextElement()); 1303 print(": "); 1304 } 1305 1306 if ( nextState != DFA.NO_TARGET ) { 1307 if ( dfa.isFinal[nextState] ) 1308 print("zzIsFinal = true; "); 1309 1310 if ( dfa.isPushback[nextState] ) 1311 print("zzPushbackPosL = zzCurrentPosL; "); 1312 1313 if ( dfa.isLookEnd[nextState] ) 1314 print("zzPushback = true; "); 1315 1316 if ( !isTransition[nextState] ) 1317 print("zzNoLookAhead = true; "); 1318 1319 if ( nextState == state ) 1320 println("break zzForNext;"); 1321 else 1322 println("zzState = "+nextState+"; break zzForNext;"); 1323 } 1324 else 1325 println("break zzForAction;"); 1326 } 1327 1328 private void emitDefaultTransition(int state, int nextState) { 1329 print(" default: "); 1330 1331 if ( nextState != DFA.NO_TARGET ) { 1332 if ( dfa.isFinal[nextState] ) 1333 print("zzIsFinal = true; "); 1334 1335 if ( dfa.isPushback[nextState] ) 1336 print("zzPushbackPosL = zzCurrentPosL; "); 1337 1338 if ( dfa.isLookEnd[nextState] ) 1339 print("zzPushback = true; "); 1340 1341 if ( !isTransition[nextState] ) 1342 print("zzNoLookAhead = true; "); 1343 1344 if ( nextState == state ) 1345 println("break zzForNext;"); 1346 else 1347 println("zzState = "+nextState+"; break zzForNext;"); 1348 } 1349 else 1350 println( "break zzForAction;" ); 1351 } 1352 1353 private void emitPushback() { 1354 println(" if (zzWasPushback)"); 1355 println(" zzMarkedPos = zzPushbackPosL;"); 1356 } 1357 1358 private int getDefaultTransition(int state) { 1359 int max = 0; 1360 1361 for (int i = 0; i < dfa.numStates; i++) { 1362 if ( table[state][max] == null ) 1363 max = i; 1364 else 1365 if ( table[state][i] != null && table[state][max].size() < table[state][i].size() ) 1366 max = i; 1367 } 1368 1369 if ( table[state][max] == null ) return DFA.NO_TARGET; 1370 if ( noTarget[state] == null ) return max; 1371 1372 if ( table[state][max].size() < noTarget[state].size() ) 1373 max = DFA.NO_TARGET; 1374 1375 return max; 1376 } 1377 1378 private void transformTransitionTable() { 1380 1381 int numInput = parser.getCharClasses().getNumClasses()+1; 1382 1383 int i; 1384 char j; 1385 1386 table = new CharSet[dfa.numStates][dfa.numStates]; 1387 noTarget = new CharSet[dfa.numStates]; 1388 1389 for (i = 0; i < dfa.numStates; i++) 1390 for (j = 0; j < dfa.numInput; j++) { 1391 1392 int nextState = dfa.table[i][j]; 1393 1394 if ( nextState == DFA.NO_TARGET ) { 1395 if ( noTarget[i] == null ) 1396 noTarget[i] = new CharSet(numInput, colMap[j]); 1397 else 1398 noTarget[i].add(colMap[j]); 1399 } 1400 else { 1401 if ( table[i][nextState] == null ) 1402 table[i][nextState] = new CharSet(numInput, colMap[j]); 1403 else 1404 table[i][nextState].add(colMap[j]); 1405 } 1406 } 1407 } 1408 1409 private void findActionStates() { 1410 isTransition = new boolean [dfa.numStates]; 1411 1412 for (int i = 0; i < dfa.numStates; i++) { 1413 char j = 0; 1414 while ( !isTransition[i] && j < dfa.numInput ) 1415 isTransition[i] = dfa.table[i][j++] != DFA.NO_TARGET; 1416 } 1417 } 1418 1419 1420 private void reduceColumns() { 1421 colMap = new int [dfa.numInput]; 1422 colKilled = new boolean [dfa.numInput]; 1423 1424 int i,j,k; 1425 int translate = 0; 1426 boolean equal; 1427 1428 numCols = dfa.numInput; 1429 1430 for (i = 0; i < dfa.numInput; i++) { 1431 1432 colMap[i] = i-translate; 1433 1434 for (j = 0; j < i; j++) { 1435 1436 k = -1; 1438 equal = true; 1439 while (equal && ++k < dfa.numStates) 1440 equal = dfa.table[k][i] == dfa.table[k][j]; 1441 1442 if (equal) { 1443 translate++; 1444 colMap[i] = colMap[j]; 1445 colKilled[i] = true; 1446 numCols--; 1447 break; 1448 } } } } 1452 1453 private void reduceRows() { 1454 rowMap = new int [dfa.numStates]; 1455 rowKilled = new boolean [dfa.numStates]; 1456 1457 int i,j,k; 1458 int translate = 0; 1459 boolean equal; 1460 1461 numRows = dfa.numStates; 1462 1463 for (i = 0; i < dfa.numStates; i++) { 1465 1466 rowMap[i] = i-translate; 1467 1468 for (j = 0; j < i; j++) { 1471 1472 k = -1; 1474 equal = true; 1475 while (equal && ++k < dfa.numInput) 1476 equal = dfa.table[i][k] == dfa.table[j][k]; 1477 1478 if (equal) { 1479 translate++; 1480 rowMap[i] = rowMap[j]; 1481 rowKilled[i] = true; 1482 numRows--; 1483 break; 1484 } } } 1488 } 1489 1490 1491 1494 private void setupEOFCode() { 1495 if (scanner.eofclose) { 1496 scanner.eofCode = LexScan.conc(scanner.eofCode, " yyclose();"); 1497 scanner.eofThrow = LexScan.concExc(scanner.eofThrow, "java.io.IOException"); 1498 } 1499 } 1500 1501 1502 1505 public void emit() { 1506 1507 setupEOFCode(); 1508 1509 if (scanner.functionName == null) 1510 scanner.functionName = "yylex"; 1511 1512 reduceColumns(); 1513 findActionStates(); 1514 1515 emitHeader(); 1516 emitUserCode(); 1517 emitClassName(); 1518 1519 skel.emitNext(); 1520 1521 println(" private static final int ZZ_BUFFERSIZE = "+scanner.bufferSize+";"); 1522 1523 if (scanner.debugOption) { 1524 println(" private static final String ZZ_NL = System.getProperty(\"line.separator\");"); 1525 } 1526 1527 skel.emitNext(); 1528 1529 emitLexicalStates(); 1530 1531 emitCharMapArray(); 1532 1533 emitActionTable(); 1534 1535 if (scanner.useRowMap) { 1536 reduceRows(); 1537 1538 emitRowMapArray(); 1539 1540 if (scanner.packed) 1541 emitDynamicInit(); 1542 else 1543 emitZZTrans(); 1544 } 1545 1546 skel.emitNext(); 1547 1548 if (scanner.useRowMap) 1549 emitAttributes(); 1550 1551 skel.emitNext(); 1552 1553 emitClassCode(); 1554 1555 skel.emitNext(); 1556 1557 emitConstructorDecl(); 1558 1559 emitCharMapInitFunction(); 1560 1561 skel.emitNext(); 1562 1563 emitScanError(); 1564 1565 skel.emitNext(); 1566 1567 emitDoEOF(); 1568 1569 skel.emitNext(); 1570 1571 emitLexFunctHeader(); 1572 1573 emitNextInput(); 1574 1575 if (scanner.useRowMap) 1576 emitGetRowMapNext(); 1577 else 1578 emitTransitionTable(); 1579 1580 if (scanner.lookAheadUsed) 1581 emitPushback(); 1582 1583 skel.emitNext(); 1584 1585 emitActions(); 1586 1587 skel.emitNext(); 1588 1589 emitEOFVal(); 1590 1591 skel.emitNext(); 1592 1593 emitNoMatch(); 1594 1595 skel.emitNext(); 1596 1597 emitMain(); 1598 1599 skel.emitNext(); 1600 1601 out.close(); 1602 } 1603 1604} 1605 | Popular Tags |