1 2 package com.sun.java_cup.internal; 3 4 import java.util.Hashtable ; 5 import java.util.Enumeration ; 6 7 26 27 public class production { 28 29 30 31 32 33 56 public production( 57 non_terminal lhs_sym, 58 production_part rhs_parts[], 59 int rhs_l, 60 String action_str) 61 throws internal_error 62 { 63 int i; 64 action_part tail_action; 65 String declare_str; 66 int rightlen = rhs_l; 67 68 69 if (rhs_l >= 0) 70 _rhs_length = rhs_l; 71 else if (rhs_parts != null) 72 _rhs_length = rhs_parts.length; 73 else 74 _rhs_length = 0; 75 76 77 if (lhs_sym == null) 78 throw new internal_error( 79 "Attempt to construct a production with a null LHS"); 80 81 85 86 90 91 if (rhs_l > 0) { 92 if (rhs_parts[rhs_l - 1].is_action()) { 93 rightlen = rhs_l - 1; 94 } else { 95 rightlen = rhs_l; 96 } 97 } 98 99 100 declare_str = declare_labels( 101 rhs_parts, rightlen, action_str); 102 103 if (action_str == null) 104 action_str = declare_str; 105 else 106 action_str = declare_str + action_str; 107 108 109 lhs_sym.note_use(); 110 111 112 _lhs = new symbol_part(lhs_sym); 113 114 115 _rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length); 116 117 118 tail_action = strip_trailing_action(rhs_parts, _rhs_length); 119 if (tail_action != null) _rhs_length--; 120 121 125 126 127 _rhs = new production_part[_rhs_length]; 128 for (i=0; i<_rhs_length; i++) { 129 _rhs[i] = rhs_parts[i]; 130 if (!_rhs[i].is_action()) { 131 ((symbol_part)_rhs[i]).the_symbol().note_use(); 132 if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) { 133 _rhs_prec = 134 ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num(); 135 _rhs_assoc = 136 ((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side(); 137 } 138 } 139 } 140 141 143 if (action_str == null) action_str = ""; 144 if (tail_action != null && tail_action.code_string() != null) 145 action_str = action_str + "\t\t" + tail_action.code_string(); 146 147 148 _action = new action_part(action_str); 149 150 151 remove_embedded_actions(); 152 153 154 _index = next_index++; 155 156 157 _all.put(new Integer (_index),this); 158 159 160 lhs_sym.add_production(this); 161 } 162 163 164 165 166 public production( 167 non_terminal lhs_sym, 168 production_part rhs_parts[], 169 int rhs_l) 170 throws internal_error 171 { 172 this(lhs_sym,rhs_parts,rhs_l,null); 173 } 174 175 176 177 179 public production( 180 non_terminal lhs_sym, 181 production_part rhs_parts[], 182 int rhs_l, 183 String action_str, 184 int prec_num, 185 int prec_side) 186 throws internal_error 187 { 188 this(lhs_sym,rhs_parts,rhs_l,action_str); 189 190 191 set_precedence_num(prec_num); 192 set_precedence_side(prec_side); 193 } 194 195 196 197 199 public production( 200 non_terminal lhs_sym, 201 production_part rhs_parts[], 202 int rhs_l, 203 int prec_num, 204 int prec_side) 205 throws internal_error 206 { 207 this(lhs_sym,rhs_parts,rhs_l,null); 208 209 set_precedence_num(prec_num); 210 set_precedence_side(prec_side); 211 } 212 213 214 215 216 217 218 219 220 223 protected static Hashtable _all = new Hashtable (); 224 225 226 public static Enumeration all() {return _all.elements();} 227 228 229 public static production find(int indx) { 230 return (production) _all.get(new Integer (indx)); 231 } 232 233 234 235 236 public static int number() {return _all.size();} 237 238 239 protected static int next_index; 240 241 242 243 244 245 246 protected symbol_part _lhs; 247 248 249 public symbol_part lhs() {return _lhs;} 250 251 252 253 protected int _rhs_prec = -1; 254 protected int _rhs_assoc = -1; 255 256 257 public int precedence_num() { return _rhs_prec; } 258 public int precedence_side() { return _rhs_assoc; } 259 260 261 public void set_precedence_num(int prec_num) { 262 _rhs_prec = prec_num; 263 } 264 public void set_precedence_side(int prec_side) { 265 _rhs_assoc = prec_side; 266 } 267 268 269 270 271 protected production_part _rhs[]; 272 273 274 public production_part rhs(int indx) throws internal_error 275 { 276 if (indx >= 0 && indx < _rhs_length) 277 return _rhs[indx]; 278 else 279 throw new internal_error( 280 "Index out of range for right hand side of production"); 281 } 282 283 284 285 286 protected int _rhs_length; 287 288 289 public int rhs_length() {return _rhs_length;} 290 291 292 293 296 protected action_part _action; 297 298 301 public action_part action() {return _action;} 302 303 304 305 306 protected int _index; 307 308 309 public int index() {return _index;} 310 311 312 313 314 protected int _num_reductions = 0; 315 316 317 public int num_reductions() {return _num_reductions;} 318 319 320 public void note_reduction_use() {_num_reductions++;} 321 322 323 324 325 protected boolean _nullable_known = false; 326 327 328 public boolean nullable_known() {return _nullable_known;} 329 330 331 332 333 protected boolean _nullable = false; 334 335 336 public boolean nullable() {return _nullable;} 337 338 339 340 343 protected terminal_set _first_set = new terminal_set(); 344 345 348 public terminal_set first_set() {return _first_set;} 349 350 351 352 353 354 357 protected static boolean is_id_start(char c) 358 { 359 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'); 360 361 } 363 364 365 366 369 protected static boolean is_id_char(char c) 370 { 371 return is_id_start(c) || (c >= '0' && c <= '9'); 372 } 373 374 375 376 377 378 379 384 protected String make_declaration( 385 String labelname, 386 String stack_type, 387 int offset) 388 { 389 String ret; 390 391 392 if (emit.lr_values()) 393 ret = "\t\tint " + labelname + "left = ((com.sun.java_cup.internal.runtime.Symbol)" + 394 emit.pre("stack") + ".elementAt(" + emit.pre("top") + 395 "-" + offset + ")).left;\n" + 396 "\t\tint " + labelname + "right = ((com.sun.java_cup.internal.runtime.Symbol)" + 397 emit.pre("stack") + ".elementAt(" + emit.pre("top") + 398 "-" + offset + ")).right;\n"; 399 else ret = ""; 400 401 402 return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type + 403 ")((" + "com.sun.java_cup.internal.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") 404 + "-" + offset + ")).value;\n"; 405 406 } 407 408 409 415 protected String declare_labels( 416 production_part rhs[], 417 int rhs_len, 418 String final_action) 419 { 420 String declaration = ""; 421 422 symbol_part part; 423 action_part act_part; 424 int pos; 425 426 427 for (pos = 0; pos < rhs_len; pos++) 428 { 429 if (!rhs[pos].is_action()) 430 { 431 part = (symbol_part)rhs[pos]; 432 433 434 if (part.label() != null) 435 { 436 declaration = declaration + 437 make_declaration(part.label(), part.the_symbol().stack_type(), 438 rhs_len-pos-1); 439 } 440 } 441 } 442 return declaration; 443 } 444 445 446 447 448 449 454 protected int merge_adjacent_actions(production_part rhs_parts[], int len) 455 { 456 int from_loc, to_loc, merge_cnt; 457 458 459 if (rhs_parts == null || len == 0) return 0; 460 461 merge_cnt = 0; 462 to_loc = -1; 463 for (from_loc=0; from_loc<len; from_loc++) 464 { 465 466 if (to_loc < 0 || !rhs_parts[to_loc].is_action() 467 || !rhs_parts[from_loc].is_action()) 468 { 469 470 to_loc++; 471 472 473 if (to_loc != from_loc) rhs_parts[to_loc] = null; 474 } 475 476 477 if (to_loc != from_loc) 478 { 479 480 if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() && 481 rhs_parts[from_loc].is_action()) 482 { 483 484 rhs_parts[to_loc] = new action_part( 485 ((action_part)rhs_parts[to_loc]).code_string() + 486 ((action_part)rhs_parts[from_loc]).code_string()); 487 merge_cnt++; 488 } 489 else 490 { 491 492 rhs_parts[to_loc] = rhs_parts[from_loc]; 493 } 494 } 495 } 496 497 498 return len - merge_cnt; 499 } 500 501 502 503 508 protected action_part strip_trailing_action( 509 production_part rhs_parts[], 510 int len) 511 { 512 action_part result; 513 514 515 if (rhs_parts == null || len == 0) return null; 516 517 518 if (rhs_parts[len-1].is_action()) 519 { 520 521 result = (action_part)rhs_parts[len-1]; 522 rhs_parts[len-1] = null; 523 return result; 524 } 525 else 526 return null; 527 } 528 529 530 531 543 544 548 protected void remove_embedded_actions( 549 550 ) throws internal_error 551 { 552 non_terminal new_nt; 553 production new_prod; 554 String declare_str; 555 556 557 for (int act_loc = 0; act_loc < rhs_length(); act_loc++) 558 if (rhs(act_loc).is_action()) 559 { 560 561 562 declare_str = declare_labels( 563 _rhs, act_loc, ""); 564 565 new_nt = non_terminal.create_new(); 566 new_nt.is_embedded_action = true; 567 568 569 new_prod = new action_production(this, new_nt, null, 0, 570 declare_str + ((action_part)rhs(act_loc)).code_string()); 571 572 573 _rhs[act_loc] = new symbol_part(new_nt); 574 } 575 } 576 577 578 579 584 public boolean check_nullable() throws internal_error 585 { 586 production_part part; 587 symbol sym; 588 int pos; 589 590 591 if (nullable_known()) return nullable(); 592 593 594 if (rhs_length() == 0) 595 { 596 597 return set_nullable(true); 598 } 599 600 601 for (pos=0; pos<rhs_length(); pos++) 602 { 603 part = rhs(pos); 604 605 606 if (!part.is_action()) 607 { 608 sym = ((symbol_part)part).the_symbol(); 609 610 611 if (!sym.is_non_term()) 612 return set_nullable(false); 613 614 else if (!((non_terminal)sym).nullable()) 615 616 return false; 617 } 618 } 619 620 621 return set_nullable(true); 622 } 623 624 625 boolean set_nullable(boolean v) 626 { 627 _nullable_known = true; 628 _nullable = v; 629 return v; 630 } 631 632 633 634 638 public terminal_set check_first_set() throws internal_error 639 { 640 int part; 641 symbol sym; 642 643 644 for (part=0; part<rhs_length(); part++) 645 { 646 647 if (!rhs(part).is_action()) 648 { 649 sym = ((symbol_part)rhs(part)).the_symbol(); 650 651 652 if (sym.is_non_term()) 653 { 654 655 _first_set.add(((non_terminal)sym).first_set()); 656 657 658 if (!((non_terminal)sym).nullable()) 659 break; 660 } 661 else 662 { 663 664 _first_set.add((terminal)sym); 665 666 667 break; 668 } 669 } 670 } 671 672 673 return first_set(); 674 } 675 676 677 678 679 public boolean equals(production other) 680 { 681 if (other == null) return false; 682 return other._index == _index; 683 } 684 685 686 687 688 public boolean equals(Object other) 689 { 690 if (!(other instanceof production)) 691 return false; 692 else 693 return equals((production)other); 694 } 695 696 697 698 699 public int hashCode() 700 { 701 702 return _index*13; 703 } 704 705 706 707 708 public String toString() 709 { 710 String result; 711 712 713 try { 714 result = "production [" + index() + "]: "; 715 result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$"); 716 result += " :: = "; 717 for (int i = 0; i<rhs_length(); i++) 718 result += rhs(i) + " "; 719 result += ";"; 720 if (action() != null && action().code_string() != null) 721 result += " {" + action().code_string() + "}"; 722 723 if (nullable_known()) 724 if (nullable()) 725 result += "[NULLABLE]"; 726 else 727 result += "[NOT NULLABLE]"; 728 } catch (internal_error e) { 729 731 e.crash(); 732 result = null; 733 } 734 735 return result; 736 } 737 738 739 740 741 public String to_simple_string() throws internal_error 742 { 743 String result; 744 745 result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS"); 746 result += " ::= "; 747 for (int i = 0; i < rhs_length(); i++) 748 if (!rhs(i).is_action()) 749 result += ((symbol_part)rhs(i)).the_symbol().name() + " "; 750 751 return result; 752 } 753 754 755 756 } 757 | Popular Tags |