Пример #1
0
 private Node ConnectEntry(Node source, Entry entry)
 {
     return(entry switch
     {
         MatchEntry matchEntry => ConnectMatch(source, matchEntry),
         StateEntry stateEntry => ConnectState(source, stateEntry, stateEntry.State.Inline || Automata.ForceInlineAll),
         QuantifierEntry quantifierEntry => ConnectQuantifier(source, quantifierEntry),
         PredicateEntryBase predicateEntry => ConnectPredicate(source, predicateEntry),
         ActionEntry actionEntry => ConnectAction(source, actionEntry),
         EpsilonEntry _ => source,
         _ => throw new ArgumentOutOfRangeException(nameof(entry))
     });
Пример #2
0
            private static void EliminateLeftRecursion(ParserState parserState, List <ParserProduction> productions)
            {
                var hasLeftRecursion = false;

                foreach (var stateProduction in productions)
                {
                    stateProduction.LeftRecursionClassifier = Classify(stateProduction, parserState);

                    hasLeftRecursion |= IsLeftRecursion(stateProduction.LeftRecursionClassifier);
                }

                if (hasLeftRecursion == false)
                {
                    return;
                }

                var count          = productions.Count;
                var recursionState = new ParserState(null, true);
                var index          = 0;

                foreach (var production in productions)
                {
                    if (production.LeftRecursionClassifier == LeftRecursionClassifier.Binary ||
                        production.LeftRecursionClassifier == LeftRecursionClassifier.Ternary ||
                        production.LeftRecursionClassifier == LeftRecursionClassifier.Prefix)
                    {
                        var assoc        = production.IsRightAssoc ? 0 : 1;
                        var nextPriority = new PriorityStateEntryContext(count - index + assoc);

                        foreach (var parserStateEntry in production.Entries.Skip(1).OfType <ParserStateEntry>().Where(e => ReferenceEquals(e.State, parserState)))
                        {
                            parserStateEntry.StateEntryContext = nextPriority;
                        }
                    }

                    if (IsLeftRecursion(production.LeftRecursionClassifier) == false)
                    {
                        continue;
                    }

                    production.LeftRecursionEntry = (ParserStateEntry)production.Entries[0];
                    production.Entries[0]         = ShouldPrefixPredicate(production.LeftRecursionClassifier) ? (Entry) new LeftRecursionPredicate(parserState, count - index).Entry : EpsilonEntry.Instance;

                    recursionState.Productions.Add(production);

                    index++;
                }

                var quantifierEntry = new QuantifierEntry(new StateEntry(recursionState)
                {
                    SkipStack = true
                }, QuantifierKind.ZeroOrMore, QuantifierMode.Greedy);
                var primaryState = new ParserState(null, true);

                primaryState.Productions.AddRange(productions.Where(production => IsLeftRecursion(production.LeftRecursionClassifier) == false));

                productions.Clear();
                productions.Add(new ParserProduction(new Entry[] { new StateEntry(primaryState)
                                                                   {
                                                                       SkipStack = true
                                                                   }, quantifierEntry }));
            }