private static IDfa <Optional <Rule <TLabel> >, TLabel> CompileRules(IList <Rule <TLabel> > rules) { var dfas = rules.ToDictionary( keySelector: (rule) => Optional <Rule <TLabel> > .Some(rule), elementSelector: (rule) => RegexToDfa(rule.Rhs)); var merged = DfaMerger <Optional <Rule <TLabel> >, TLabel> .Merge( dfas, conflictSolver : (matchesEnumerable) => { var matches = matchesEnumerable.ToList(); if (matches.Count == 0) { return(Optional <Rule <TLabel> > .None()); } else if (matches.Count == 1) { return(matches[0]); } else { throw new ArgumentException($"two rules have conflicting regexes (for symbol: {matches[0].Get().Lhs})"); } }); return(DfaMinimizer <Optional <Rule <TLabel> >, TLabel> .Minimize(merged)); }
private static IDfa <bool, TLabel> RegexToDfa(Regex <TLabel> regex) { INfa <TLabel> nfa = RegexToNfaConverter <TLabel> .Convert(regex); IDfa <bool, TLabel> dfa = NfaToDfaConverter <TLabel> .Convert(nfa); return(DfaMinimizer <bool, TLabel> .Minimize(dfa)); }
public void TestMinimize(string[] strings, string expected) { var trie = new Trie(); trie.AddRange(strings); var min = DfaMinimizer <char> .Minimize(trie); var result = min.ToString(); Assert.AreEqual(expected, result); }
private static void CheckMinimization <TLabel>(IDfa <TLabel, char> dfa, int expectedNumberOfStates = -1) { var minimalDfa = DfaMinimizer <TLabel, char> .Minimize(dfa); var numberOfStates = ReachableStates(minimalDfa).Count; if (expectedNumberOfStates != -1) { Assert.AreEqual(expectedNumberOfStates, numberOfStates); } CheckAutomatonEquivalence(dfa, minimalDfa); CheckStateStability(minimalDfa); }
// tokenCategories - List of pair (Token, Regex for thie Token) public Lexer( IEnumerable <KeyValuePair <TLabel, string> > tokenCategories, TLabel eof, TLabel noneValue, Func <IEnumerable <TLabel>, TLabel> conflictSolver) { this.eof = eof; this.noneValue = noneValue; var converter = new StringToRegexConverterFactory().CreateConverter(); Dictionary <TLabel, IDfa <bool, char> > multipleDfa = tokenCategories.ToDictionary( x => x.Key, x => { Regex <char> regex = converter.Convert(x.Value); INfa <char> nfaPre = RegexToNfaConverter <char> .Convert(regex); INfa <char> nfa = ConcreteNfa <char> .CreateFromNfa(nfaPre); IDfa <bool, char> dfa = NfaToDfaConverter <char> .Convert(nfa); return(DfaMinimizer <bool, char> .Minimize(dfa)); }); var mergedDfa = DfaMerger <TLabel, char> .Merge(multipleDfa, conflictSolver); this.minimalizedDfa = DfaMinimizer <TLabel, char> .Minimize(mergedDfa); }