//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\ //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ using System.Text; using System.Collections; using Ilog.Language.Util; namespace Ilog.Language.Syntax { /** * This is the class of LR(0) items. An LR(0) item consists of a pair * (rule,mark) where mark is the index of the dot in * the RHS. Dot marks range from 1 to rule.Sequence.Length. * * @version Last modified on Sat May 21 20:04:50 2005 by hak * @author Hassan Aït-Kaci * @copyright © 2000 ILOG, S.A. */ internal class Item : ArrayListIndexed { /** * Constructs an Item with the specified reference rule, item * index, and mark position. */ internal Item (Rule rule, int index, int mark) : base(grammar.Items,index) { this.rule = rule; this.mark = mark; } /** The grammar this symbol belongs to. */ private static Grammar grammar = Grammar.currentGrammar; /** The rule referred to by this item. */ private Rule rule; internal Rule @Rule { get { return rule; } } /** The mark of the dot (= 1,...,length). */ private int mark; /** * The FIRST set of the sequence that follows the symbol after the dot; * that is, the value of FIRST(S) if this item is of the form A -> P.BS. */ private SetOf suffixFirst; internal SetOf SuffixFirst { get { return suffixFirst; } } /** * This is true iff this item is of the form A -> P.BS * and all the symbols in FIRST(S) derive the empty symbol. */ private bool isNullable = true; internal bool IsNullable { get { return isNullable; } } /** * This is true iff this item has a dot at the left end * of the RHS. */ internal bool IsInitial { get { return mark == 1; } } /** * This is true iff this item has a dot at the right end * of the RHS. */ internal bool IsFinal { get { return mark == rule.Sequence.Length; } } /** * This is true iff this item is empty production. */ internal bool IsEmpty { get { return IsInitial && IsFinal; } } /** * This is the grammar symbol that is immediately after the dot in * this item. If the dot is at the right end of the RHS, returns * the EMPTY symbol. */ internal GrammarSymbol Marker { get { return IsFinal ? Grammar.EMPTY : rule.Sequence[mark]; } } /** * This is true iff the marker is a nonterminal. */ internal bool MarkerIsNonTerminal { get { return Marker is NonTerminal; } } /** * This is the item obtained from this one by shifting the dot * over one position to the right. If the dot is at the end of the * rule's RHS, it is this item. */ internal Item Shift { get { return IsFinal ? this : grammar.GetItem(rule,mark+1); } } /** * This is the item obtained from this one by shifting the dot * over one position to the left. If the dot is at the beginning * of the rule's RHS, it is this item. */ internal Item Unshift { get { return IsInitial ? this : grammar.GetItem(rule,mark-1); } } /** * This is true iff this item is a kernel item (see * definition on page 223 of the Dragon Book). */ internal bool IsKernel { get { return IsInitial ? rule.Head.IsSTART : (mark > 1); } } /** * Computes the FIRST set of the suffix of this item past the * symbol after the dot; that is, the value of FIRST(S) if this * item is of the form A -> P.BS. See Dragon Book, page 189. */ internal void ComputeSuffixFirst () { suffixFirst = new SetOf(grammar.Terminals); for (int i=mark+1; itrue iff this changes the previous set. */ internal bool AddPred (State state, State from) { SetOf preds = Pred(state); if (preds[from]) return false; preds.Add(from); return true; } /** * Update PRED(state,this) with froms set of states, and returns * true iff this changes the previous set. */ internal bool AddPred (State state, SetOf froms) { SetOf preds = Pred(state); if (froms <= preds) return false; preds.Union(froms); return true; } /** * A table associating to each state in which this item occurs a * set of terminal symbols which are the lookahead symbols that * propagate to this item in that state. */ private Hashtable lookaheadTable; /** * Initializes and returns this item's lookahead set in the given * state. */ internal SetOf InitLookaheads (State state) { if (lookaheadTable == null) lookaheadTable = new Hashtable(); SetOf symbols = new SetOf(grammar.Terminals); lookaheadTable[state] = symbols; return symbols; } /** * Returns the set of lookahead symbols for this item in the given * state. NB: No check is made for null table or entry because, by * construction, it will always be used for a state for which this * is not the case. */ internal SetOf GetLookaheads (State state) { return (SetOf)lookaheadTable[state]; } /** * Returns true iff the specified object denotes the same item. */ public override bool Equals (object other) { if (!(other is Item)) return false; return index == ((Item)other).index; } /** * Returns a hash code for this Item. */ public override int GetHashCode () { return index; } /** * Returns a string description for this item of the form * of a rule with a dot (.) indicating the mark position. */ public override string ToString () { StringBuilder s = new StringBuilder(); s.Append("[") .Append(rule.Index) .Append("] ") .Append(rule.Sequence[0]) .Append(" -->"); for (int i=1; i