@@ -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