KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java_cup > internal > lr_item_core


1
2 package com.sun.java_cup.internal;
3
4 /** The "core" of an LR item. This includes a production and the position
5  * of a marker (the "dot") within the production. Typically item cores
6  * are written using a production with an embedded "dot" to indicate their
7  * position. For example: <pre>
8  * A ::= B * C d E
9  * </pre>
10  * This represents a point in a parse where the parser is trying to match
11  * the given production, and has succeeded in matching everything before the
12  * "dot" (and hence is expecting to see the symbols after the dot next). See
13  * lalr_item, lalr_item_set, and lalr_start for full details on the meaning
14  * and use of items.
15  *
16  * @see com.sun.java_cup.internal.lalr_item
17  * @see com.sun.java_cup.internal.lalr_item_set
18  * @see com.sun.java_cup.internal.lalr_state
19  * @version last updated: 11/25/95
20  * @author Scott Hudson
21 */

22
23 public class lr_item_core {
24    
25   /*-----------------------------------------------------------*/
26   /*--- Constructor(s) ----------------------------------------*/
27   /*-----------------------------------------------------------*/
28
29   /** Full constructor.
30    * @param prod production this item uses.
31    * @param pos position of the "dot" within the item.
32    */

33   public lr_item_core(production prod, int pos) throws internal_error
34     {
35       symbol after_dot = null;
36       production_part part;
37
38       if (prod == null)
39     throw new internal_error(
40       "Attempt to create an lr_item_core with a null production");
41
42       _the_production = prod;
43
44       if (pos < 0 || pos > _the_production.rhs_length())
45     throw new internal_error(
46       "Attempt to create an lr_item_core with a bad dot position");
47
48       _dot_pos = pos;
49
50       /* compute and cache hash code now */
51       _core_hash_cache = 13*_the_production.hashCode() + pos;
52
53       /* cache the symbol after the dot */
54       if (_dot_pos < _the_production.rhs_length())
55     {
56       part = _the_production.rhs(_dot_pos);
57       if (!part.is_action())
58         _symbol_after_dot = ((symbol_part)part).the_symbol();
59     }
60     }
61
62   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
63
64   /** Constructor for dot at start of right hand side.
65    * @param prod production this item uses.
66    */

67   public lr_item_core(production prod) throws internal_error
68     {
69       this(prod,0);
70     }
71
72   /*-----------------------------------------------------------*/
73   /*--- (Access to) Instance Variables ------------------------*/
74   /*-----------------------------------------------------------*/
75
76   /** The production for the item. */
77   protected production _the_production;
78
79   /** The production for the item. */
80   public production the_production() {return _the_production;}
81
82   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
83
84   /** The position of the "dot" -- this indicates the part of the production
85    * that the marker is before, so 0 indicates a dot at the beginning of
86    * the RHS.
87    */

88   protected int _dot_pos;
89
90   /** The position of the "dot" -- this indicates the part of the production
91    * that the marker is before, so 0 indicates a dot at the beginning of
92    * the RHS.
93    */

94   public int dot_pos() {return _dot_pos;}
95
96   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
97
98   /** Cache of the hash code. */
99   protected int _core_hash_cache;
100
101   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
102
103   /** Cache of symbol after the dot. */
104   protected symbol _symbol_after_dot = null;
105
106   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
107
108   /** Is the dot at the end of the production? */
109   public boolean dot_at_end()
110     {
111        return _dot_pos >= _the_production.rhs_length();
112     }
113
114   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
115
116   /** Return the symbol after the dot. If there is no symbol after the dot
117    * we return null. */

118   public symbol symbol_after_dot()
119     {
120       /* use the cached symbol */
121       return _symbol_after_dot;
122     }
123
124   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
125
126   /** Determine if we have a dot before a non terminal, and if so which one
127    * (return null or the non terminal).
128    */

129   public non_terminal dot_before_nt()
130     {
131       symbol sym;
132
133       /* get the symbol after the dot */
134       sym = symbol_after_dot();
135
136       /* if it exists and is a non terminal, return it */
137       if (sym != null && sym.is_non_term())
138     return (non_terminal)sym;
139       else
140     return null;
141     }
142
143   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
144
145   /** Produce a new lr_item_core that results from shifting the dot one
146    * position to the right.
147    */

148   public lr_item_core shift_core() throws internal_error
149     {
150       if (dot_at_end())
151     throw new internal_error(
152       "Attempt to shift past end of an lr_item_core");
153
154       return new lr_item_core(_the_production, _dot_pos+1);
155     }
156
157   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
158
159   /** Equality comparison for the core only. This is separate out because we
160    * need separate access in a super class.
161    */

162   public boolean core_equals(lr_item_core other)
163     {
164       return other != null &&
165          _the_production.equals(other._the_production) &&
166          _dot_pos == other._dot_pos;
167     }
168
169   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
170
171   /** Equality comparison. */
172   public boolean equals(lr_item_core other) {return core_equals(other);}
173
174   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
175
176   /** Generic equality comparison. */
177   public boolean equals(Object JavaDoc other)
178     {
179       if (!(other instanceof lr_item_core))
180     return false;
181       else
182     return equals((lr_item_core)other);
183     }
184
185   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
186
187   /** Hash code for the core (separated so we keep non overridden version). */
188   public int core_hashCode()
189     {
190       return _core_hash_cache;
191     }
192
193   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
194
195   /** Hash code for the item. */
196   public int hashCode()
197     {
198       return _core_hash_cache;
199     }
200
201   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
202
203   /** Return the hash code that object would have provided for us so we have
204    * a (nearly) unique id for debugging.
205    */

206   protected int obj_hash()
207     {
208       return super.hashCode();
209     }
210
211   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
212
213   /** Convert to a string (separated out from toString() so we can call it
214    * from subclass that overrides toString()).
215    */

216   public String JavaDoc to_simple_string() throws internal_error
217     {
218       String JavaDoc result;
219       production_part part;
220
221       if (_the_production.lhs() != null &&
222       _the_production.lhs().the_symbol() != null &&
223       _the_production.lhs().the_symbol().name() != null)
224     result = _the_production.lhs().the_symbol().name();
225       else
226     result = "$$NULL$$";
227
228       result += " ::= ";
229
230       for (int i = 0; i<_the_production.rhs_length(); i++)
231     {
232       /* do we need the dot before this one? */
233       if (i == _dot_pos)
234         result += "(*) ";
235       
236       /* print the name of the part */
237       if (_the_production.rhs(i) == null)
238         {
239           result += "$$NULL$$ ";
240         }
241       else
242         {
243           part = _the_production.rhs(i);
244           if (part == null)
245         result += "$$NULL$$ ";
246           else if (part.is_action())
247         result += "{ACTION} ";
248           else if (((symbol_part)part).the_symbol() != null &&
249                        ((symbol_part)part).the_symbol().name() != null)
250         result += ((symbol_part)part).the_symbol().name() + " ";
251           else
252         result += "$$NULL$$ ";
253         }
254     }
255
256       /* put the dot after if needed */
257       if (_dot_pos == _the_production.rhs_length())
258     result += "(*) ";
259
260       return result;
261     }
262
263   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
264
265   /** Convert to a string */
266   public String JavaDoc toString()
267     {
268       /* can't throw here since super class doesn't, so we crash instead */
269       try {
270         return to_simple_string();
271       } catch(internal_error e) {
272     e.crash();
273     return null;
274       }
275     }
276
277   /*-----------------------------------------------------------*/
278
279 }
280    
281
Popular Tags