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