Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: java_cup/lr_item_core.java


1   
2   package java_cup;
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     java_cup.lalr_item
17   * @see     java_cup.lalr_item_set
18   * @see     java_cup.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 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 to_simple_string() throws internal_error
217     {
218       String 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 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