public static Dictionary <object, HashSet <SyntaxPredicate> > CalculateFollowSet( List <ProductionRule> productionRules, Dictionary <object, HashSet <SyntaxPredicate> > firstSet) { var result = new Dictionary <object, HashSet <SyntaxPredicate> >(); foreach (var key in firstSet.Keys) { result.Add(key, new HashSet <SyntaxPredicate>()); } bool updated = true; while (updated) { updated = false; foreach (var productionRule in productionRules) { int i = 0; for (; i < productionRule.Predicates.Count; ++i) { if (productionRule.Predicates[i] is KeyedNonTerminalPredicate kp) { bool epl = true; for (int j = i + 1; j < productionRule.Predicates.Count; ++j) { if (productionRule.Predicates[j] is TerminalPredicate tp) { epl = false; updated |= result[kp.Key].Add(tp); break; } if (productionRule.Predicates[j] is KeyedNonTerminalPredicate kp2) { var f = firstSet[kp2.Key]; foreach (var source in f.Except(EpsilonPredicate.Enumerator())) { updated |= result[kp.Key].Add(source); } if (!f.Contains(EpsilonPredicate.Instance)) { epl = false; break; } } } if (epl) { foreach (var sp in result[productionRule.Key].Except(EpsilonPredicate.Enumerator())) { updated |= result[kp.Key].Add(sp); } } } } } } return(result); }
public static Dictionary <object, HashSet <SyntaxPredicate> > CalculateFirstSet(List <ProductionRule> productionRules) { var result = new Dictionary <object, HashSet <SyntaxPredicate> >(); foreach (var productionRule in productionRules) { if (!result.ContainsKey(productionRule.Key)) { result.Add(productionRule.Key, new HashSet <SyntaxPredicate>()); } } bool updated = true; while (updated) { updated = false; foreach (var productionRule in productionRules) { var key = productionRule.Key; if (productionRule.Length == 0) { updated |= result[key].Add(EpsilonPredicate.Instance); continue; } bool epl = true; foreach (var predicate in productionRule.Predicates) { if (predicate is TerminalPredicate) { updated |= result[key].Add(predicate); epl = false; break; } if (predicate is KeyedNonTerminalPredicate kp) { var t = kp.Key; var tset = result[t].Except(EpsilonPredicate.Enumerator()); foreach (var syntaxPredicate in tset) { updated |= result[key].Add(syntaxPredicate); } if (!result[t].Contains(EpsilonPredicate.Instance)) { epl = false; break; } } } if (epl) { updated |= result[key].Add(EpsilonPredicate.Instance); } } } return(result); }