public void Iterator_Advance_Test()
        {
            var input = new List <int> {
                0, 1, 2, 3
            };
            var mi = new MemoizedInput <int>(input);

            var it = mi.Begin;

            Assert.AreNotEqual(it, mi.End);

            Assert.AreEqual(it.Current, input[0]);
            Assert.AreEqual(mi.At(3), mi.End);

            Assert.AreEqual(it.Next().Current, input[1]);
            Assert.AreEqual(it.Next().Next().Current, input[2]);
            Assert.AreEqual(it.Next().Next().Next().Current, input[3]);
            Assert.AreEqual(it.Next().Next().Next().Next(), mi.End);

            var it2 = it;

            it2 = it2.Next().Next();
            Assert.AreNotEqual(it, it2);
            Assert.AreEqual(it, mi.Begin);
            Assert.AreEqual(mi.At(2), it2);
        }
        public void Iterator_Comparison_Test()
        {
            var input = new List <int> {
                0, 1, 2, 3
            };
            var mi = new MemoizedInput <int>(input);

            var it = mi.Begin;

            Assert.AreEqual(it.Next().Next().Next().Next(), mi.End);
            Assert.IsTrue(mi.Begin < mi.End);
            Assert.IsTrue(mi.Begin <= mi.End);
            Assert.IsTrue(mi.End > mi.Begin);
            Assert.IsTrue(mi.End >= mi.Begin);
            Assert.IsTrue(mi.At(0) >= mi.Begin);
            Assert.IsTrue(mi.At(0) <= mi.Begin);
            Assert.IsTrue(mi.At(0) == mi.Begin);

            it = it.Next();
            Assert.IsTrue(it > mi.Begin);
            Assert.IsTrue(it >= mi.Begin);
            Assert.IsTrue(it.Next() >= it);
            Assert.IsTrue(mi.End > it);
            Assert.IsTrue(mi.Begin < it);
        }
Beispiel #3
0
 public ParseState(DfaState <TSymbol> state,
                   int transitionIndex,
                   MemoizedInput <ParseLeaf <TSymbol> > .Iterator iterator,
                   IEnumerator <ItParseResult <TSymbol> > nextPossibleResult = null)
 {
     State              = state;
     TransitionIndex    = transitionIndex;
     Iterator           = iterator;
     NextPossibleResult = nextPossibleResult;
 }
Beispiel #4
0
        // At this moment return null when parsing fails
        public ParseResult <TSymbol> Parse(IEnumerable <ParseLeaf <TSymbol> > word)
        {
            var memoizedWord = new MemoizedInput <ParseLeaf <TSymbol> >(word);
            var result       = ParseTerm(_grammar.Start, memoizedWord, memoizedWord.Begin).First();

            // whole input has to be eaten
            if (result && (result as ItOK <TSymbol>).Iterator != memoizedWord.End)
            {
                result = new ItError <TSymbol>((result as ItOK <TSymbol>).Iterator, _grammar.Start);
            }
            return(ParserUtils <TSymbol> .Convert(result));
        }
        public void Empty_Input_Test()
        {
            var input = new List <int>();
            var mi    = new MemoizedInput <int>(input);

            var it_0 = mi.Begin;

            Assert.AreEqual(it_0, mi.End);

            Assert.AreEqual(it_0.Next(), mi.End);
            Assert.AreEqual(it_0.Next().Next(), mi.End);

            Assert.AreEqual(mi.At(10), mi.End);
            Assert.AreEqual(mi.At(0), mi.End);
            Assert.AreEqual(mi.At(-1), mi.End);
        }
Beispiel #6
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);
            }
        }
 private ItParseResult <TSymbol> ReturnError(TSymbol term, IList <IParseTree <TSymbol> > children,
                                             MemoizedInput <ParseLeaf <TSymbol> > .Iterator input, MemoizedInput <ParseLeaf <TSymbol> > .Iterator currentIt)
 {
     return(new ItError <TSymbol>(currentIt, term));
 }
Beispiel #9
0
 public ItError(MemoizedInput <ParseLeaf <TSymbol> > .Iterator iterator, TSymbol symbol)
 {
     Iterator = iterator;
     Symbol   = symbol;
 }
Beispiel #10
0
 public ItOK(IParseTree <TSymbol> tree, MemoizedInput <ParseLeaf <TSymbol> > .Iterator iterator)
 {
     Tree     = tree;
     Iterator = iterator;
 }