public void SubsetConstruction_String() { var nfaBuilder = new Graph.Builder(); NFAHelper.Graph( nfaBuilder, NFAHelper.Series( nfaBuilder, NFAHelper.CreateSimplePath(nfaBuilder, '"'), NFAHelper.Optional( nfaBuilder, NFAHelper.Repeat( nfaBuilder, NFAHelper.Parallell( nfaBuilder, NFAHelper.Series( nfaBuilder, NFAHelper.CreateSimplePath(nfaBuilder, '"'), NFAHelper.CreateSimplePath(nfaBuilder, '"')), NFAHelper.CreateSimplePath(nfaBuilder, '"', true)))), NFAHelper.CreateSimplePath(nfaBuilder, '"'))); var dfaGraph = FATools.CreateDfa(nfaBuilder.Graph); const string expected = "0 (S:S0) -- [\"] --> 1\r\n" + "1 -- [\"] --> 2 (L:E0)\r\n" + "1 -- ![\"] --> 1\r\n" + "2 (L:E0) -- [\"] --> 1\r\n" + ""; Assert.That(FARenderer.Render(dfaGraph), Is.EqualTo(expected)); }
public void SubsetConstruction_Precidence() { var graphBuilder = new Graph.Builder(); NFAHelper.Graph( graphBuilder, NFAHelper.Series <NodeData, CharSet>( graphBuilder, NFAHelper.CreateSimplePath(graphBuilder, '1'), NFAHelper.CreateSimplePath(graphBuilder, '2'), NFAHelper.CreateSimplePath(graphBuilder, '3'), NFAHelper.CreateSimplePath(graphBuilder, '4')), NFAHelper.Repeat( graphBuilder, NFAHelper.CreateSimplePath(graphBuilder, '0', '9'))); var dfaGraph = FATools.CreateDfa(graphBuilder.Graph); const string expected = "0 (S:S0) -- [0,2-9] --> 1 (L:E1)\r\n" + "0 (S:S0) -- [1] --> 2 (L:E1)\r\n" + "1 (L:E1) -- [0-9] --> 1 (L:E1)\r\n" + "2 (L:E1) -- [0-1,3-9] --> 1 (L:E1)\r\n" + "2 (L:E1) -- [2] --> 3 (L:E1)\r\n" + "3 (L:E1) -- [0-2,4-9] --> 1 (L:E1)\r\n" + "3 (L:E1) -- [3] --> 4 (L:E1)\r\n" + "4 (L:E1) -- [4] --> 5 (L:E0)\r\n" + "4 (L:E1) -- [0-3,5-9] --> 1 (L:E1)\r\n" + "5 (L:E0) -- [0-9] --> 1 (L:E1)\r\n" + ""; Assert.That(FARenderer.Render(dfaGraph), Is.EqualTo(expected)); }
public void SubsetConstruction_Label() { var nfaGraphBuilder = new Graph.Builder(); var lead = new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z') }; var tail = new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z'), new CharRange('0', '9'), new CharRange('_', '_') }; NFAHelper.Graph( nfaGraphBuilder, NFAHelper.Series( nfaGraphBuilder, NFAHelper.CreateSimplePath(nfaGraphBuilder, CharSet.New(lead)), NFAHelper.Optional( nfaGraphBuilder, NFAHelper.Repeat( nfaGraphBuilder, NFAHelper.CreateSimplePath(nfaGraphBuilder, CharSet.New(tail)))))); var dfaGraph = FATools.CreateDfa(nfaGraphBuilder.Graph); const string expected = "0 (S:S0) -- [A-Z,a-z] --> 1 (L:E0)\r\n" + "1 (L:E0) -- [0-9,A-Z,_,a-z] --> 1 (L:E0)\r\n" + ""; Assert.That(FARenderer.Render(dfaGraph), Is.EqualTo(expected)); }
Graph BuildDFA(Dictionary <string, int> typeLookup) { var nfa = new Graph <NodeData, CharSet> .Builder(); for (var i = 0; i < _config.States.Count; i++) { var state = _config.States[i]; if (state.Rules.Count == 0) { ReporterHelper.AddError(_reporter, state.Label, "The state '{0}' does not define any rules.", state.Label.Text); continue; } var startState = nfa.NewState(true, new NodeData(i, null)); for (var j = 0; j < state.Rules.Count; j++) { var rule = state.Rules[j]; ReElement element; if (!typeLookup.TryGetValue(rule.Token.Text, out var endStateID)) { endStateID = typeLookup.Count; typeLookup.Add(rule.Token.Text, endStateID); } try { element = ReParser.Parse(rule.Regex.Text); } catch (ReParseException ex) { ReporterHelper.AddError(_reporter, rule.Regex, ex.Message); continue; } if (element.MatchesEmptyString) { ReporterHelper.AddWarning( _reporter, rule.Regex, "This regular expression claims to match the empty string, " + "this is not supported and usually indicates a typeo in the regular expression"); } element.GenerateNFA(nfa, startState, nfa.NewState(false, new NodeData(null, endStateID, j))); } } return(FATools.CreateDfa(nfa.Graph)); }
public void SubsetConstruction_MultipleEntrypoints() { var nfaBuilder = new Graph.Builder(); NFASegment segment; var s1 = nfaBuilder.NewState(true, new NodeData(1, null)); var s2 = nfaBuilder.NewState(true, new NodeData(2, null)); var e1 = nfaBuilder.NewState(false, new NodeData(null, 1)); var e2 = nfaBuilder.NewState(false, new NodeData(null, 2)); segment = NFAHelper.Series( nfaBuilder, NFAHelper.CreateSimplePath(nfaBuilder, 'c'), NFAHelper.CreateSimplePath(nfaBuilder, 'a'), NFAHelper.CreateSimplePath(nfaBuilder, 't')); nfaBuilder.AddTransition(s1, segment.FromState); nfaBuilder.AddTransition(segment.ToState, e1); segment = NFAHelper.Repeat( nfaBuilder, NFAHelper.CreateSimplePath( nfaBuilder, CharSet.New(new CharRange[] { new CharRange('a', 'z'), new CharRange('A', 'Z'), }))); nfaBuilder.AddTransition(s1, segment.FromState); nfaBuilder.AddTransition(s2, segment.FromState); nfaBuilder.AddTransition(segment.ToState, e2); var dfaGraph = FATools.CreateDfa(nfaBuilder.Graph); const string expected = "0 (S:S1) -- [A-Z,a-b,d-z] --> 1 (L:E2)\r\n" + "0 (S:S1) -- [c] --> 2 (L:E2)\r\n" + "3 (S:S2) -- [A-Z,a-z] --> 1 (L:E2)\r\n" + "1 (L:E2) -- [A-Z,a-z] --> 1 (L:E2)\r\n" + "2 (L:E2) -- [A-Z,b-z] --> 1 (L:E2)\r\n" + "2 (L:E2) -- [a] --> 4 (L:E2)\r\n" + "4 (L:E2) -- [t] --> 5 (L:E1)\r\n" + "4 (L:E2) -- [A-Z,a-s,u-z] --> 1 (L:E2)\r\n" + "5 (L:E1) -- [A-Z,a-z] --> 1 (L:E2)\r\n" + ""; Assert.That(FARenderer.Render(dfaGraph), Is.EqualTo(expected)); }
static object GenerateScanGraph(string text) { var errorReporter = new Mock <IErrorReporter>(MockBehavior.Strict); var parser = new ConfigParser(errorReporter.Object); var config = parser.Parse(new ConfigScanner(text)); var state = config.States[0]; var nfa = new Graph.Builder(); var start = nfa.NewState(true, new NodeData(0, null)); for (var i = 0; i < state.Rules.Count; i++) { var rule = state.Rules[i]; var element = ReParser.Parse(rule.Regex.Text); element.GenerateNFA(nfa, start, nfa.NewState(false, new NodeData(null, i))); } return(FATools.CreateDfa(nfa.Graph)); }