package java_cup;

/**
 * This class represents a part of a production which is a symbol (terminal or
 * non terminal). This simply maintains a reference to the symbol in question.
 *
 * @see java_cup.production
 * @version last updated: 11/25/95
 * @author Scott Hudson
 */
public class symbol_part extends production_part {

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

  /**
   * Full constructor.
   * 
   * @param sym the symbol that this part is made up of.
   * @param lab an optional label string for the part.
   */
  public symbol_part(symbol sym, String lab) throws internal_error {
    super(lab);

    if (sym == null)
      throw new internal_error("Attempt to construct a symbol_part with a null symbol");
    _the_symbol = sym;
  }

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

  /**
   * Constructor with no label.
   * 
   * @param sym the symbol that this part is made up of.
   */
  public symbol_part(symbol sym) throws internal_error {
    this(sym, null);
  }

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

  /** The symbol that this part is made up of. */
  protected symbol _the_symbol;

  /** The symbol that this part is made up of. */
  public symbol the_symbol() {
    return _the_symbol;
  }

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

  /** Respond that we are not an action part. */
  @Override
  public boolean is_action() {
    return false;
  }

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

  /** Equality comparison. */
  public boolean equals(symbol_part other) {
    return other != null && super.equals(other) && the_symbol().equals(other.the_symbol());
  }

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

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

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

  /** Produce a hash code. */
  @Override
  public int hashCode() {
    return super.hashCode() ^ (the_symbol() == null ? 0 : the_symbol().hashCode());
  }

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

  /** Convert to a string. */
  @Override
  public String toString() {
    if (the_symbol() != null)
      return super.toString() + the_symbol();
    else
      return super.toString() + "$$MISSING-SYMBOL$$";
  }

  /*-----------------------------------------------------------*/

}
