Source code: java_cup/parse_action_table.java
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 */
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. */
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 */
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. */
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 += " [term " + col + ":" + under_state[row].under_term[col] + "]";
122
123 /* end the line after the 2nd one */
124 cnt++;
125 if (cnt == 2)
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