/// <summary> /// Gets the set of terminal symbols that could follow the nonterminal symbol s /// in the current item-set. /// </summary> /// <param name="s"></param> /// <returns></returns> public IEnumerable <ITerminalSymbol> Follows(INonterminalSymbol s) { var result = new HashSet <ITerminalSymbol>(); foreach (var e in items.Where(i => !i.AtEnd && i.NextSymbol == s)) { ProductionRule rule = e.Rule; int index; for (index = e.DotPosition + 1; index < rule.rhs.Length; ++index) { foreach (var t in rule.rhs[index].First) { result.Add(t); } if (!rule.rhs[index].CanBeEmpty) { break; } } if (index == rule.rhs.Length) { // This wasn't documented properly I don't think // Also add the lookahead of the matched item if the rule can match at the end of the rule. result.Add(e.Lookahead[0]); } } return(result); }
public ShiftReduceConflict(ProductionRule ruleToShift, ProductionRule ruleToReduce) : base("Shift-reduce conflict") { ShiftRule = ruleToShift; ReduceRule = ruleToReduce; }
public ReduceReduceConflict(ProductionRule r1, ProductionRule r2) : base("Reduce-reduce conflict") { Rule1 = r1; Rule2 = r2; }
public Item(ProductionRule rule, int dotPosition, params ITerminalSymbol[] lookahead) { Rule = rule; DotPosition = dotPosition; Lookahead = lookahead; }