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); }
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)); }
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); }
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); }
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); } } } }
private static bool IsAccepting(IDfa <Optional <Rule <TLabel> >, TLabel> dfa, IState state) { return(!dfa.Label(state).IsNone()); }
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); }