private void SolveLeftRecursion(IEnumerable <Symbol>[] alphas) { if (alphas.Length == 0) { return; } var primeSymbol = Grammer.AddRule(); primeSymbol.RHSList.Add(Expression.E); foreach (var alpha in alphas) { primeSymbol.RHSList.Add(Expression.Create(alpha.Append(primeSymbol))); } var betas = RHSList.Where(e => e.Value[0] != this).ToArray(); RHSList.Clear(); foreach (var beta in betas) { if (beta.IsEpsilon) { RHSList.Add(Expression.Create(primeSymbol)); } else { RHSList.Add(beta.Append(primeSymbol)); } } //here we should apply left factoring on the prime symbol but the Grammer will do that. }
public static Grammer Create(IEnumerable <char> alphabet, IEnumerable <string> rules, bool eleminateExtraRules) { var result = new Grammer(alphabet, rules); result.Fix(); if (eleminateExtraRules) { result.EleminateExtralRules(); } return(result); }
internal void ApplyLeftFactoring() { var trie = TrieNode.CreateRoot(); foreach (var exp in RHSList) { if (exp.IsEpsilon) { continue; } trie.AddExpression(exp); } var alphas = trie.GetMinCommonExpressions(); alphas.Add(Expression.E); var groupedExpressions = alphas.ToDictionary(a => a, a => new List <Expression>()); //Group them by there alpha and if non then epsilon is its alpha foreach (var exp in RHSList) { var expAlpha = alphas.FirstOrDefault(a => exp.StartsWith(a)) ?? Expression.E; groupedExpressions[expAlpha].Add(exp); } RHSList.Clear(); var primes = new List <NonTerminalSymbol>(); foreach (var grp in groupedExpressions) { if (grp.Key == Expression.E) { RHSList.AddRange(grp.Value); } else { var primeSymbol = Grammer.AddRule(); primeSymbol.RHSList.AddRange(grp.Value.Select(e => e.SubExpression(grp.Key.Count))); RHSList.Add(Expression.Create(grp.Key.Value.Append(primeSymbol))); primes.Add(primeSymbol); } } foreach (var prime in primes) { prime.ApplyLeftFactoring(); } }
internal NonTerminalSymbol(char val, bool isStartSymbol, Grammer grammer) : base(val) { Grammer = grammer; IsStartSymbol = isStartSymbol; }