public bool Equals( LR0Item other ) { return !object.ReferenceEquals(other, null) && this.rule.Equals(other.rule) && this.cursor_pos == other.cursor_pos; }
/// <summary> /// Calculates and returns the closure of the given canonical set. /// </summary> /// <param name="set">Get the closure of this set.</param> /// <param name="grammar">The set belongs to this grammar.</param> /// <returns>The closure of the given <paramref name="set"/>.</returns> /// <exception cref="ArgumentNullException"> if any of the parameters is <c>null</c>.</exception> public static ISet<LR0Item> Closure( ISet<LR0Item> set, RestrictedStartSymbolGrammar grammar ) { if( object.ReferenceEquals(set, null) ) throw new ArgumentNullException("set"); if( object.ReferenceEquals(grammar, null) ) throw new ArgumentNullException("grammar"); var closure = new List<LR0Item>(set); for( int i = 0; i < closure.Count; ++i ) { var item = closure[i]; // Skip this, if the cursor pos is on the end if( item.CursorPosition == item.Rule.RightHandSide.Count ) continue; // Skip this, if the next_symbol is not grammatical var next_symbol = item.Rule.RightHandSide[item.CursorPosition]; if( !(next_symbol is GrammaticalSymbol) ) continue; // Get all the rules whit next_symbol on the left hand side var rules = from rule in grammar.Rules where rule.LeftHandSide.Equals(next_symbol) select rule; // Add all the generated RL(0) items to the closure foreach( var rule in rules ) { var new_item = new LR0Item(rule, 0); if( !closure.Contains(new_item) ) closure.Add(new_item); } } return new HashSet<LR0Item>(closure); }