1 2 package java_cup; 3 4 import java.util.Enumeration; 5 6 /** This class represents the complete "action" table of the parser. 7 * It has one row for each state in the parse machine, and a column for 8 * each terminal symbol. Each entry in the table represents a shift, 9 * reduce, or an error. 10 * 11 * @see java_cup.parse_action 12 * @see java_cup.parse_action_row 13 * @version last updated: 11/25/95 14 * @author Scott Hudson 15 */ 16 public class parse_action_table { 17 18 /*-----------------------------------------------------------*/ 19 /*--- Constructor(s) ----------------------------------------*/ 20 /*-----------------------------------------------------------*/ 21 22 /** Simple constructor. All terminals, non-terminals, and productions must 23 * already have been entered, and the viable prefix recognizer should 24 * have been constructed before this is called. 25 */ parse_action_table()26 public parse_action_table() 27 { 28 /* determine how many states we are working with */ 29 _num_states = lalr_state.number(); 30 31 /* allocate the array and fill it in with empty rows */ 32 under_state = new parse_action_row[_num_states]; 33 for (int i=0; i<_num_states; i++) 34 under_state[i] = new parse_action_row(); 35 } 36 37 /*-----------------------------------------------------------*/ 38 /*--- (Access to) Instance Variables ------------------------*/ 39 /*-----------------------------------------------------------*/ 40 41 /** How many rows/states are in the machine/table. */ 42 protected int _num_states; 43 44 /** How many rows/states are in the machine/table. */ num_states()45 public int num_states() {return _num_states;} 46 47 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 48 49 /** Actual array of rows, one per state. */ 50 public parse_action_row[] under_state; 51 52 /*-----------------------------------------------------------*/ 53 /*--- General Methods ---------------------------------------*/ 54 /*-----------------------------------------------------------*/ 55 56 /** Check the table to ensure that all productions have been reduced. 57 * Issue a warning message (to System.err) for each production that 58 * is never reduced. 59 */ check_reductions()60 public void check_reductions() 61 throws internal_error 62 { 63 parse_action act; 64 production prod; 65 66 /* tabulate reductions -- look at every table entry */ 67 for (int row = 0; row < num_states(); row++) 68 { 69 for (int col = 0; col < under_state[row].size(); col++) 70 { 71 /* look at the action entry to see if its a reduce */ 72 act = under_state[row].under_term[col]; 73 if (act != null && act.kind() == parse_action.REDUCE) 74 { 75 /* tell production that we used it */ 76 ((reduce_action)act).reduce_with().note_reduction_use(); 77 } 78 } 79 } 80 81 /* now go across every production and make sure we hit it */ 82 for (Enumeration p = production.all(); p.hasMoreElements(); ) 83 { 84 prod = (production)p.nextElement(); 85 86 /* if we didn't hit it give a warning */ 87 if (prod.num_reductions() == 0) 88 { 89 /* count it * 90 emit.not_reduced++; 91 92 /* give a warning if they haven't been turned off */ 93 if (!emit.nowarn) 94 { 95 System.err.println("*** Production \"" + 96 prod.to_simple_string() + "\" never reduced"); 97 lexer.warning_count++; 98 } 99 } 100 } 101 } 102 103 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .* 104 105 /** Convert to a string. */ toString()106 public String toString() 107 { 108 String result; 109 int cnt; 110 111 result = "-------- ACTION_TABLE --------\n"; 112 for (int row = 0; row < num_states(); row++) 113 { 114 result += "From state #" + row + "\n"; 115 cnt = 0; 116 for (int col = 0; col < under_state[row].size(); col++) 117 { 118 /* if the action is not an error print it */ 119 if (under_state[row].under_term[col].kind() != parse_action.ERROR) 120 { 121 result += col + ":" + under_state[row].under_term[col] + " "; 122 123 /* end the line after the 3rd one */ 124 cnt++; 125 if (cnt == 3) 126 { 127 result += "\n"; 128 cnt = 0; 129 } 130 } 131 } 132 /* finish the line if we haven't just done that */ 133 if (cnt != 0) result += "\n"; 134 } 135 result += "------------------------------"; 136 137 return result; 138 } 139 140 /*-----------------------------------------------------------*/ 141 142 }; 143 144