예제 #1
0
        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();
            }
        }
예제 #2
0
        /// <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());
        }