+++ /dev/null
-
-package java_cup;
-
-/** The "core" of an LR item. This includes a production and the position
- * of a marker (the "dot") within the production. Typically item cores
- * are written using a production with an embedded "dot" to indicate their
- * position. For example: <pre>
- * A ::= B * C d E
- * </pre>
- * This represents a point in a parse where the parser is trying to match
- * the given production, and has succeeded in matching everything before the
- * "dot" (and hence is expecting to see the symbols after the dot next). See
- * lalr_item, lalr_item_set, and lalr_start for full details on the meaning
- * and use of items.
- *
- * @see java_cup.lalr_item
- * @see java_cup.lalr_item_set
- * @see java_cup.lalr_state
- * @version last updated: 11/25/95
- * @author Scott Hudson
-*/
-
-public class lr_item_core {
-
- /*-----------------------------------------------------------*/
- /*--- Constructor(s) ----------------------------------------*/
- /*-----------------------------------------------------------*/
-
- /** Full constructor.
- * @param prod production this item uses.
- * @param pos position of the "dot" within the item.
- */
- public lr_item_core(production prod, int pos) throws internal_error
- {
- symbol after_dot = null;
- production_part part;
-
- if (prod == null)
- throw new internal_error(
- "Attempt to create an lr_item_core with a null production");
-
- _the_production = prod;
-
- if (pos < 0 || pos > _the_production.rhs_length())
- throw new internal_error(
- "Attempt to create an lr_item_core with a bad dot position");
-
- _dot_pos = pos;
-
- /* compute and cache hash code now */
- _core_hash_cache = 13*_the_production.hashCode() + pos;
-
- /* cache the symbol after the dot */
- if (_dot_pos < _the_production.rhs_length())
- {
- part = _the_production.rhs(_dot_pos);
- if (!part.is_action())
- _symbol_after_dot = ((symbol_part)part).the_symbol();
- }
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Constructor for dot at start of right hand side.
- * @param prod production this item uses.
- */
- public lr_item_core(production prod) throws internal_error
- {
- this(prod,0);
- }
-
- /*-----------------------------------------------------------*/
- /*--- (Access to) Instance Variables ------------------------*/
- /*-----------------------------------------------------------*/
-
- /** The production for the item. */
- protected production _the_production;
-
- /** The production for the item. */
- public production the_production() {return _the_production;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** The position of the "dot" -- this indicates the part of the production
- * that the marker is before, so 0 indicates a dot at the beginning of
- * the RHS.
- */
- protected int _dot_pos;
-
- /** The position of the "dot" -- this indicates the part of the production
- * that the marker is before, so 0 indicates a dot at the beginning of
- * the RHS.
- */
- public int dot_pos() {return _dot_pos;}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Cache of the hash code. */
- protected int _core_hash_cache;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Cache of symbol after the dot. */
- protected symbol _symbol_after_dot = null;
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Is the dot at the end of the production? */
- public boolean dot_at_end()
- {
- return _dot_pos >= _the_production.rhs_length();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the symbol after the dot. If there is no symbol after the dot
- * we return null. */
- public symbol symbol_after_dot()
- {
- /* use the cached symbol */
- return _symbol_after_dot;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Determine if we have a dot before a non terminal, and if so which one
- * (return null or the non terminal).
- */
- public non_terminal dot_before_nt()
- {
- symbol sym;
-
- /* get the symbol after the dot */
- sym = symbol_after_dot();
-
- /* if it exists and is a non terminal, return it */
- if (sym != null && sym.is_non_term())
- return (non_terminal)sym;
- else
- return null;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Produce a new lr_item_core that results from shifting the dot one
- * position to the right.
- */
- public lr_item_core shift_core() throws internal_error
- {
- if (dot_at_end())
- throw new internal_error(
- "Attempt to shift past end of an lr_item_core");
-
- return new lr_item_core(_the_production, _dot_pos+1);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison for the core only. This is separate out because we
- * need separate access in a super class.
- */
- public boolean core_equals(lr_item_core other)
- {
- return other != null &&
- _the_production.equals(other._the_production) &&
- _dot_pos == other._dot_pos;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Equality comparison. */
- public boolean equals(lr_item_core other) {return core_equals(other);}
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Generic equality comparison. */
- public boolean equals(Object other)
- {
- if (!(other instanceof lr_item_core))
- return false;
- else
- return equals((lr_item_core)other);
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Hash code for the core (separated so we keep non overridden version). */
- public int core_hashCode()
- {
- return _core_hash_cache;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Hash code for the item. */
- public int hashCode()
- {
- return _core_hash_cache;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Return the hash code that object would have provided for us so we have
- * a (nearly) unique id for debugging.
- */
- protected int obj_hash()
- {
- return super.hashCode();
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string (separated out from toString() so we can call it
- * from subclass that overrides toString()).
- */
- public String to_simple_string() throws internal_error
- {
- String result;
- production_part part;
-
- if (_the_production.lhs() != null &&
- _the_production.lhs().the_symbol() != null &&
- _the_production.lhs().the_symbol().name() != null)
- result = _the_production.lhs().the_symbol().name();
- else
- result = "$$NULL$$";
-
- result += " ::= ";
-
- for (int i = 0; i<_the_production.rhs_length(); i++)
- {
- /* do we need the dot before this one? */
- if (i == _dot_pos)
- result += "(*) ";
-
- /* print the name of the part */
- if (_the_production.rhs(i) == null)
- {
- result += "$$NULL$$ ";
- }
- else
- {
- part = _the_production.rhs(i);
- if (part == null)
- result += "$$NULL$$ ";
- else if (part.is_action())
- result += "{ACTION} ";
- else if (((symbol_part)part).the_symbol() != null &&
- ((symbol_part)part).the_symbol().name() != null)
- result += ((symbol_part)part).the_symbol().name() + " ";
- else
- result += "$$NULL$$ ";
- }
- }
-
- /* put the dot after if needed */
- if (_dot_pos == _the_production.rhs_length())
- result += "(*) ";
-
- return result;
- }
-
- /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
-
- /** Convert to a string */
- public String toString()
- {
- /* can't throw here since super class doesn't, so we crash instead */
- try {
- return to_simple_string();
- } catch(internal_error e) {
- e.crash();
- return null;
- }
- }
-
- /*-----------------------------------------------------------*/
-
-}
-