-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
199 lines (172 loc) · 6.41 KB
/
Program.cs
File metadata and controls
199 lines (172 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
using RegexDebug.RegexDev;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
namespace RegexDebug
{
internal class Program
{
static void Main(string[] args)
{
EnableVirtualTerminalProcessing();
var pattern = @"(?x:#this ia a regex to quickly match any very long palindrome string
(?=^(?'len'.)+)(?=(?(h)(?'-h')(?'half')(?'-len').|(?'h')(?'-len').)+)(?'-h')?(?'half')#first to obtain half of the length of the text to be matched
(?i)
(?'-half'(.))+#balancing group#half is used to ensure that the left side only moustly matches half of the target string, avoiding invalid backtracking
(.)?(?'-1'\1)+(?!(?'-1'))
)";
var astStyle = 1;//whether or not convert AST to .NET 5+ compatible regex pattern
var regexCanRunOnDotNET5 = "";
var rootNode = new RegexParse().ParseAST(pattern, astStyle, out regexCanRunOnDotNET5);
//print colorful AST tree
Console.WriteLine(regexCanRunOnDotNET5);
RegexParserUtils.PrintColorASTTree(rootNode);
Test();
}
private static void Test()
{
PrintRegexDev();
int customBufferSize = 10000 * 10;
Console.SetIn(new StreamReader(
Console.OpenStandardInput(customBufferSize),
Console.InputEncoding,
false,
customBufferSize
));
Console.WriteLine("Pause your regex, and input 'parse' in new line to parse your regex:");
var pattern = Console.ReadLine();
while (true)
{
#region read console input, bulid a regex pattern
while (true)
{
var text = Console.ReadLine();
if (text.ToUpper() == "EXIT") Environment.Exit(0);
else if (text.ToUpper() == "CLS" || text.ToUpper() == "CLEAR")
{
pattern = "";
Console.Clear();
}
else if (text.ToUpper() == "PARSE") break;
else
{
if (pattern.Length > 0) pattern += "\n";
pattern += text;
}
}
#endregion
var patterndotNET5 = "";
try
{
Stopwatch stopwatch = Stopwatch.StartNew();
var parse = new RegexParse();
var rootNode = parse.ParseAST(pattern, 1, out patterndotNET5);
stopwatch.Stop();
var myParseTime = stopwatch.Elapsed.TotalMilliseconds;
stopwatch.Restart();
new Regex(patterndotNET5);
stopwatch.Stop();
var dotNETParseTime = stopwatch.Elapsed.TotalMilliseconds;
//Test parse regex if or not equal to original pattern
var sb = new StringBuilder();
RegexParse.GetUnitPattern(rootNode, sb);//convert AST back to regex pattern, to verify the parsing is correct
patterndotNET5 = sb.ToString();
Console.ForegroundColor = ConsoleColor.Magenta;
Console.Write("Parse pattern is equal original pattern:");
if (patterndotNET5 == pattern)//not equal doesn't mean parsing wrong, it is very highly likely that the regex has been converted
Console.ForegroundColor = ConsoleColor.Blue;
else Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine((patterndotNET5 == pattern) + (patterndotNET5 == pattern ? "" : "\tnot equal doesn't mean parsing wrong, it is very highly likely that the regex has been converted"));
Console.ForegroundColor = ConsoleColor.White;
if (patterndotNET5 != pattern)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(patterndotNET5);
Console.ForegroundColor = ConsoleColor.White;
}
// print AST
//RegexParserUtils.PrintAST(rootNode);
// doubao AI's printer:
//RegexASTTreePrinter.PrintASTTree(rootNode);
// Print AST TREE
//RegexParserUtils.PrintASTTree(rootNode);
//print colorful AST tree
RegexParserUtils.PrintColorASTTree(rootNode);
{
var jsonstr = new RegexNodeJson().GetJsonObject(rootNode);
var html = Resource1.Html;
File.WriteAllText("Lang.js", Resource1.Lang);
File.WriteAllText("regex_ast_railroad.html", html);
File.WriteAllText("railroad_json.js", $"var json = {jsonstr};var regex = `{patterndotNET5.Replace("\\","\\\\").Replace("`","\\`")}`");
string fileName = "regex_ast_railroad.html";
string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c start \"\" \"{filePath}\"",
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
// generate Markdown style mermaid diagram
//string markdown = RegexParserUtils.ASTToStyledMermaid(rootNode);
//Console.WriteLine(markdown);
// generate node diagram in HTML, and open it in default browser
{
string html = RegexParserUtils.ASTToHtml(rootNode, patterndotNET5);
File.WriteAllText("regex_ast.html", html);//save to current directory
string fileName = "regex_ast.html";
string filePath = Path.Combine(Directory.GetCurrentDirectory(), fileName);
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c start \"\" \"{filePath}\"",
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
Console.WriteLine($"ParseAST:{myParseTime}(match:{parse.regexMatchTime}),c# engine:{dotNETParseTime}");
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine(ex.Message);
Console.ForegroundColor = ConsoleColor.White;
}
pattern = "";
Console.WriteLine();
}
}
private static void PrintRegexDev()
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Visit [https://github.com/longxya/regexdev] to get more information.");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine();
}
#region Enable virtual terminal processing. Make ANSI colors effective
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
const int STD_OUTPUT_HANDLE = -11;
const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
static void EnableVirtualTerminalProcessing()
{
var handle = GetStdHandle(STD_OUTPUT_HANDLE);
uint mode;
if (!GetConsoleMode(handle, out mode))
{
return;
}
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(handle, mode);
}
#endregion
}
}