protected virtual void PopulateNextCache() { for (int i = 0; i < TargetGrammar.Count; i++) { var r = initialListing[TargetGrammar[i]]; for (int j = 0; j < r.Count; j++) { AdvanceableProduction prod = r[j]; while (prod.HasNext) { var tmp = prod.FunctionalNext(); advancementDict[prod] = tmp; prod = tmp; } advancementDict[prod] = prod; terminates[prod] = new AdvanceableRule(r.Name); terminates[prod].Add(prod); } } }
private string ToString0(AdvanceableProduction production) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("[{0} => ",Name); for(int i = 0;i < production.Min; i++) sb.AppendFormat("{0} ", production[i]); sb.Append("!"); for(int i = production.Min;i < production.Position; i++) sb.AppendFormat("{0} ", production[i]); sb.Append("@"); for(int i = production.Position; i < production.Max; i++) sb.AppendFormat("{0} ", production[i]); sb.AppendFormat(", {0}]", LookaheadSymbol); return sb.ToString(); }
public override IEnumerable <LookaheadRule> Closure( IEnumerable <LookaheadRule> rules, string terminateSymbol) { //Closure is more refined. //If [A → α • B β, a] belongs to the set of items, //and B → γ is a production of the grammar, //then we add the item [B → • γ, b] for all b in FIRST(β a). HashSet <LookaheadRule> rr = new HashSet <LookaheadRule>(rules); int size = currentRules.Count; do { size = rr.Count; //get rid of the foreach (var rule in rr) { var a = rule.LookaheadSymbol; var container = singles[rule.Name][rule.LookaheadSymbol]; for (int j = 0; j < rule.Count; j++) { var p = rule[j]; string symbol = p.Current; if (!p.HasNext) { nullTerminators.Add(terminates[p]); } else { if (TargetGrammar.Exists(symbol)) { AdvanceableProduction betaProd = advancementDict[p]; //create beta var target = initialListing[TargetGrammar[symbol]]; //grab the B-Production var actualTarget = memo[target]; if (!betaProd.HasNext && a.Equals(terminateSymbol)) { currentRules.Add(actualTarget[terminateSymbol]); } else { if (betaProd.HasNext) { var next = container[p]; var ff = First(next, betaProd.Position); foreach (var v in ff) { currentRules.Add(actualTarget[v]); } } currentRules.Add(actualTarget[a]); } } } } } rr.UnionWith(currentRules); currentRules.Clear(); }while(rr.Count != size); for (int n = 0; n < nullTerminators.Count; n++) { var v = nullTerminators[n]; string name = v.Name; foreach (var s in rr) { if (s.Name.Equals(name)) { foreach (var qq in v) { if (!s.Contains(qq)) { s.Add(qq); } } } } } if (nullTerminators.Count > 0) { nullTerminators.Clear(); } if (currentRules.Count > 0) { currentRules.Clear(); } return(rr); }