void ReadCFGFromConsole() { var lines = new List <string>(); string line; while (!string.IsNullOrEmpty(line = Console.ReadLine())) { lines.Add(line); } Thecfg = CFG.FromProductionStrings(lines); Algo = new LL1Algo(Thecfg); Algo.Compute(); }
/// <exception cref="NotComputedException"></exception> public static FollowComputer Compute(LL1Algo algo) { _ = algo.Nullable ?? throw new NotComputedException(nameof(algo.Nullable)); _ = algo.First ?? throw new NotComputedException(nameof(algo.First)); var iterations = new List <FollowTable>(); var follow = new FollowTable(); // initialize first iteration foreach (var A in algo.Thecfg.Nonterminals) { follow.Add(A, new FollowResult()); } do { if (iterations.Count == 0) { iterations.Add(follow); } else { iterations.Add(DictUtil.Clone(follow)); } follow = iterations.Last(); foreach (var prod in algo.Thecfg.Productions) { for (int i = 0; i < prod.Rhs.Count; ++i) { var Bi = prod.Rhs[i]; if (Bi.Type == Symbol.Types.NonTerminal) { // test Bi+1,...,Bk var rest = prod.Rhs.Skip(i + 1); follow[Bi].UnionWith(algo.First.Sequence(rest)); if (rest.All(e => e.Type == Symbol.Types.NonTerminal && algo.Nullable[e]) || i == prod.Rhs.Count - 1) { follow[Bi].UnionWith(follow[prod.Lhs]); } } } } // stop loop if no changes between iterations } while (iterations.Count == 1 || !DictUtil.Equal(follow, iterations[iterations.Count - 2])); return(new FollowComputer(algo, iterations)); }
/// <exception cref="NotComputedException"></exception> public static FirstComputer Compute(LL1Algo algo) { _ = algo.Nullable ?? throw new NotComputedException(nameof(algo.Nullable)); var iterations = new List <FirstTable>(); var first = new FirstTable(); // initialize first iteration foreach (var A in algo.Thecfg.Nonterminals) { first.Add(A, new FirstResult()); } do { if (iterations.Count == 0) { iterations.Add(first); } else { iterations.Add(DictUtil.Clone(first)); } first = iterations.Last(); foreach (var prod in algo.Thecfg.Productions) { foreach (var Bi in prod.Rhs) { if (Bi.Type == Symbol.Types.Terminal) { first[prod.Lhs].Add(Bi); break; } else { first[prod.Lhs].UnionWith(first[Bi]); } if (!algo.Nullable[Bi]) { break; } } } // stop loop if no changes between iterations } while (iterations.Count == 1 || !DictUtil.Equal(first, iterations[iterations.Count - 2])); return(new FirstComputer(algo, iterations)); }
public static NullableComputer Compute(LL1Algo algo) { var iterations = new List <NullableTable>(); var nullable = new NullableTable(); // initialize first iteration foreach (var A in algo.Thecfg.Nonterminals) { nullable.Add(A, false); } do { if (iterations.Count == 0) { iterations.Add(nullable); } else { iterations.Add(new NullableTable(nullable)); } nullable = iterations.Last(); foreach (var prod in algo.Thecfg.Productions) { if (prod.DerivesToNull || prod.Rhs.All(e => e.Type == Symbol.Types.NonTerminal && nullable[e])) { nullable[prod.Lhs] = true; } } // stop loop if no changes between iterations } while (iterations.Count == 1 || nullable.Except(iterations[iterations.Count - 2]).Any()); return(new NullableComputer(algo, iterations)); }
/// <exception cref="NotComputedException"></exception> public static Parse Compute(LL1Algo algo) { _ = algo.Nullable ?? throw new NotComputedException(nameof(algo.Nullable)); _ = algo.First ?? throw new NotComputedException(nameof(algo.First)); _ = algo.Follow ?? throw new NotComputedException(nameof(algo.Follow)); // init 2d dict var parset = new ParseTable(); foreach (var A in algo.Thecfg.Nonterminals) { parset.Add(A, new ParseTableRow()); foreach (var a in algo.Thecfg.Terminals) { parset[A].Add(a, new ParseTableResult()); } } // do algo foreach (var prod in algo.Thecfg.Productions) { foreach (var a in algo.First.Sequence(prod.Rhs)) { parset[prod.Lhs][a].Add(prod); } if (algo.Nullable.Sequence(prod.Rhs)) { foreach (var a in algo.Follow[prod.Lhs]) { parset[prod.Lhs][a].Add(prod); } } } return(new Parse(algo, parset)); }
private Parse(LL1Algo algo, ParseTable result) : base(algo) { _Result = result; Parsable = result.All(dict => dict.Value.All(e => e.Value.Count <= 1)); }
private FollowComputer(LL1Algo algo, List <FollowTable> iterations) : base(algo) { Iterations = iterations; }
protected AbstractComputer(LL1Algo algo) { Algo = algo; }
private FirstComputer(LL1Algo algo, List <FirstTable> iterations) : base(algo) { Iterations = iterations; }
private NullableComputer(LL1Algo algo, List <NullableTable> iterations) : base(algo) { Iterations = iterations; }