public static ParseState Closure(this IEnumerable<Item> items, Grammar grammar)
        {
            HashSet<Item> closure = new HashSet<Item>(items);
            HashSet<Item> toAdd = new HashSet<Item>();

            do
            {
                toAdd.Clear();
                foreach (var item in closure)
                {
                    if (item.Position == item.Production.Body.Length)
                        continue;

                    BnfTerm term = item.Production.Body[item.Position];

                    if (term is NonTerminal)
                    {
                        NonTerminal nonTerm = term as NonTerminal;
                        foreach (var production in grammar.Productions.Where(a => a.Head.Equals(nonTerm)))
                            toAdd.Add(new Item(production, 0));
                    }
                }
            }
            while (closure.UnionWithAddedCount(toAdd) > 0);

            return new ParseState(closure, IsAcceptingState(closure, grammar));
        }
Example #2
0
        public static Automaton CreateAutomaton(Grammar g)
        {
            //initialise to closure of start item
            HashSet<ParseState> states = new HashSet<ParseState>();
            states.Add(g.Productions.Where(a => a.Head.Equals(g.Root)).Select(a => new Item(a, 0)).Closure(g));

            HashSet<ParseStateTransition> transitions = new HashSet<ParseStateTransition>();

            HashSet<ParseState> sToAdd = new HashSet<ParseState>();
            HashSet<ParseStateTransition> tToAdd = new HashSet<ParseStateTransition>();

            do
            {
                sToAdd.Clear();
                tToAdd.Clear();

                foreach (var state in states)
                {
                    foreach (var item in state)
                    {
                        if (item.Production.Body.Length == item.Position)
                            continue;

                        BnfTerm term = item.Production.Body[item.Position];
                        ParseState j = state.Goto(term, g);

                        sToAdd.Add(j);
                        tToAdd.Add(new ParseStateTransition(state, term, j));
                    }
                }
            }
            while (states.UnionWithAddedCount(sToAdd) != 0 | transitions.UnionWithAddedCount(tToAdd) != 0);

            return new Automaton(transitions, g);
        }