package java_cup;

import java.util.Stack;

/** This class represents an LALR item. Each LALR item consists of 
 *  a production, a "dot" at a position within that production, and
 *  a set of lookahead symbols (terminal).  (The first two of these parts
 *  are provide by the super class).  An item is designed to represent a 
 *  configuration that the parser may be in.  For example, an item of the 
 *  form: <pre>
 *    [A ::= B * C d E  , {a,b,c}]
 *  </pre>
 *  indicates that the parser is in the middle of parsing the production <pre>
 *    A ::= B C d E
 *  </pre>
 *  that B has already been parsed, and that we will expect to see a lookahead 
 *  of either a, b, or c once the complete RHS of this production has been 
 *  found.<p>
 *
 *  Items may initially be missing some items from their lookahead sets.  
 *  Links are maintained from each item to the set of items that would need 
 *  to be updated if symbols are added to its lookahead set.  During 
 *  "lookahead propagation", we add symbols to various lookahead sets and 
 *  propagate these changes across these dependency links as needed. 
 *  
 * @see     java_cup.lalr_item_set
 * @see     java_cup.lalr_state
 * @version last updated: 11/25/95
 * @author  Scott Hudson
 */
public class lalr_item extends lr_item_core {

  /*-----------------------------------------------------------*/
  /*--- Constructor(s) ----------------------------------------*/
  /*-----------------------------------------------------------*/

  /** Full constructor. 
   * @param prod the production for the item.
   * @param pos  the position of the "dot" within the production.
   * @param look the set of lookahead symbols.
   */
  public lalr_item(production prod, int pos, terminal_set look) 
    throws internal_error
    {
      super(prod, pos);
      _lookahead = look;
      _propagate_items = new Stack();
      needs_propagation = true;
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Constructor with default position (dot at start). 
   * @param prod the production for the item.
   * @param look the set of lookahead symbols.
   */
  public lalr_item(production prod, terminal_set look) throws internal_error
    {
      this(prod,0,look);
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Constructor with default position and empty lookahead set. 
   * @param prod the production for the item.
   */
  public lalr_item(production prod) throws internal_error
    {
      this(prod,0,new terminal_set());
    }

  /*-----------------------------------------------------------*/
  /*--- (Access to) Instance Variables ------------------------*/
  /*-----------------------------------------------------------*/

  /** The lookahead symbols of the item. */
  protected terminal_set _lookahead;

  /** The lookahead symbols of the item. */
  public terminal_set lookahead() {return _lookahead;};

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Links to items that the lookahead needs to be propagated to. */
  protected Stack _propagate_items; 

  /** Links to items that the lookahead needs to be propagated to */
  public Stack propagate_items() {return _propagate_items;}

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Flag to indicate that this item needs to propagate its lookahead 
   *  (whether it has changed or not). 
   */
  protected boolean needs_propagation;

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Add a new item to the set of items we propagate to. */
  public void add_propagate(lalr_item prop_to)
    {
      _propagate_items.push(prop_to);
      needs_propagation = true;
    }

  /*-----------------------------------------------------------*/
  /*--- General Methods ---------------------------------------*/
  /*-----------------------------------------------------------*/

  /** Propagate incoming lookaheads through this item to others need to 
   *  be changed.
   * @params incoming symbols to potentially be added to lookahead of this item.
   */
  public void propagate_lookaheads(terminal_set incoming) throws internal_error
    {
      boolean change = false;

      /* if we don't need to propagate, then bail out now */
      if (!needs_propagation && (incoming == null || incoming.empty()))
    return;

      /* if we have null incoming, treat as an empty set */
      if (incoming != null)
    {
      /* add the incoming to the lookahead of this item */
      change = lookahead().add(incoming);
    }

      /* if we changed or need it anyway, propagate across our links */
      if (change || needs_propagation)
    {
          /* don't need to propagate again */
          needs_propagation = false;

      /* propagate our lookahead into each item we are linked to */
      for (int i = 0; i < propagate_items().size(); i++)
        ((lalr_item)propagate_items().elementAt(i))
                      .propagate_lookaheads(lookahead());
    }
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Produce the new lalr_item that results from shifting the dot one position
   *  to the right. 
   */
  public lalr_item shift() throws internal_error
    {
      lalr_item result;

      /* can't shift if we have dot already at the end */
      if (dot_at_end())
    throw new internal_error("Attempt to shift past end of an lalr_item");

      /* create the new item w/ the dot shifted by one */
      result = new lalr_item(the_production(), dot_pos()+1, 
                        new terminal_set(lookahead()));

      /* change in our lookahead needs to be propagated to this item */
      add_propagate(result);

      return result;
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Calculate lookahead representing symbols that could appear after the
   *   symbol that the dot is currently in front of.  Note: this routine must
   *   not be invoked before first sets and nullability has been calculated
   *   for all non terminals. 
   */ 
  public terminal_set calc_lookahead(terminal_set lookahead_after) 
    throws internal_error
    {
      terminal_set    result;
      int             pos;
      production_part part;
      symbol          sym;

      /* sanity check */
      if (dot_at_end())
    throw new internal_error(
      "Attempt to calculate a lookahead set with a completed item");

      /* start with an empty result */
      result = new terminal_set();

      /* consider all nullable symbols after the one to the right of the dot */
      for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++) 
    {
       part = the_production().rhs(pos);

       /* consider what kind of production part it is -- skip actions */ 
       if (!part.is_action())
         {
           sym = ((symbol_part)part).the_symbol();

           /* if its a terminal add it in and we are done */
           if (!sym.is_non_term())
         {
           result.add((terminal)sym);
           return result;
         }
           else
         {
           /* otherwise add in first set of the non terminal */
           result.add(((non_terminal)sym).first_set());

           /* if its nullable we continue adding, if not, we are done */
           if (!((non_terminal)sym).nullable())
             return result;
         }
         }
    }

      /* if we get here everything past the dot was nullable 
         we add in the lookahead for after the production and we are done */
      result.add(lookahead_after);
      return result;
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Determine if everything from the symbol one beyond the dot all the 
   *  way to the  end of the right hand side is nullable.  This would indicate
   *  that the lookahead of this item must be included in the lookaheads of
   *  all items produced as a closure of this item.  Note: this routine should 
   *  not be invoked until after first sets and nullability have been 
   *  calculated for all non terminals. 
   */
  public boolean lookahead_visible() throws internal_error
    {
      production_part part;
      symbol          sym;

      /* if the dot is at the end, we have a problem, but the cleanest thing
     to do is just return true. */
      if (dot_at_end()) return true;

      /* walk down the rhs and bail if we get a non-nullable symbol */
      for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++)
    {
      part = the_production().rhs(pos);

      /* skip actions */
      if (!part.is_action())
        {
          sym = ((symbol_part)part).the_symbol();

          /* if its a terminal we fail */
          if (!sym.is_non_term()) return false;

          /* if its not nullable we fail */
          if (!((non_terminal)sym).nullable()) return false;
        }
    }

      /* if we get here its all nullable */
      return true;
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Equality comparison -- here we only require the cores to be equal since
   *   we need to do sets of items based only on core equality (ignoring 
   *   lookahead sets). 
   */
  public boolean equals(lalr_item other)
    {
      if (other == null) return false;
      return super.equals(other);
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Generic equality comparison. */
  public boolean equals(Object other)
    {
      if (!(other instanceof lalr_item)) 
    return false;
      else
    return equals((lalr_item)other);
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Return a hash code -- here we only hash the core since we only test core
   *  matching in LALR items. 
   */
  public int hashCode()
    {
      return super.hashCode();
    }

  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/

  /** Convert to string. */
  public String toString()
    {
      String result = "";

      // additional output for debugging:
      // result += "(" + hashCode() + ")"; 
      result += "[";
      result += super.toString();
      result += ", ";
      if (lookahead() != null)
    {
      result += "{";
      for (int t = 0; t < terminal.number(); t++)
        if (lookahead().contains(t))
          result += terminal.find(t).name() + " ";
      result += "}";
    }
      else
    result += "NULL LOOKAHEAD!!";
      result += "]";

      // additional output for debugging:
      // result += " -> ";
      // for (int i = 0; i<propagate_items().size(); i++)
      //   result += propagate_items().elementAt(i).hashCode() + " ";
      //
      // if (needs_propagation) result += " NP";

      return result;
    }
    /*-----------------------------------------------------------*/
};
