static void _RunFromFA() { var expr = RegexExpression.Parse("(0*11*0[01]*)"); var fa = expr.ToFA <string>(); fa.IsAccepting = true; // modify the expression by changing the FSM var x = new CharFA <string>(); var y = new CharFA <string>(); var z = new CharFA <string>(true); x.InputTransitions.Add('a', y); y.InputTransitions.Add('b', y); y.InputTransitions.Add('c', z); fa = x; var test = "[A-Z_a-z][0-9A-Z_a-z]*"; //test = "ab*c"; test = "(foo)*bar"; fa = RegexExpression.Parse(test).ToFA <string>(); fa.RenderToFile(@"..\..\..\test_expr_nfa.jpg"); var ffa = fa.ToDfa(); ffa.RenderToFile(@"..\..\..\test_expr.jpg"); expr = RegexExpression.FromFA(fa); Console.WriteLine(expr); fa.RenderToFile(@"..\..\..\test_nfa.jpg"); var dfa = fa.ToDfa(); dfa.RenderToFile(@"..\..\..\test.jpg"); }
static void _RunDom() { var test = "(ABC|DEF)*"; var dom = RegexExpression.Parse(test); Console.WriteLine(dom.ToString()); var rep = dom as RegexRepeatExpression; rep.MinOccurs = 1; Console.WriteLine(dom.ToString()); dom.ToFA("Accept"); Console.WriteLine(); }
static void Main() { var sw = Stopwatch.StartNew(); var a = RegexExpression.Parse(@"a.+a").ToFA <string>(); Console.WriteLine(sw.ElapsedMilliseconds); a.RenderToFile("tmp.png"); // _BuildArticleImages() // requires GraphViz // _RunCompiledLexCodeGen() /*_RunLexer(); * _RunMatch(); * _RunDom(); * // the following require GraphViz * _RunStress(); * _RunStress2();*/ }
static void _RunStress() { // C# keywords const string cskw = "abstract|add|as|ascending|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|do|double|dynamic|else|enum|equals|explicit|extern|false|finally|fixed|float|for|foreach|get|global|goto|if|implicit|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|var|virtual|void|volatile|while|yield"; var expr = RegexExpression.Parse(cskw); var fa = expr.ToFA(""); Console.WriteLine("C# keyword NFA has {0} states.", fa.FillClosure().Count); Console.WriteLine("Reducing C# keywords"); // very expensive in this case fa = fa.Reduce(new _ConsoleProgress()); Console.WriteLine(); Console.WriteLine("C# keyword DFA has {0} states.", fa.FillClosure().Count); var dopt = new CharFA <string> .DotGraphOptions(); dopt.Dpi = 150; // make the image smaller Console.WriteLine("Rendering stress.jpg"); fa.RenderToFile(@"..\..\..\stress.jpg", dopt); }
static void _BuildArticleImages() { // this generates the figures used in the code project article // at https://www.codeproject.com/Articles/5251476/How-to-Build-a-Regex-Engine-in-Csharp var litA = CharFA <string> .Literal("ABC", "Accept"); litA.RenderToFile(@"..\..\..\literal.jpg"); var litAa = CharFA <string> .CaseInsensitive(litA, "Accept"); litAa.RenderToFile(@"..\..\..\literal_ci.jpg"); var opt = CharFA <string> .Optional(litA, "Accept"); opt.RenderToFile(@"..\..\..\optional.jpg"); var litB = CharFA <string> .Literal("DEF"); var or = CharFA <string> .Or(new CharFA <string>[] { litA, litB }, "Accept"); or.RenderToFile(@"..\..\..\or.jpg"); var set = CharFA <string> .Set("ABC", "Accept"); set.RenderToFile(@"..\..\..\set.jpg"); var loop = CharFA <string> .Repeat(litA, 1, -1, "Accept"); loop.RenderToFile(@"..\..\..\repeat.jpg"); var concat = CharFA <string> .Concat(new CharFA <string>[] { litA, litB }, "Accept"); concat.RenderToFile(@"..\..\..\concat.jpg"); var foobar = CharFA <string> .Or(new CharFA <string>[] { CharFA <string> .Literal("foo"), CharFA <string> .Literal("bar") }, "Accept"); foobar.RenderToFile(@"..\..\..\foobar_nfa.jpg"); var rfoobar = foobar.Reduce(); rfoobar.RenderToFile(@"..\..\..\foobar.jpg"); var lfoobar = CharFA <string> .Repeat(foobar, 1, -1, "Accept"); lfoobar.RenderToFile(@"..\..\..\foobar_loop_nfa.jpg"); var rlfoobar = lfoobar.Reduce(); rlfoobar.RenderToFile(@"..\..\..\foobar_loop.jpg"); var digits = CharFA <string> .Repeat( CharFA <string> .Set("0123456789"), 1, -1 , "Digits"); var word = CharFA <string> .Repeat( CharFA <string> .Set(new CharRange[] { new CharRange('A', 'Z'), new CharRange('a', 'z') }), 1, -1 , "Word"); var whitespace = CharFA <string> .Repeat( CharFA <string> .Set(" \t\r\n\v\f"), 1, -1 , "Whitespace"); var lexer = CharFA <string> .ToLexer(digits, word, whitespace); lexer.RenderToFile(@"..\..\..\lexer.jpg"); var dopt = new CharFA <string> .DotGraphOptions(); dopt.DebugSourceNfa = lexer; var dlexer = lexer.ToDfa(); dlexer.RenderToFile(@"..\..\..\dlexer.jpg", dopt ); dlexer.RenderToFile(@"..\..\..\dlexer2.jpg"); var dom = RegexExpression.Parse("(ABC|DEF)+"); var fa = dom.ToFA("Accept"); fa.RenderToFile(@"..\..\..\ABCorDEFloop.jpg"); }
public SpecflowStepInfo Create(string classFullName, string methodName, GherkinStepKind stepKind, string pattern) { CharFA <string> regexForPartialMatch; try { regexForPartialMatch = RegexExpression.Parse(pattern).ToFA <string>(); } catch (Exception) { regexForPartialMatch = null; } Regex regex; try { var fullMatchPattern = pattern; if (!fullMatchPattern.StartsWith("^")) { fullMatchPattern = "^" + fullMatchPattern; } if (!fullMatchPattern.EndsWith("$")) { fullMatchPattern += "$"; } regex = new Regex(fullMatchPattern, RegexOptions.Compiled, TimeSpan.FromSeconds(2)); } catch (ArgumentException) { regex = null; } var regexesPerCapture = new List <Regex>(); var partialPattern = new StringBuilder(); var error = false; foreach (var(type, text, _) in _stepPatternUtil.TokenizeStepPattern(pattern)) { switch (type) { case StepPatternUtil.StepPatternTokenType.Text: partialPattern.Append(text); break; case StepPatternUtil.StepPatternTokenType.Capture: var captureText = text; if (text == ".+") { captureText = ".+?"; } else if (text == ".*") { captureText = ".*?"; } partialPattern.Append('(').Append(captureText).Append(")"); try { regexesPerCapture.Add(new Regex("^" + partialPattern + "(?:(?:[ \"\\)])|$)", RegexOptions.Compiled)); } catch (ArgumentException) { error = true; } break; default: throw new ArgumentOutOfRangeException(); } if (error) { break; } } return(new SpecflowStepInfo(classFullName, methodName, stepKind, pattern, regex, regexForPartialMatch, regexesPerCapture)); }