Пример #1
0
        LRNode Closure(LRNode node)
        {
            bool isChanged = true;

            while (isChanged)
            {
                isChanged = false;
                int prevCount = node.Elements.Count;
                HashSet <LRNodeElement> toAdd = new HashSet <LRNodeElement>();
                foreach (var element in node.Elements)
                {
                    var rule = element.GrammarRule;
                    if (rule.DotPos >= rule.ProductionElements.Count)
                    {
                        continue;
                    }
                    var pe   = rule.ProductionElements[rule.DotPos];
                    var next = rule.DotPos + 1 < rule.ProductionElements.Count ? rule.ProductionElements[rule.DotPos + 1] : new EpsilonProduction();
                    if (pe is NonTerminalProduction)
                    {
                        foreach (var r in grammarBuilder.NonTerminals[pe.Name].GetAllRules())
                        {
                            foreach (var terminal in CalculateFirst(next, element.TerminalProduction))
                            {
                                toAdd.Add(new LRNodeElement(r.Clone(), terminal));
                            }
                        }
                    }
                }

                foreach (var e in toAdd)
                {
                    node.Elements.Add(e);
                }
                if (node.Elements.Count != prevCount)
                {
                    isChanged = true;
                }
            }

            return(node);
        }
Пример #2
0
        /// <summary>
        /// GOTO function from dragonbook
        /// </summary>
        /// <param name="I"></param>
        /// <param name="X"></param>
        /// <returns></returns>
        LRNode Goto(LRNode I, IProductionElement X)
        {
            LRNode node = new LRNode();

            foreach (var e in I.Elements)
            {
                var rule     = e.GrammarRule;
                var terminal = e.TerminalProduction;
                if (rule.DotPos < rule.ProductionElements.Count)
                {
                    var pe = rule.ProductionElements[rule.DotPos];
                    //TODO : think about removing first part of condition.
                    if (pe.GetType().Equals(X.GetType()) && X.Name.Equals(pe.Name))
                    {
                        var newRule = rule.Clone();
                        newRule.DotPos++;
                        node.Elements.Add(new LRNodeElement(newRule, terminal));
                    }
                }
            }
            return(Closure(node));
        }