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(); } }
/// <remarks>Solves only 1-level indirect recursion</remarks> internal void SolveIndirectLeftRecusrion() { var newRHS = new List <Expression>(RHSList.Count + 10); foreach (var exp in RHSList) { if ((exp[0] as NonTerminalSymbol)?.RHSList.Any(re => re.Value[0] == this) ?? false) { newRHS.AddRange((exp[0] as NonTerminalSymbol).RHSList.Select(re => re.Append(exp.SubExpression(1)))); } else { newRHS.Add(exp); } } RHSList.Clear(); RHSList.AddRange(newRHS); SolveLeftRecursion(CalcAlphas()); }