Example #1
0
        // returns either a list of successfull parsed results or a singleton list with failure
        private IEnumerable <ItParseResult <TSymbol> > ParseTerm(TSymbol term, MemoizedInput <ParseLeaf <TSymbol> > word, MemoizedInput <ParseLeaf <TSymbol> > .Iterator iterator)
        {
            var dfa = _grammar.Automatons[term];
            // stack for backtracking - <position in word, current state of appropriate DFA>
            var  st       = new Stack <ParseState>();
            var  children = new Stack <IParseTree <TSymbol> >();
            bool accepted = false;
            var  eof      = ParserUtils <TSymbol> .GetEOF();

            ItError <TSymbol> furthest = null;

            st.Push(new ParseState(dfa.Start, 0, iterator));

            while (st.Any())
            {
                var     parseState    = st.Peek();
                var     node          = parseState.State;
                var     it            = parseState.Iterator;
                TSymbol currentSymbol = (it != word.End) ? it.Current.Symbol : eof;

                if (node.Accepting > 0 && (currentSymbol.Equals(eof) || _grammar.Follow[term].Contains(currentSymbol)))
                {
                    accepted = true;
                    var parsedChildren = children.ToList();
                    parsedChildren.Reverse();
                    var parsedTree = new ParseBranch <TSymbol>(
                        iterator != word.End ? GetFragmentRange(
                            iterator.Current.Fragment,
                            (children.Any() ? children.Peek().Fragment : iterator.Current.Fragment)) : null,
                        term,
                        _grammar.WhichProduction[node.Accepting],
                        parsedChildren);

                    yield return(new ItOK <TSymbol>(parsedTree, it));
                }

                var trans = node.Transitions;
                var ind   = parseState.TransitionIndex;
                for (; ind < trans.Count; ind++)
                {
                    if (GrammarUtils <TSymbol> .IsDead(trans[ind].Value))
                    {
                        continue;
                    }
                    if (_grammar.InFirstPlus(trans[ind].Key, currentSymbol))
                    {
                        if (trans[ind].Key.IsTerminal)
                        {
                            children.Push(new ParseLeaf <TSymbol>(it != word.End ? it.Current.Fragment : null, currentSymbol)); // TODO It would be better to have special END fragment
                            st.Push(new ParseState(trans[ind].Value, 0, it != word.End ? it.Next() : word.End));
                            break;
                        }
                        else
                        {
                            IEnumerator <ItParseResult <TSymbol> > resultIt = ParseTerm(trans[ind].Key, word, it).GetEnumerator();
                            resultIt.MoveNext();
                            if (resultIt.Current)
                            {
                                var res = resultIt.Current as ItOK <TSymbol>;
                                children.Push(res.Tree);
                                st.Push(new ParseState(trans[ind].Value, 0, res.Iterator, resultIt));
                                break;
                            }
                            else
                            {
                                var res = resultIt.Current as ItError <TSymbol>;
                                if (furthest == null || res.Iterator > furthest.Iterator)
                                {
                                    furthest = res;
                                }
                            }
                        }
                    }
                }
                parseState.TransitionIndex = ind;

                // could not find next parsing transition
                if (ind >= trans.Count)
                {
                    if (furthest == null || it > furthest.Iterator)
                    {
                        furthest = new ItError <TSymbol>(it, term);
                    }
                    Backtrack(st, children);
                }
            }

            if (accepted)
            {
                yield break;
            }
            else
            {
                yield return(furthest ?? new ItError <TSymbol>(iterator, term));
            }
        }
        private ItParseResult <TSymbol> ParseTerm(TSymbol term, MemoizedInput <ParseLeaf <TSymbol> > word, MemoizedInput <ParseLeaf <TSymbol> > .Iterator input)
        {
            var dfa      = _grammar.Automatons[term];
            var children = new List <IParseTree <TSymbol> >();

            var it    = input;
            var state = dfa.Start;
            var eof   = ParserUtils <TSymbol> .GetEOF();

            var builder = new LookaheadDfaBuilder <TSymbol>();

            while (true)
            {
                LookaheadDfa <TSymbol> lookeaheadDfa = builder.Build(_grammar, it.Current.Symbol /* ? */, state);
                var     lookState     = lookeaheadDfa.Start;
                TSymbol currentSymbol = (it != word.End) ? it.Current.Symbol : eof;

                if (state.Accepting > 0 && _grammar.Follow[term].Contains(currentSymbol))
                {
                    var parsedTree = new ParseBranch <TSymbol>(
                        GetFragmentRange(input.Current.Fragment, children.Last().Fragment),
                        term,
                        _grammar.WhichProduction[state.Accepting],
                        children);

                    return(new ItOK <TSymbol>(parsedTree, it));
                }

                var lookIt = it;
                while (lookState.Accepting == 0)
                {
                    TSymbol lookSym = (lookIt != word.End) ? lookIt.Current.Symbol : eof;
                    lookState = FindTransition(lookState.Transitions, lookSym);
                    lookIt    = lookIt.Next();
                }

                var decisions = lookeaheadDfa.Decisions[lookState.Accepting];
                if (decisions.Count() > 1)
                {
                    throw new NotImplementedException("Backtracking not implemented");
                }
                else if (!decisions.Any())
                {
                    return(ReturnError(term, children, input, it));
                }

                TSymbol transSymbol = (TSymbol)decisions.ElementAt(0);
                if (_grammar.IsTerminal(transSymbol))
                {
                    children.Add(new ParseLeaf <TSymbol>(it.Current.Fragment, currentSymbol));
                    it = it.Next();
                }
                else
                {
                    var result = ParseTerm(transSymbol, word, it);
                    if (!result)
                    {
                        return(ReturnError(term, children, input, it));
                    }
                    var okRes = result as ItOK <TSymbol>;
                    children.Add(okRes.Tree);
                    it = okRes.Iterator;
                }

                state = FindTransition(state.Transitions, transSymbol);
            }
        }