1 package java_cup; 2 3 import java.io.PrintWriter ; 4 import java.util.Stack ; 5 import java.util.Enumeration ; 6 import java.util.Date ; 7 8 56 57 97 98 public class emit { 99 100 101 102 103 104 105 private emit() { } 106 107 108 109 110 111 112 public static final int max_string_size = 65500; 113 114 115 public static String prefix = "CUP$"; 116 117 118 119 120 public static String package_name = null; 121 122 123 124 125 public static String symbol_const_class_name = "sym"; 126 127 128 129 130 public static String parser_class_name = "parser"; 131 132 133 134 136 public static String extendsimpls = ""; 137 138 139 140 141 public static String action_code = null; 142 143 144 145 146 public static String parser_code = null; 147 148 149 150 151 public static String init_code = null; 152 153 154 155 156 public static String scan_code = null; 157 158 159 160 161 public static production start_production = null; 162 163 164 165 166 public static Stack import_list = new Stack (); 167 168 169 170 171 public static int num_conflicts = 0; 172 173 174 175 176 public static boolean nowarn = false; 177 178 179 180 181 public static int not_reduced = 0; 182 183 184 185 186 public static int unused_term = 0; 187 188 189 190 191 public static int unused_non_term = 0; 192 193 194 195 196 197 198 public static long symbols_time = 0; 199 200 201 public static long parser_time = 0; 202 203 204 public static long action_code_time = 0; 205 206 207 public static long production_table_time = 0; 208 209 210 public static long action_table_time = 0; 211 212 213 public static long goto_table_time = 0; 214 215 216 protected static boolean _lr_values; 217 218 219 public static boolean lr_values() {return _lr_values;} 220 protected static void set_lr_values(boolean b) { _lr_values = b;} 221 222 223 224 225 226 229 protected static String pre(String str) { 230 return prefix + parser_class_name + "$" + str; 231 } 232 233 234 235 238 protected static void emit_package(PrintWriter out) 239 { 240 241 if (package_name != null) { 242 out.println("package " + package_name + ";"); out.println(); 243 } 244 } 245 246 247 248 254 public static void symbols(PrintWriter out, 255 boolean emit_non_terms, boolean sym_interface) 256 { 257 terminal term; 258 non_terminal nt; 259 String class_or_interface = (sym_interface)?"interface":"class"; 260 261 long start_time = System.currentTimeMillis(); 262 263 264 out.println(); 265 out.println("//----------------------------------------------------"); 266 out.println("// The following code was generated by " + 267 version.title_str); 268 out.println("// " + new Date ()); 269 out.println("//----------------------------------------------------"); 270 out.println(); 271 emit_package(out); 272 273 274 out.println("/** CUP generated " + class_or_interface + 275 " containing symbol constants. */"); 276 out.println("public " + class_or_interface + " " + 277 symbol_const_class_name + " {"); 278 279 out.println(" /* terminals */"); 280 281 282 for (Enumeration e = terminal.all(); e.hasMoreElements(); ) 283 { 284 term = (terminal)e.nextElement(); 285 286 287 out.println(" public static final int " + term.name() + " = " + 288 term.index() + ";"); 289 } 290 291 292 if (emit_non_terms) 293 { 294 out.println(); 295 out.println(" /* non terminals */"); 296 297 298 for (Enumeration e = non_terminal.all(); e.hasMoreElements(); ) 299 { 300 nt = (non_terminal)e.nextElement(); 301 302 303 out.println(" static final int " + nt.name() + " = " + 304 nt.index() + ";"); 305 } 306 } 307 308 309 out.println("}"); 310 out.println(); 311 312 symbols_time = System.currentTimeMillis() - start_time; 313 } 314 315 316 317 322 protected static void emit_action_code(PrintWriter out, production start_prod, 323 int max_actions) 324 throws internal_error 325 { 326 production prod; 327 328 long start_time = System.currentTimeMillis(); 329 330 331 out.println(); 332 out.println( 333 "/** Cup generated class to encapsulate user supplied action code.*/" 334 ); 335 out.println("class " + pre("actions") + " {"); 336 337 338 if (action_code != null) 339 { 340 out.println(); 341 out.println(action_code); 342 } 343 344 345 out.println(" private final "+parser_class_name+" parser;"); 346 347 348 out.println(); 349 out.println(" /** Constructor */"); 350 out.println(" " + pre("actions") + "("+parser_class_name+" parser) {"); 351 out.println(" this.parser = parser;"); 352 out.println(" }"); 353 354 355 emit_do_action_header(out, ""); 356 357 int num_prods = production.number(); 358 359 if (num_prods > max_actions) { 360 emit_dispatch_search(out, 0, num_prods-1, max_actions, " "); 361 } else { 362 emit_dispatch_switch(out, 0, num_prods-1, start_prod); 363 } 364 365 366 out.println(" }"); 367 368 if (num_prods > max_actions) { 369 emit_dispatch_methods(out, 0, num_prods-1, max_actions, start_prod); 370 } 371 372 373 out.println("}"); 374 out.println(); 375 376 action_code_time = System.currentTimeMillis() - start_time; 377 } 378 379 protected static void emit_do_action_call(PrintWriter out, String suffix) 380 throws internal_error 381 { 382 383 out.print(pre("do_action" + suffix) + "("); 384 out.print(pre("act_num,")); 385 out.print(pre("parser,")); 386 out.print(pre("stack,")); 387 out.print(pre("top)")); 388 } 389 390 protected static void emit_do_action_header(PrintWriter out, String suffix) 391 throws internal_error 392 { 393 394 out.println(); 395 out.println(" /** Method with the actual generated action code. */"); 396 out.println(" public final java_cup.runtime.Symbol " + 397 pre("do_action" + suffix) + "("); 398 out.println(" int " + pre("act_num,")); 399 out.println(" java_cup.runtime.lr_parser " + pre("parser,")); 400 out.println(" java.util.Stack " + pre("stack,")); 401 out.println(" int " + pre("top)")); 402 out.println(" throws java.lang.Exception"); 403 out.println(" {"); 404 405 406 408 out.println(" /* Symbol object for return from actions */"); 409 out.println(" java_cup.runtime.Symbol " + pre("result") + ";"); 410 out.println(); 411 } 412 413 protected static void emit_dispatch_search(PrintWriter out, int lo, int hi, 414 int max_actions, 415 String in) 416 throws internal_error 417 { 418 if (hi - lo + 1 <= max_actions) { 419 out.print(in + "return "); 420 emit_do_action_call(out, "_" + lo); 421 out.println(";"); 422 } 423 else { 424 int mid = (lo + hi) / 2; 425 out.println(in + "if (" + pre("act_num") + " <= " + mid + ") {"); 426 emit_dispatch_search(out, lo, mid, max_actions, in + " "); 427 out.println(in + "} else {"); 428 emit_dispatch_search(out, mid+1, hi, max_actions, in + " "); 429 out.println(in + "}"); 430 } 431 } 432 433 protected static void emit_dispatch_methods(PrintWriter out, int lo, int hi, 434 int max_actions, 435 production start_prod) 436 throws internal_error 437 { 438 if (hi - lo + 1 <= max_actions) { 439 emit_do_action_header(out, "_" + lo); 440 emit_dispatch_switch(out, lo, hi, start_prod); 441 442 out.println(" }"); 443 } else { 444 int mid = (lo + hi) / 2; 445 emit_dispatch_methods(out, lo, mid, max_actions, start_prod); 446 emit_dispatch_methods(out, mid+1, hi, max_actions, start_prod); 447 } 448 } 449 450 protected static void emit_dispatch_switch(PrintWriter out, int lo, int hi, 451 production start_prod) 452 throws internal_error 453 { 454 production prod; 455 456 457 out.println(" /* select the action based on the action number */"); 458 out.println(" switch (" + pre("act_num") + ")"); 459 out.println(" {"); 460 461 462 for (Enumeration p = production.all(); p.hasMoreElements(); ) 463 { 464 prod = (production)p.nextElement(); 465 466 if (prod.index() < lo || prod.index() > hi) 467 continue; 468 469 470 out.println(" /*. . . . . . . . . . . . . . . . . . . .*/"); 471 out.println(" case " + prod.index() + ": // " + 472 prod.to_simple_string()); 473 474 emit_production_block(out, prod, start_prod); 475 } 476 477 out.println(" default:"); 478 out.println(" {"); 479 out.println(" throw new Exception("); 480 out.println(" \"Invalid action number found in " + 481 "internal parse table\");"); 482 out.println(" }"); 483 out.println(); 484 485 486 out.println(" }"); 487 } 488 489 490 491 496 protected static void emit_production_block(PrintWriter out, production prod, 497 production start_prod) 498 throws internal_error 499 { 500 501 out.println(" {"); 502 503 504 507 out.println(" " + prod.lhs().the_symbol().stack_type() + 508 " RESULT = null;"); 509 510 514 for (int i=0; i<prod.rhs_length(); i++) { 515 if (!(prod.rhs(i) instanceof symbol_part)) continue; 517 symbol s = ((symbol_part)prod.rhs(i)).the_symbol(); 518 if (!(s instanceof non_terminal)) continue; 519 if (((non_terminal)s).is_embedded_action == false) continue; 522 int index = prod.rhs_length() - i - 1; out.println(" " + "// propagate RESULT from " + 525 s.name()); 526 out.println(" " + "if ( " + 527 "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" 528 + emit.pre("top") + "-" + index + ")).value != null )"); 529 out.println(" " + "RESULT = " + 530 "(" + prod.lhs().the_symbol().stack_type() + ") " + 531 "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" 532 + emit.pre("top") + "-" + index + ")).value;"); 533 } 534 535 536 if (prod.action() != null && prod.action().code_string() != null && 537 !prod.action().equals("")) 538 out.println(prod.action().code_string()); 539 540 543 544 546 if (emit.lr_values()) { 547 int loffset; 548 String leftstring, rightstring; 549 int roffset = 0; 550 rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + 551 emit.pre("top") + "-" + roffset + ")).right"; 552 if (prod.rhs_length() == 0) 553 leftstring = rightstring; 554 else { 555 loffset = prod.rhs_length() - 1; 556 leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + 557 emit.pre("top") + "-" + loffset + ")).left"; 558 } 559 out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" + 560 prod.lhs().the_symbol().index() + "/*" + 561 prod.lhs().the_symbol().name() + "*/" + 562 ", " + leftstring + ", " + rightstring + ", RESULT);"); 563 } else { 564 out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" + 565 prod.lhs().the_symbol().index() + "/*" + 566 prod.lhs().the_symbol().name() + "*/" + 567 ", RESULT);"); 568 } 569 570 571 out.println(" }"); 572 573 574 if (prod == start_prod) 575 { 576 out.println(" /* ACCEPT */"); 577 out.println(" " + pre("parser") + ".done_parsing();"); 578 } 579 580 581 out.println(" return " + pre("result") + ";"); 582 out.println(); 583 } 584 585 586 587 590 protected static void emit_production_table(PrintWriter out) 591 { 592 production all_prods[]; 593 production prod; 594 595 long start_time = System.currentTimeMillis(); 596 597 598 all_prods = new production[production.number()]; 599 for (Enumeration p = production.all(); p.hasMoreElements(); ) 600 { 601 prod = (production)p.nextElement(); 602 all_prods[prod.index()] = prod; 603 } 604 605 short[][] prod_table = new short[production.number()][2]; 607 for (int i = 0; i<production.number(); i++) 608 { 609 prod = all_prods[i]; 610 prod_table[i][0] = (short) prod.lhs().the_symbol().index(); 612 prod_table[i][1] = (short) prod.rhs_length(); 613 } 614 615 out.println(); 616 out.println(" /** Production table. */"); 617 out.println(" protected static final short _production_table[][] = "); 618 out.print (" unpackFromStrings("); 619 do_table_as_string(out, prod_table); 620 out.println(");"); 621 622 623 out.println(); 624 out.println(" /** Access to production table. */"); 625 out.println(" public short[][] production_table() " + 626 "{return _production_table;}"); 627 628 production_table_time = System.currentTimeMillis() - start_time; 629 } 630 631 632 633 639 protected static void do_action_table( 640 PrintWriter out, 641 parse_action_table act_tab, 642 boolean compact_reduces, 643 int max_actions) 644 throws internal_error 645 { 646 parse_action_row row; 647 parse_action act; 648 int red; 649 650 long start_time = System.currentTimeMillis(); 651 652 653 short[][] action_table = new short[act_tab.num_states()][]; 654 655 for (int i = 0; i < act_tab.num_states(); i++) 656 { 657 658 row = act_tab.under_state[i]; 659 660 661 if (compact_reduces) 662 row.compute_default(); 663 else 664 row.default_reduce = -1; 665 666 667 short[] temp_table = new short[2*row.size()]; 668 int nentries = 0; 669 670 671 for (int j = 0; j < row.size(); j++) 672 { 673 674 act = row.under_term[j]; 675 676 677 if (act.kind() != parse_action.ERROR) 678 { 679 680 681 682 if (act.kind() == parse_action.SHIFT) 683 { 684 685 temp_table[nentries++] = (short) j; 686 temp_table[nentries++] = (short) 687 (((shift_action)act).shift_to().index() + 1); 688 } 689 690 691 else if (act.kind() == parse_action.REDUCE) 692 { 693 694 red = ((reduce_action)act).reduce_with().index(); 695 if (red != row.default_reduce) { 696 697 temp_table[nentries++] = (short) j; 698 temp_table[nentries++] = (short) (-(red+1)); 699 } 700 } else if (act.kind() == parse_action.NONASSOC) 701 { 702 703 } 704 705 else 706 throw new internal_error("Unrecognized action code " + 707 act.kind() + " found in parse table"); 708 } 709 } 710 711 712 action_table[i] = new short[nentries + 2]; 713 System.arraycopy(temp_table, 0, action_table[i], 0, nentries); 714 715 716 action_table[i][nentries++] = -1; 717 if (row.default_reduce != -1) 718 action_table[i][nentries++] = (short) (-(row.default_reduce+1)); 719 else 720 action_table[i][nentries++] = 0; 721 } 722 723 724 out.println(); 725 out.println(" /** Parse-action table. */"); 726 out.println(" protected static final short[][] _action_table = "); 727 out.print (" unpackFromStrings("); 728 do_table_as_string(out, action_table); 729 out.println(");"); 730 731 732 out.println(); 733 out.println(" /** Access to parse-action table. */"); 734 out.println(" public short[][] action_table() {return _action_table;}"); 735 736 action_table_time = System.currentTimeMillis() - start_time; 737 } 738 739 740 741 745 protected static void do_reduce_table( 746 PrintWriter out, 747 parse_reduce_table red_tab) 748 { 749 lalr_state goto_st; 750 parse_action act; 751 752 long start_time = System.currentTimeMillis(); 753 754 755 short[][] reduce_goto_table = new short[red_tab.num_states()][]; 756 757 for (int i=0; i<red_tab.num_states(); i++) 758 { 759 760 short[] temp_table = new short[2*red_tab.under_state[i].size()]; 761 int nentries = 0; 762 763 for (int j=0; j<red_tab.under_state[i].size(); j++) 764 { 765 766 goto_st = red_tab.under_state[i].under_non_term[j]; 767 768 769 if (goto_st != null) 770 { 771 772 temp_table[nentries++] = (short) j; 773 temp_table[nentries++] = (short) goto_st.index(); 774 } 775 } 776 777 reduce_goto_table[i] = new short[nentries+2]; 778 System.arraycopy(temp_table, 0, reduce_goto_table[i], 0, nentries); 779 780 781 reduce_goto_table[i][nentries++] = -1; 782 reduce_goto_table[i][nentries++] = -1; 783 } 784 785 786 out.println(); 787 out.println(" /** <code>reduce_goto</code> table. */"); 788 out.println(" protected static final short[][] _reduce_table = "); 789 out.print (" unpackFromStrings("); 790 do_table_as_string(out, reduce_goto_table); 791 out.println(");"); 792 793 794 out.println(); 795 out.println(" /** Access to <code>reduce_goto</code> table. */"); 796 out.println(" public short[][] reduce_table() {return _reduce_table;}"); 797 out.println(); 798 799 goto_table_time = System.currentTimeMillis() - start_time; 800 } 801 802 protected static void do_table_as_string(PrintWriter out, short[][] sa) { 804 out.println("new String[] {"); 805 out.print(" \""); 806 int nchar=0, nbytes=0; 807 nbytes+=do_escaped(out, (char)(sa.length>>16)); 808 nchar =do_newline(out, nchar, nbytes); 809 if (nbytes > max_string_size) nbytes = 0; 810 nbytes+=do_escaped(out, (char)(sa.length&0xFFFF)); 811 nchar =do_newline(out, nchar, nbytes); 812 if (nbytes > max_string_size) nbytes = 0; 813 for (int i=0; i<sa.length; i++) { 814 nbytes+=do_escaped(out, (char)(sa[i].length>>16)); 815 nchar =do_newline(out, nchar, nbytes); 816 if (nbytes > max_string_size) nbytes = 0; 817 nbytes+=do_escaped(out, (char)(sa[i].length&0xFFFF)); 818 nchar =do_newline(out, nchar, nbytes); 819 if (nbytes > max_string_size) nbytes = 0; 820 for (int j=0; j<sa[i].length; j++) { 821 nbytes+=do_escaped(out, (char)(2+sa[i][j])); 824 nchar =do_newline(out, nchar, nbytes); 825 if (nbytes > max_string_size) nbytes = 0; 826 } 827 } 828 out.print("\" }"); 829 } 830 protected static int do_newline(PrintWriter out, int nchar, int nbytes) { 832 if (nbytes > max_string_size) { 833 out.println("\", "); out.print(" \""); } 834 else if (nchar > 11) { out.println("\" +"); out.print(" \""); } 835 else return nchar+1; 836 return 0; 837 } 838 protected static int do_escaped(PrintWriter out, char c) { 840 StringBuffer escape = new StringBuffer (); 841 if (c <= 0xFF) { 842 escape.append(Integer.toOctalString(c)); 843 while(escape.length() < 3) escape.insert(0, '0'); 844 } else { 845 escape.append(Integer.toHexString(c)); 846 while(escape.length() < 4) escape.insert(0, '0'); 847 escape.insert(0, 'u'); 848 } 849 escape.insert(0, '\\'); 850 out.print(escape.toString()); 851 852 if (c == 0) return 2; 854 if (c >= 0x01 && c <= 0x7F) return 1; 855 if (c >= 0x80 && c <= 0x7FF) return 2; 856 return 3; 857 } 858 859 860 861 871 public static void parser( 872 PrintWriter out, 873 parse_action_table action_table, 874 parse_reduce_table reduce_table, 875 int start_st, 876 production start_prod, 877 boolean compact_reduces, 878 int max_actions, 879 boolean suppress_scanner) 880 throws internal_error 881 { 882 long start_time = System.currentTimeMillis(); 883 884 885 out.println(); 886 out.println("//----------------------------------------------------"); 887 out.println("// The following code was generated by " + 888 version.title_str); 889 out.println("// " + new Date ()); 890 out.println("//----------------------------------------------------"); 891 out.println(); 892 emit_package(out); 893 894 895 for (int i = 0; i < import_list.size(); i++) 896 out.println("import " + import_list.elementAt(i) + ";"); 897 898 899 out.println(); 900 out.println("/** "+version.title_str+" generated parser."); 901 out.println(" * @version " + new Date ()); 902 out.println(" */"); 903 out.println("public class " + parser_class_name); 904 if (extendsimpls.equals("")) 905 out.println(" extends java_cup.runtime.lr_parser"); 906 else out.println(extendsimpls); 907 908 909 910 out.println("{"); 911 if (extendsimpls.equals("")) { 912 out.println(" /** Default constructor. */"); 913 out.println(" public " + parser_class_name + "() {super();}"); 914 if (!suppress_scanner) { 915 out.println(); 916 out.println(" /** Constructor which sets the default scanner. */"); 917 out.println(" public " + parser_class_name + 918 "(java_cup.runtime.Scanner s) {super(s);}"); 919 } 920 } 921 922 923 emit_production_table(out); 924 do_action_table(out, action_table, compact_reduces, max_actions); 925 do_reduce_table(out, reduce_table); 926 927 928 out.println(" /** Instance of action encapsulation class. */"); 929 out.println(" protected " + pre("actions") + " action_obj;"); 930 out.println(); 931 932 933 out.println(" /** Action encapsulation object initializer. */"); 934 out.println(" protected void init_actions()"); 935 out.println(" {"); 936 out.println(" action_obj = new " + pre("actions") + "(this);"); 937 out.println(" }"); 938 out.println(); 939 940 941 out.println(" /** Invoke a user supplied parse action. */"); 942 out.println(" public java_cup.runtime.Symbol do_action("); 943 out.println(" int act_num,"); 944 out.println(" java_cup.runtime.lr_parser parser,"); 945 out.println(" java.util.Stack stack,"); 946 out.println(" int top)"); 947 out.println(" throws java.lang.Exception"); 948 out.println(" {"); 949 out.println(" /* call code in generated class */"); 950 out.println(" return action_obj." + pre("do_action(") + 951 "act_num, parser, stack, top);"); 952 out.println(" }"); 953 out.println(""); 954 955 956 957 out.println(" /** Indicates start state. */"); 958 out.println(" public int start_state() {return " + start_st + ";}"); 959 960 961 out.println(" /** Indicates start production. */"); 962 out.println(" public int start_production() {return " + 963 start_production.index() + ";}"); 964 out.println(); 965 966 967 out.println(" /** <code>EOF</code> Symbol index. */"); 968 out.println(" public int EOF_sym() {return " + terminal.EOF.index() + 969 ";}"); 970 out.println(); 971 out.println(" /** <code>error</code> Symbol index. */"); 972 out.println(" public int error_sym() {return " + terminal.error.index() + 973 ";}"); 974 out.println(); 975 976 977 if (init_code != null) 978 { 979 out.println(); 980 out.println(" /** User initialization code. */"); 981 out.println(" public void user_init() throws java.lang.Exception"); 982 out.println(" {"); 983 out.println(init_code); 984 out.println(" }"); 985 } 986 987 988 if (scan_code != null) 989 { 990 out.println(); 991 out.println(" /** Scan to get the next Symbol. */"); 992 out.println(" public java_cup.runtime.Symbol scan()"); 993 out.println(" throws java.lang.Exception"); 994 out.println(" {"); 995 out.println(scan_code); 996 out.println(" }"); 997 } 998 999 1000 if (parser_code != null) 1001 { 1002 out.println(); 1003 out.println(parser_code); 1004 } 1005 1006 1007 out.println("}"); 1008 1009 1010 emit_action_code(out, start_prod, max_actions); 1011 1012 parser_time = System.currentTimeMillis() - start_time; 1013 } 1014 1015 1016} 1017 | Popular Tags |