Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 08278c9

Browse files
authored
Implements dot operator in regex
1 parent eee7f32 commit 08278c9

File tree

1 file changed

+111
-104
lines changed

1 file changed

+111
-104
lines changed

‎ScannerGenerator.cs‎

Lines changed: 111 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public class diagram
6262
public void MakeNFA(string pattern) { Diagram = make_nfa("(" + pattern + ")"); }
6363
public void OptimizeNFA() { while (opt_nfa(Diagram)) ; }
6464
public void NFAtoDFA() { Diagram = nfa2dfa(Diagram); }
65-
public void MinimizeDFA() { opt_dfa_hopcroft(Diagram); }
65+
public void MinimizeDFA() { opt_dfa(Diagram); }
6666
public string PrintDiagram() { return print_diagram(Diagram); }
6767

6868
public static string PrintDiagram(diagram dia) { return print_diagram(dia); }
@@ -200,11 +200,17 @@ private diagram make_nfa(string pattern)
200200
case '[':
201201
var ch_list = new List<char>();
202202
i++;
203+
bool inverse = false;
204+
if (i < pattern.Length && pattern[i] == '^')
205+
{
206+
inverse = true;
207+
i++;
208+
}
203209
for (; i < pattern.Length && pattern[i] != ']'; i++)
204210
{
205211
if (pattern[i] == '\\' && i + 1 < pattern.Length)
206212
{
207-
if (@"+-?*|()[].=<>/".Contains(pattern[i + 1]))
213+
if (@"+-?*|()[].=<>/\".Contains(pattern[i + 1]))
208214
ch_list.Add(pattern[++i]);
209215
else
210216
{
@@ -222,6 +228,7 @@ private diagram make_nfa(string pattern)
222228

223229
default:
224230
build_errors.Add($"{pattern[i]} escape character not found!");
231+
ch_list.Add(pattern[i]);
225232
break;
226233
}
227234
}
@@ -236,6 +243,18 @@ private diagram make_nfa(string pattern)
236243
ch_list.Add(pattern[i]);
237244
}
238245
var ends_point2 = new transition_node { index = index_count++, transition = new List<Tuple<char, transition_node>>() };
246+
if (inverse)
247+
{
248+
var set = new bool[128];
249+
var nch_list = new List<char>();
250+
foreach (var ch2 in ch_list)
251+
set[ch2] = true;
252+
for (int j = 0; j < 128; j++)
253+
if (!set[j])
254+
nch_list.Add((char)j);
255+
ch_list.Clear();
256+
ch_list = nch_list;
257+
}
239258
foreach (var ch2 in ch_list)
240259
{
241260
cur.transition.Add(new Tuple<char, transition_node>(ch2, ends_point2));
@@ -249,6 +268,21 @@ private diagram make_nfa(string pattern)
249268
first_valid_stack.Push(cur);
250269
break;
251270

271+
case '.':
272+
var ends_point3 = new transition_node { index = index_count++, transition = new List<Tuple<char, transition_node>>() };
273+
for( int i2 = 0; i2 < 128; i2++)
274+
{
275+
cur.transition.Add(new Tuple<char, transition_node>((char)i2, ends_point3));
276+
}
277+
cur = ends_point3;
278+
nodes.Add(cur);
279+
if (first_valid_stack.Count != 0)
280+
{
281+
second_valid_stack.Push(first_valid_stack.Peek());
282+
}
283+
first_valid_stack.Push(cur);
284+
break;
285+
252286
case '\\':
253287
default:
254288
char ch = pattern[i];
@@ -343,6 +377,52 @@ private static string print_diagram(diagram d)
343377
return builder.ToString();
344378
}
345379

380+
/// <summary>
381+
/// GraphViz.Net(Jamie Dixon), Microsoft.Bcl.Immutable(Microsoft) 누겟 패키지 설치 필요
382+
///
383+
/// App.config 파일 수정해야함
384+
/// <?xml version="1.0" encoding="utf-8"?>
385+
/// <configuration>
386+
/// <startup>
387+
/// <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
388+
/// </startup>
389+
/// <appSettings>
390+
/// <add key="graphVizLocation" value="C:\Program Files (x86)\Graphviz2.38\bin"/>
391+
/// </appSettings>
392+
/// </configuration>
393+
///
394+
/// public class Graph
395+
/// {
396+
/// public static Bitmap ToImage(string str)
397+
/// {
398+
/// var getStartProcessQuery = new GetStartProcessQuery();
399+
/// var getProcessStartInfoQuery = new GetProcessStartInfoQuery();
400+
/// var registerLayoutPluginCommand = new RegisterLayoutPluginCommand(getProcessStartInfoQuery, getStartProcessQuery);
401+
///
402+
/// var wrapper = new GraphGeneration(getStartProcessQuery,
403+
/// getProcessStartInfoQuery,
404+
/// registerLayoutPluginCommand);
405+
///
406+
/// byte[] output = wrapper.GenerateGraph(str /*"digraph{a -> b; b -> c; c -> a;}"*/, Enums.GraphReturnType.Png);
407+
///
408+
/// return ByteToImage(output);
409+
/// }
410+
///
411+
///
412+
/// private static Bitmap ByteToImage(byte[] blob)
413+
/// {
414+
/// MemoryStream mStream = new MemoryStream();
415+
/// byte[] pData = blob;
416+
/// mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
417+
/// Bitmap bm = new Bitmap(mStream, false);
418+
/// mStream.Dispose();
419+
/// return bm;
420+
/// }
421+
///
422+
/// }
423+
/// </summary>
424+
/// <param name="d"></param>
425+
/// <returns></returns>
346426
private static string print_diagram_for_graphviz(diagram d)
347427
{
348428
var builder = new StringBuilder();
@@ -704,103 +784,13 @@ private string dic2str(SortedDictionary<char, int> dic)
704784
{
705785
return string.Join(",", dic.ToList().Select(x => $"({x.Key},{x.Value})"));
706786
}
707-
708-
/// <summary>
709-
/// Minimization DFA using coloring
710-
/// </summary>
711-
/// <param name="dia"></param>
712-
/// <returns></returns>
713-
private void opt_dfa(diagram dia)
714-
{
715-
var color = new List<int>();
716-
var color_count = 1;
717-
Dictionary<string, List<int>> previous_group = null;
718-
var check = new List<bool>(dia.count_of_vertex);
719-
check.AddRange(Enumerable.Repeat(false, dia.count_of_vertex));
720-
721-
color.AddRange(Enumerable.Repeat(0, dia.count_of_vertex));
722-
723-
#if true // For distingushiable states
724-
var color_set = new Dictionary<string, int>();
725-
#endif
726-
727-
foreach (var node in dia.nodes)
728-
if (node.is_acceptable)
729-
{
730-
color[node.index] = color_count;
731-
check[node.index] = true;
732-
733-
#if true // For distingushiable states
734-
if (node.accept_token_names != null)
735-
{
736-
if (!color_set.ContainsKey(node.accept_token_names[0]))
737-
color_set.Add(node.accept_token_names[0], color_count++);
738-
color[node.index] = color_set[node.accept_token_names[0]];
739-
}
740-
#endif
741-
}
742-
743-
color_count++;
744-
745-
while (true)
746-
{
747-
// Collect transition color
748-
var dic = new Dictionary<int, SortedDictionary<char, int>>();
749-
foreach (var node in dia.nodes)
750-
foreach (var ts in node.transition)
751-
{
752-
if (!dic.ContainsKey(node.index))
753-
dic.Add(node.index, new SortedDictionary<char, int>());
754-
dic[node.index].Add(ts.Item1, color[ts.Item2.index]);
755-
}
756-
757-
// Grouping
758-
var list = dic.ToList();
759-
var group = new Dictionary<string, List<int>>();
760-
for (int i = 0; i < list.Count; i++)
761-
{
762-
var ds = dic2str(list[i].Value);
763-
if (!group.ContainsKey(ds))
764-
group.Add(ds, new List<int>());
765-
group[ds].Add(list[i].Key);
766-
}
767-
768-
foreach (var gi in group)
769-
{
770-
foreach (var index in gi.Value)
771-
if (!check[index])
772-
color[index] = color_count;
773-
if (gi.Value.Count == 1)
774-
check[gi.Value[0]] = true;
775-
color_count++;
776-
}
777-
778-
if (previous_group != null && previous_group.Count == group.Count)
779-
break;
780-
781-
previous_group = group;
782-
}
783-
784-
var dicc = new Dictionary<int, int>();
785-
var inverse_transition = get_inverse_transtition(dia);
786-
for (int i = 0; i < color.Count; i++)
787-
if (!dicc.ContainsKey(color[i]))
788-
dicc.Add(color[i], i);
789-
else if (inverse_transition.ContainsKey(i))
790-
{
791-
foreach (var inv in inverse_transition[i])
792-
for (int j = 0; j < dia.nodes[inv].transition.Count; j++)
793-
if (dia.nodes[inv].transition[j].Item2.index == i)
794-
dia.nodes[inv].transition[j] = new Tuple<char, transition_node>(dia.nodes[inv].transition[j].Item1, dia.nodes[dicc[color[i]]]);
795-
}
796-
}
797-
787+
798788
/// <summary>
799789
/// Minimization DFA using Hopcroft Algorithm
800790
/// </summary>
801791
/// <param name="dia"></param>
802792
/// <returns></returns>
803-
private void opt_dfa_hopcroft(diagram dia)
793+
private void opt_dfa(diagram dia)
804794
{
805795
var visit = new HashSet<string>();
806796
var queue = new Queue<List<int>>();
@@ -809,7 +799,7 @@ private void opt_dfa_hopcroft(diagram dia)
809799
var acc_nodes = new List<int>();
810800
var nacc_nodes = new List<int>();
811801
foreach (var node in dia.nodes)
812-
if (node.is_acceptable)
802+
if (node.is_acceptable&&node.accept_token_names==null)
813803
acc_nodes.Add(node.index);
814804
else
815805
nacc_nodes.Add(node.index);
@@ -822,7 +812,25 @@ private void opt_dfa_hopcroft(diagram dia)
822812
color.AddRange(Enumerable.Repeat(0, dia.count_of_vertex));
823813

824814
acc_nodes.ForEach(x => color[x] = color_count);
825-
color_count = 1;
815+
color_count = 2;
816+
817+
#if true // For distingushiable states
818+
var dict_dist = new Dictionary<string, List<int>>();
819+
foreach (var node in dia.nodes)
820+
if (node.is_acceptable && node.accept_token_names != null)
821+
if (dict_dist.ContainsKey(node.accept_token_names[0]))
822+
dict_dist[node.accept_token_names[0]].Add(node.index);
823+
else
824+
dict_dist.Add(node.accept_token_names[0], new List<int> { node.index });
825+
826+
foreach (var dist in dict_dist)
827+
{
828+
foreach (var dd in dist.Value)
829+
color[dd] = color_count;
830+
queue.Enqueue(dist.Value);
831+
color_count++;
832+
}
833+
#endif
826834

827835
while (queue.Count > 0)
828836
{
@@ -832,11 +840,7 @@ private void opt_dfa_hopcroft(diagram dia)
832840

833841
if (visit.Contains(str)) continue;
834842
visit.Add(str);
835-
836-
//foreach (var node in front)
837-
// color[node] = color_count;
838-
//color_count++;
839-
843+
840844
// Collect transition color
841845
var dic = new Dictionary<int, SortedDictionary<char, int>>();
842846
foreach (var index in front)
@@ -979,7 +983,7 @@ public void Generate()
979983
diagram.nodes = nodes;
980984
diagram.start_node = nodes[0];
981985
diagram.count_of_vertex = nodes.Count;
982-
986+
983987
this.diagram = diagram;
984988
}
985989

@@ -1113,6 +1117,8 @@ public bool Error()
11131117
}
11141118

11151119
public int Position { get { return latest_pos; } }
1120+
public int Line { get { return current_line; } set { current_line = value; } }
1121+
public int Column { get { return current_column; } set { current_column = value; } }
11161122

11171123
public Tuple<string, string, int, int> Next()
11181124
{
@@ -1159,7 +1165,8 @@ public Tuple<string, string, int, int> Next()
11591165

11601166
node_pos = next_transition;
11611167
}
1162-
1168+
if (accept_table[node_pos] == null)
1169+
throw new Exception($"[SCANNER] Pattern not found! L:{cur_line}, C:{cur_column}, D:'{builder.ToString()}'");
11631170
return new Tuple<string, string, int, int> (accept_table[node_pos], builder.ToString(), cur_line + 1, cur_column + 1);
11641171
}
11651172

@@ -1171,4 +1178,4 @@ public Tuple<string, string, int, int> Lookahead()
11711178
return result;
11721179
}
11731180
}
1174-
}
1181+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /