Exemple #1
0
        public Grammar(TSymbol start, IDictionary <TSymbol, IProduction <TSymbol>[]> productions)
        {
            Start           = start;
            Productions     = productions;
            WhichProduction = new Dictionary <uint, IProduction <TSymbol> >();
            Automatons      = new Dictionary <TSymbol, Dfa <TSymbol> >();
            // Here we prepare automatons for each symbol.
            uint productionMarker = 1;

            foreach (var symbolProductions in Productions)
            {
                var automatons = new List <Lexer.DfaUtils.MinimizedDfa <TSymbol> >();
                foreach (var production in symbolProductions.Value)
                {
                    automatons.Add(Dfa <TSymbol> .RegexDfa(production.Rhs, productionMarker));
                    WhichProduction[productionMarker] = production;
                    productionMarker++;
                }
                Automatons[symbolProductions.Key] = Dfa <TSymbol> .ProductDfa(automatons.ToArray());
            }

            Nullable = GrammarUtils <TSymbol> .ComputeNullable(Automatons);

            First = GrammarUtils <TSymbol> .ComputeFirst(Automatons, Nullable);

            Follow = GrammarUtils <TSymbol> .ComputeFollow(Automatons, Nullable, First);

            SymbolListLeftRecursion = GrammarUtils <TSymbol> .HasLeftRecursion(Automatons, Nullable);

            TargetStatesDictionary = GrammarUtils <TSymbol> .computeTargetStatesDictionary(Automatons);

            AccStateOwnerDictionary = GrammarUtils <TSymbol> .computeAccStateOwnerDictionary(Automatons);
        }
Exemple #2
0
        // For testing purposes only!
        public void InjectAutomatons(Dictionary <TSymbol, Dfa <TSymbol> > automatons)
        {
            this.Automatons        = automatons;
            TargetStatesDictionary = GrammarUtils <TSymbol> .computeTargetStatesDictionary(Automatons);

            AccStateOwnerDictionary = GrammarUtils <TSymbol> .computeAccStateOwnerDictionary(Automatons);
        }
        // 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));
            }
        }