1 2 package com.sun.java_cup.internal; 3 4 import java.util.Hashtable ; 5 import java.util.Enumeration ; 6 import java.util.Stack ; 7 8 51 52 public class lalr_state { 53 54 55 56 57 60 public lalr_state(lalr_item_set itms) throws internal_error 61 { 62 63 if (itms == null) 64 throw new internal_error( 65 "Attempt to construct an LALR state from a null item set"); 66 67 if (find_state(itms) != null) 68 throw new internal_error( 69 "Attempt to construct a duplicate LALR state"); 70 71 72 _index = next_index++; 73 74 75 _items = itms; 76 77 78 _all.put(_items,this); 79 } 80 81 82 83 84 85 86 protected static Hashtable _all = new Hashtable (); 87 88 89 public static Enumeration all() {return _all.elements();} 90 91 92 93 94 public static int number() {return _all.size();} 95 96 97 98 102 protected static Hashtable _all_kernels = new Hashtable (); 103 104 105 106 113 public static lalr_state find_state(lalr_item_set itms) 114 { 115 if (itms == null) 116 return null; 117 else 118 return (lalr_state)_all.get(itms); 119 } 120 121 122 123 124 protected static int next_index = 0; 125 126 127 128 129 130 131 protected lalr_item_set _items; 132 133 134 public lalr_item_set items() {return _items;} 135 136 137 138 139 protected lalr_transition _transitions = null; 140 141 142 public lalr_transition transitions() {return _transitions;} 143 144 145 146 147 protected int _index; 148 149 150 public int index() {return _index;} 151 152 153 154 155 156 159 protected static void dump_state(lalr_state st) throws internal_error 160 { 161 lalr_item_set itms; 162 lalr_item itm; 163 production_part part; 164 165 if (st == null) 166 { 167 System.out.println("NULL lalr_state"); 168 return; 169 } 170 171 System.out.println("lalr_state [" + st.index() + "] {"); 172 itms = st.items(); 173 for (Enumeration e = itms.all(); e.hasMoreElements(); ) 174 { 175 itm = (lalr_item)e.nextElement(); 176 System.out.print(" ["); 177 System.out.print(itm.the_production().lhs().the_symbol().name()); 178 System.out.print(" ::= "); 179 for (int i = 0; i<itm.the_production().rhs_length(); i++) 180 { 181 if (i == itm.dot_pos()) System.out.print("(*) "); 182 part = itm.the_production().rhs(i); 183 if (part.is_action()) 184 System.out.print("{action} "); 185 else 186 System.out.print(((symbol_part)part).the_symbol().name() + " "); 187 } 188 if (itm.dot_at_end()) System.out.print("(*) "); 189 System.out.println("]"); 190 } 191 System.out.println("}"); 192 } 193 194 195 196 203 protected static void propagate_all_lookaheads() throws internal_error 204 { 205 206 for (Enumeration st = all(); st.hasMoreElements(); ) 207 { 208 209 ((lalr_state)st.nextElement()).propagate_lookaheads(); 210 } 211 } 212 213 214 215 216 217 221 public void add_transition(symbol on_sym, lalr_state to_st) 222 throws internal_error 223 { 224 lalr_transition trans; 225 226 227 trans = new lalr_transition(on_sym, to_st, _transitions); 228 _transitions = trans; 229 } 230 231 232 233 270 271 public static lalr_state build_machine(production start_prod) 272 throws internal_error 273 { 274 lalr_state start_state; 275 lalr_item_set start_items; 276 lalr_item_set new_items; 277 lalr_item_set linked_items; 278 lalr_item_set kernel; 279 Stack work_stack = new Stack (); 280 lalr_state st, new_st; 281 symbol_set outgoing; 282 lalr_item itm, new_itm, existing, fix_itm; 283 symbol sym, sym2; 284 Enumeration i, s, fix; 285 286 287 if (start_prod == null) 288 throw new internal_error( 289 "Attempt to build viable prefix recognizer using a null production"); 290 291 292 start_items = new lalr_item_set(); 293 294 itm = new lalr_item(start_prod); 295 itm.lookahead().add(terminal.EOF); 296 297 start_items.add(itm); 298 299 300 kernel = new lalr_item_set(start_items); 301 302 303 start_items.compute_closure(); 304 305 306 start_state = new lalr_state(start_items); 307 work_stack.push(start_state); 308 309 310 _all_kernels.put(kernel, start_state); 311 312 313 while (!work_stack.empty()) 314 { 315 316 st = (lalr_state)work_stack.pop(); 317 318 319 outgoing = new symbol_set(); 320 for (i = st.items().all(); i.hasMoreElements(); ) 321 { 322 itm = (lalr_item)i.nextElement(); 323 324 325 sym = itm.symbol_after_dot(); 326 if (sym != null) outgoing.add(sym); 327 } 328 329 330 for (s = outgoing.all(); s.hasMoreElements(); ) 331 { 332 sym = (symbol)s.nextElement(); 333 334 335 linked_items = new lalr_item_set(); 336 337 339 new_items = new lalr_item_set(); 340 for (i = st.items().all(); i.hasMoreElements();) 341 { 342 itm = (lalr_item)i.nextElement(); 343 344 345 sym2 = itm.symbol_after_dot(); 346 if (sym.equals(sym2)) 347 { 348 349 new_items.add(itm.shift()); 350 351 352 linked_items.add(itm); 353 } 354 } 355 356 357 kernel = new lalr_item_set(new_items); 358 359 360 new_st = (lalr_state)_all_kernels.get(kernel); 361 362 363 if (new_st == null) 364 { 365 366 new_items.compute_closure(); 367 368 369 new_st = new lalr_state(new_items); 370 371 372 work_stack.push(new_st); 373 374 375 _all_kernels.put(kernel, new_st); 376 } 377 378 else 379 { 380 381 for (fix = linked_items.all(); fix.hasMoreElements(); ) 382 { 383 fix_itm = (lalr_item)fix.nextElement(); 384 385 386 for (int l =0; l < fix_itm.propagate_items().size(); l++) 387 { 388 389 new_itm = 390 (lalr_item)fix_itm.propagate_items().elementAt(l); 391 392 393 existing = new_st.items().find(new_itm); 394 395 396 if (existing != null) 397 fix_itm.propagate_items().setElementAt(existing ,l); 398 } 399 } 400 } 401 402 403 st.add_transition(sym, new_st); 404 } 405 } 406 407 408 409 410 propagate_all_lookaheads(); 411 412 return start_state; 413 } 414 415 416 417 421 protected void propagate_lookaheads() throws internal_error 422 { 423 424 for (Enumeration itm = items().all(); itm.hasMoreElements(); ) 425 ((lalr_item)itm.nextElement()).propagate_lookaheads(null); 426 } 427 428 429 430 451 public void build_table_entries( 452 parse_action_table act_table, 453 parse_reduce_table reduce_table) 454 throws internal_error 455 { 456 parse_action_row our_act_row; 457 parse_reduce_row our_red_row; 458 lalr_item itm; 459 parse_action act, other_act; 460 symbol sym; 461 terminal_set conflict_set = new terminal_set(); 462 463 464 our_act_row = act_table.under_state[index()]; 465 our_red_row = reduce_table.under_state[index()]; 466 467 468 for (Enumeration i = items().all(); i.hasMoreElements(); ) 469 { 470 itm = (lalr_item)i.nextElement(); 471 472 473 474 if (itm.dot_at_end()) 475 { 476 act = new reduce_action(itm.the_production()); 477 478 479 for (int t = 0; t < terminal.number(); t++) 480 { 481 482 if (!itm.lookahead().contains(t)) continue; 483 484 485 if (our_act_row.under_term[t].kind() == 486 parse_action.ERROR) 487 { 488 our_act_row.under_term[t] = act; 489 } 490 else 491 { 492 493 terminal term = terminal.find(t); 494 other_act = our_act_row.under_term[t]; 495 496 497 if ((other_act.kind() != parse_action.SHIFT) && 498 (other_act.kind() != parse_action.NONASSOC)) 499 { 500 501 if (itm.the_production().index() < 502 ((reduce_action)other_act).reduce_with().index()) 503 { 504 505 our_act_row.under_term[t] = act; 506 } 507 } else { 508 509 if(fix_with_precedence(itm.the_production(), 510 t, our_act_row, act)) { 511 term = null; 512 } 513 } 514 if(term!=null) { 515 516 conflict_set.add(term); 517 } 518 } 519 } 520 } 521 } 522 523 524 for (lalr_transition trans=transitions(); trans!=null; trans=trans.next()) 525 { 526 527 sym = trans.on_symbol(); 528 if (!sym.is_non_term()) 529 { 530 act = new shift_action(trans.to_state()); 531 532 533 if ( our_act_row.under_term[sym.index()].kind() == 534 parse_action.ERROR) 535 { 536 our_act_row.under_term[sym.index()] = act; 537 } 538 else 539 { 540 541 production p = ((reduce_action)our_act_row.under_term[sym.index()]).reduce_with(); 542 543 544 if (!fix_with_precedence(p, sym.index(), our_act_row, act)) { 545 our_act_row.under_term[sym.index()] = act; 546 conflict_set.add(terminal.find(sym.index())); 547 } 548 } 549 } 550 else 551 { 552 553 our_red_row.under_non_term[sym.index()] = trans.to_state(); 554 } 555 } 556 557 558 if (!conflict_set.empty()) 559 report_conflicts(conflict_set); 560 } 561 562 563 564 565 583 584 protected boolean fix_with_precedence( 585 production p, 586 int term_index, 587 parse_action_row table_row, 588 parse_action act) 589 590 throws internal_error { 591 592 terminal term = terminal.find(term_index); 593 594 595 if (p.precedence_num() > assoc.no_prec) { 596 597 598 if (p.precedence_num() > term.precedence_num()) { 599 table_row.under_term[term_index] = 600 insert_reduce(table_row.under_term[term_index],act); 601 return true; 602 } 603 604 605 else if (p.precedence_num() < term.precedence_num()) { 606 table_row.under_term[term_index] = 607 insert_shift(table_row.under_term[term_index],act); 608 return true; 609 } 610 else { 611 612 614 if (term.precedence_side() == assoc.right) { 615 table_row.under_term[term_index] = 616 insert_shift(table_row.under_term[term_index],act); 617 return true; 618 } 619 620 621 else if (term.precedence_side() == assoc.left) { 622 table_row.under_term[term_index] = 623 insert_reduce(table_row.under_term[term_index],act); 624 return true; 625 } 626 627 629 else if (term.precedence_side() == assoc.nonassoc) { 630 table_row.under_term[term_index] = new nonassoc_action(); 631 return true; 632 } else { 633 634 throw new internal_error("Unable to resolve conflict correctly"); 635 } 636 } 637 } 638 640 else if (term.precedence_num() > assoc.no_prec) { 641 table_row.under_term[term_index] = 642 insert_shift(table_row.under_term[term_index],act); 643 return true; 644 } 645 646 648 return false; 649 } 650 651 652 653 654 660 protected parse_action insert_action( 661 parse_action a1, 662 parse_action a2, 663 int act_type) 664 throws internal_error 665 { 666 if ((a1.kind() == act_type) && (a2.kind() == act_type)) { 667 throw new internal_error("Conflict resolution of bogus actions"); 668 } else if (a1.kind() == act_type) { 669 return a1; 670 } else if (a2.kind() == act_type) { 671 return a2; 672 } else { 673 throw new internal_error("Conflict resolution of bogus actions"); 674 } 675 } 676 677 678 protected parse_action insert_shift( 679 parse_action a1, 680 parse_action a2) 681 throws internal_error 682 { 683 return insert_action(a1, a2, parse_action.SHIFT); 684 } 685 686 687 protected parse_action insert_reduce( 688 parse_action a1, 689 parse_action a2) 690 throws internal_error 691 { 692 return insert_action(a1, a2, parse_action.REDUCE); 693 } 694 695 696 697 698 protected void report_conflicts(terminal_set conflict_set) 699 throws internal_error 700 { 701 lalr_item itm, compare; 702 symbol shift_sym; 703 704 boolean after_itm; 705 706 707 for (Enumeration itms = items().all(); itms.hasMoreElements(); ) 708 { 709 itm = (lalr_item)itms.nextElement(); 710 711 712 713 714 if (itm.dot_at_end()) 715 { 716 717 after_itm = false; 718 719 720 for (Enumeration comps = items().all(); comps.hasMoreElements(); ) 721 { 722 compare = (lalr_item)comps.nextElement(); 723 724 725 if (itm == compare) after_itm = true; 726 727 728 if (itm != compare) 729 { 730 731 if (compare.dot_at_end()) 732 { 733 734 if (after_itm) 735 736 if (compare.lookahead().intersects(itm.lookahead())) 737 738 report_reduce_reduce(itm, compare); 739 } 740 } 741 } 742 743 for (int t = 0; t < terminal.number(); t++) 744 if (conflict_set.contains(t)) 745 report_shift_reduce(itm,t); 746 } 747 } 748 } 749 750 751 752 757 protected void report_reduce_reduce(lalr_item itm1, lalr_item itm2) 758 throws internal_error 759 { 760 boolean comma_flag = false; 761 762 System.err.println("*** Reduce/Reduce conflict found in state #"+index()); 763 System.err.print (" between "); 764 System.err.println(itm1.to_simple_string()); 765 System.err.print (" and "); 766 System.err.println(itm2.to_simple_string()); 767 System.err.print(" under symbols: {" ); 768 for (int t = 0; t < terminal.number(); t++) 769 { 770 if (itm1.lookahead().contains(t) && itm2.lookahead().contains(t)) 771 { 772 if (comma_flag) System.err.print(", "); else comma_flag = true; 773 System.err.print(terminal.find(t).name()); 774 } 775 } 776 System.err.println("}"); 777 System.err.print(" Resolved in favor of "); 778 if (itm1.the_production().index() < itm2.the_production().index()) 779 System.err.println("the first production.\n"); 780 else 781 System.err.println("the second production.\n"); 782 783 784 emit.num_conflicts++; 785 lexer.warning_count++; 786 } 787 788 789 790 795 protected void report_shift_reduce( 796 lalr_item red_itm, 797 int conflict_sym) 798 throws internal_error 799 { 800 lalr_item itm; 801 symbol shift_sym; 802 803 804 System.err.println("*** Shift/Reduce conflict found in state #"+index()); 805 System.err.print (" between "); 806 System.err.println(red_itm.to_simple_string()); 807 808 809 for (Enumeration itms = items().all(); itms.hasMoreElements(); ) 810 { 811 itm = (lalr_item)itms.nextElement(); 812 813 814 if (itm != red_itm && !itm.dot_at_end()) 815 { 816 817 shift_sym = itm.symbol_after_dot(); 818 if (!shift_sym.is_non_term() && shift_sym.index() == conflict_sym) 819 { 820 821 System.err.println(" and " + itm.to_simple_string()); 822 } 823 } 824 } 825 System.err.println(" under symbol "+ terminal.find(conflict_sym).name()); 826 System.err.println(" Resolved in favor of shifting.\n"); 827 828 829 emit.num_conflicts++; 830 lexer.warning_count++; 831 } 832 833 834 835 836 public boolean equals(lalr_state other) 837 { 838 839 return other != null && items().equals(other.items()); 840 } 841 842 843 844 845 public boolean equals(Object other) 846 { 847 if (!(other instanceof lalr_state)) 848 return false; 849 else 850 return equals((lalr_state)other); 851 } 852 853 854 855 856 public int hashCode() 857 { 858 859 return items().hashCode(); 860 } 861 862 863 864 865 public String toString() 866 { 867 String result; 868 lalr_transition tr; 869 870 871 result = "lalr_state [" + index() + "]: " + _items + "\n"; 872 873 874 for (tr = transitions(); tr != null; tr = tr.next()) 875 { 876 result += tr; 877 result += "\n"; 878 } 879 880 return result; 881 } 882 883 884 } 885 | Popular Tags |