//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

package hlt.language.syntax;

import hlt.language.util.ArrayIndexed;

/**
 * This is the class of production rules used by the parser at parse
 * time. In contrast with a <tt>Grammar</tt>'s <tt>Rule</tt> (the class
 * of production rules used at parser construction time), this doesn't
 * need to store the whole sequence of symbols in the rule's body. At
 * parse time, all that is needed is:
 * <ol>
 * <li> the head symbol (what type of <tt>ParseNode</tt> to push on the
 *      parse stack); 
 * <li> the number of symbols in the rule (how far to pop the parse stack).
 * </ol>
 * Other than that, the actual rule's body is never used by <tt>GenericParser</tt>
 * or its subclasses,  nor by the code of <tt>semanticAction</tt> generated by
 * <tt>ParserGenerator</tt>.
 *
 * @see         Rule
 * @see         ParseNode
 * @see         GenericParser
 * @see         ParserGenerator
 *
 * @version     Last modified on Fri Apr 13 20:10:39 2012 by hak
 * @author      <a href="mailto:hak@acm.org">Hassan A&iuml;t-Kaci</a>
 * @copyright   &copy; <a href="http://www.hassan-ait-kaci.net/">by the author</a>
 */
public class ParserRule extends ArrayIndexed
{
  /**
   * The head symbol (the rule's LHS).
   */
  public ParserNonTerminal head;
  /**
   * The number of symbols in the rule's RHS.
   */
  public int length;

  /**
   * This rule's precedence.
   */
  int precedence = -1;

  /**
   * This rule's associativity.
   */
  int associativity = -1;

  /**
   * This is the rule's tag's index in the rule's sequence. It indicates
   * the position in this rule of the symbol ... If -1, the tag does not
   * correspond to any symbol in the rule (<i>i.e.</i>, either the
   * rule's tag is <tt>Grammar.EMPTY</tt> or it was set by
   * <tt>%prec</tt>).
   */
  int tagPosition = -1;


  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  // CONSTRUCTORS
  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

  public ParserRule (int head, int length, int index, int tagPosition)
    {
      super(GenericParser.rules,index);
      this.head = GenericParser.nonterminals[head];
      this.length = length;
      this.tagPosition = tagPosition;
    }

  public ParserRule (int head, int length, int index, int precedence, int associativity)
    {
      super(GenericParser.rules,index);
      this.head = GenericParser.nonterminals[head];
      this.length = length;
      this.precedence = precedence;
      this.associativity = associativity;
    }

  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  // XML serialization information
  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

  /**
   * A storage for recording xml annotation for this production rule if any.
   */
  private XmlInfo _xmlInfo = null;

  XmlInfo xmlInfo ()
    {
      return _xmlInfo;
    }
    
  public ParserRule setXmlInfo (XmlInfo info)
    {
      _xmlInfo = info;
      return this;
    }
  
  public ParserRule addXmlInfo (int[] children)
    {
      _xmlInfo.setChildren(children);
      return this;
    }
  
  public ParserRule addXmlInfo (int[][] xmlPaths)
    {
      _xmlInfo.setXmlPaths(xmlPaths);
      return this;
    }
  
  public ParserRule addXmlInfo (XmlWrapper[][] wrapperPaths)
    {
      _xmlInfo.setWrapperPaths(wrapperPaths);
      return this;
    }
  
  public ParserRule addXmlInfo (String[] attributeRefs)
    {
      _xmlInfo.setAttributeRefs(attributeRefs);
      return this;
    }
  
  public ParserRule addXmlInfo (XmlAttributeInfo[] attributes)
    {
      _xmlInfo.setAttributes(attributes);
      return this;
    }
  
  public ParserRule addXmlInfo (XmlTextInfo[][] infos)
    {
      _xmlInfo.setTextInfos(infos);
      return this;
    }
  
  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  // MISC.
  //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

  public String toString ()
    {
      return "[" + index() + "] " + head + " --> ";
    }

}
