Skip to content

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)