Exemplo n.º 1
0
            private ParseTree <TLabel> Reduce(
                IDfa <Optional <Rule <TLabel> >, TLabel> dfa,
                IState state,
                ParseTree <TLabel> currentToken)
            {
                if (dfa.Label(state).IsNone())
                {
                    this.diagnostics.Add(new Diagnostic(
                                             DiagnosticStatus.Error,
                                             InvalidReduceActionDiagnosticType,
                                             "Invalid reduce action at {0}",
                                             new List <Range> {
                        currentToken.InputRange
                    }));
                    throw new ParseException("Invalid reduce action");
                }

                var rule                = dfa.Label(state).Get();
                var topNodes            = this.nodesStack.Peek();
                var newCategory         = rule.Lhs;
                var range               = GetRange(topNodes);
                ParseTree <TLabel> root = new Brunch <TLabel>
                {
                    Rule = rule, Children = topNodes, Category = newCategory, InputRange = range
                };

                this.statesStack.Pop();
                this.dfaStack.Pop();
                this.nodesStack.Pop();
                if (this.nodesStack.Count != 0)
                {
                    this.nodesStack.Peek().Add(root);
                }

                return(root);
            }
Exemplo n.º 2
0
        private static TLabel GetTargetLabel <TLabel>(IDfa <TLabel, char> dfa, string s, TLabel defaultLabel)
        {
            var state = dfa.StartingState();

            foreach (var ch in s)
            {
                var transitions = dfa.Transitions(state);
                if (!transitions.ContainsKey(ch))
                {
                    return(defaultLabel);
                }

                state = transitions[ch];
            }

            return(dfa.Label(state));
        }
Exemplo n.º 3
0
        public static bool AreEquivalent(IDfa <TLabel, Symbol> firstDfa, IDfa <TLabel, Symbol> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                if (!firstDfa.Label(firstState).Equals(secondDfa.Label(secondState)))
                {
                    return(false);
                }

                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                if (!firstStateTransitions.Count.Equals(secondStateTransitions.Count))
                {
                    return(false);
                }

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    if (!secondStateTransitions.ContainsKey(c))
                    {
                        return(false);
                    }

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 4
0
        private static List <HashSet <IState> > InitialPartition(IDfa <TLabel, Symbol> dfa)
        {
            var partition  = new List <HashSet <IState> >();
            var labelId    = new Dictionary <TLabel, int>();
            int labelCount = 0;

            foreach (IState state in ReachableStates(dfa))
            {
                TLabel stateLabel = dfa.Label(state);
                if (!labelId.ContainsKey(stateLabel))
                {
                    labelId.Add(stateLabel, labelCount);
                    partition.Add(new HashSet <IState>());
                    ++labelCount;
                }

                partition[labelId[stateLabel]].Add(state);
            }

            return(partition);
        }
Exemplo n.º 5
0
        private static void CheckAutomatonEquivalence <TLabel>(IDfa <TLabel, char> firstDfa, IDfa <TLabel, char> secondDfa)
        {
            var reached = new HashSet <Tuple <IState, IState> >();
            var queue   = new Queue <Tuple <IState, IState> >();

            queue.Enqueue(Tuple.Create(firstDfa.StartingState(), secondDfa.StartingState()));
            reached.Add(queue.Peek());

            while (queue.Count > 0)
            {
                var(firstState, secondState) = queue.Dequeue();
                Assert.AreEqual(firstDfa.Label(firstState), secondDfa.Label(secondState), "Labels should be equal");
                var firstStateTransitions  = firstDfa.Transitions(firstState);
                var secondStateTransitions = secondDfa.Transitions(secondState);

                var firstTransitionCount  = firstStateTransitions.Count;
                var secondTransitionCount = secondStateTransitions.Count;
                Assert.AreEqual(
                    firstTransitionCount,
                    secondTransitionCount,
                    $"States {firstState} and {secondState} have different number of transitions: {firstTransitionCount} != {secondTransitionCount}");

                foreach (var(c, firstNextState) in firstStateTransitions)
                {
                    Assert.IsTrue(
                        secondStateTransitions.ContainsKey(c),
                        $"States have different sets of transitions, {secondTransitionCount} : {string.Join(",", firstStateTransitions.Select((x, y) => ((int)x.Key).ToString()).ToList())}");

                    var secondNextState = secondStateTransitions[c];

                    var pair = Tuple.Create(firstNextState, secondNextState);
                    if (!reached.Contains(pair))
                    {
                        reached.Add(pair);
                        queue.Enqueue(pair);
                    }
                }
            }
        }
Exemplo n.º 6
0
 private static bool IsAccepting(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state)
 {
     return(!dfa.Label(state).IsNone());
 }
Exemplo n.º 7
0
        private static IReadOnlyCollection <ParseAction <TLabel> > GetAllParseActions(
            CompiledGrammar <TLabel> grammar,
            IState state,
            IDfa <Optional <Rule <TLabel> >, TLabel> dfa,
            TLabel label,
            IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > follow,
            IReadOnlyDictionary <TLabel, IReadOnlyCollection <DfaAndState <TLabel> > > firstPlus)
        {
            var actions = new List <ParseAction <TLabel> >();

            var stateLabel  = dfa.Label(state);
            var dfaAndState = new DfaAndState <TLabel>()
            {
                Dfa = dfa, State = state
            };

            if (stateLabel.IsSome() && follow.ContainsKey(label) && follow[label].Contains(dfaAndState))
            {
                actions.Add(
                    new ParseAction <TLabel>()
                {
                    Kind = ParseAction <TLabel> .ActionKind.Reduce, Label = stateLabel.Get().Lhs
                });
            }

            var transitions = dfa.Transitions(state);

            if (transitions.ContainsKey(label))
            {
                var nextState = transitions[label];
                if (!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome())
                {
                    actions.Add(
                        new ParseAction <TLabel>()
                    {
                        Kind = ParseAction <TLabel> .ActionKind.Shift, Label = label
                    });
                }
            }

            if (firstPlus.ContainsKey(label))
            {
                var firstPlusStates = firstPlus[label];
                foreach (var transitionLabel in transitions.Keys)
                {
                    var nextState = transitions[transitionLabel];
                    if ((!dfa.IsStable(nextState) || dfa.Label(nextState).IsSome()) && grammar.Rules.ContainsKey(transitionLabel))
                    {
                        var subDfa = grammar.Rules[transitionLabel];
                        var subDfaAndStartState = new DfaAndState <TLabel>()
                        {
                            Dfa = subDfa, State = subDfa.StartingState()
                        };

                        if (firstPlusStates.Contains(subDfaAndStartState))
                        {
                            actions.Add(
                                new ParseAction <TLabel>()
                            {
                                Kind = ParseAction <TLabel> .ActionKind.Call, Label = transitionLabel
                            });
                        }
                    }
                }
            }

            return(actions);
        }