* !!! Модуль на рефале-5 $ENTRY Go { = <Prout <RE5 (ALT (CAT 'a') (CAT 'aa') (CAT 'aaaa') (CAT 'aaaaaaa') (CAT (ITER 'aaa') (ITER 'aaaaa') ) ) '1'>> <Card >; } $EXTRN CARD, PROUT; $EXTRN BR, CP, SYMB; $EXTRN OPEN, PUT, PUTOUT; $ENTRY RE5 { e.1 = <RegeMin e.1>; } $ENTRY DI5 { e.1 = <Open 'w' 7 'DI5.TXT'> <DI51 e.1>; } DI51 { * ??? ((e.1)) = <DI51 (e.1)>; ((s.a e.1) e.2) = <PUTOUT 7 ' '> <PUTOUT 7 s.a> ((s.a) <RegeMin e.1>) <DI51 (e.2)>; (s.a e.1) = <PUTOUT 7 ' '> <PUTOUT 7 s.a> ((s.a) <RegeMin e.1>); ( ) = ; } * Подпрограмма интерпретатора рег. выр. RE.REF * Рег.выр. будем обозначать через r.1 , r.2 , ... * Обращение <Re5 r.1> * Результат замены - минимальный коненый автомат в виде * (('1') 'a' ('2')) (('12') (Empty) (F)) ... * Пример автомата можно посмотреть в результате * тестового пуска этой программы * В файле RE5.TXT будет * - исходное рег.выр., * - конечный автомат, * - минимальный конечный автомат. Rege1 { e.1 = <Begin2 <Begin1 ( () (e.1) () ) e.1 <One_S e.1>>>; } Begin2 { (e.Rez) (e.Yes) ( ) = e.Rez; (e.Rez) (e.5 (e.1) e.6) ((e.1) e.2) = <Begin2 (e.Rez) (e.5 (e.1) e.6) (e.2)>; (e.Rez) (e.Yes) ((e.1) e.2) = <Begin2 <Begin1 ((e.Rez) (e.Yes (e.1)) (e.2)) (e.1) <One_S (e.1)> >>; } Begin1 { ((e.Rez) (e.Yes) (e.No)) (e.S) e.1 = (e.Rez ((e.S) '=' e.1)) <Plus (e.Yes) (e.No) e.1>; } * один шаг One_S { =; ( ) =; e.Exp = <Srch () e.Exp (S)> <Srch () e.Exp ( )>; } Plus { (e.1 (e.2) e.3) (e.No) ((s.a) (e.2)) e.7 = <Plus (e.1 (e.2) e.3) (e.No) e.7>; (e.Yes) (e.1 (e.2) e.3) ((s.a) (e.2)) e.7 = <Plus (e.Yes) (e.1 (e.2) e.3) e.7>; (e.Yes) (e.No) ((s.a) (e.2)) e.7 = <Plus (e.Yes) (e.No (e.2)) e.7>; (e.Yes) (e.No) (( ) (e.2)) e.7 = <Plus (e.Yes) (e.No) e.7>; (e.Yes) (e.No) = (e.Yes) (e.No); } * -------------------------------------------- * Модифицированный вариант программы * Regexp2.ref (Srch) * Обращение * <Srch () (r.Exp) ( S )> * результат замены ((s.1) r.1) ((s.2) r.2) ... * где s.i - обозреваемые символы, * r.i - рег.выр. * или <Srch () (r.Exp) ()> * результат замены - (() (T)) или (() (F)) Srch { (e.n) (ALT (CAT (ALT s.1 e.2) e.c) e.a) (e.s) = <Srch (e.n) (ALT (CAT s.1 e.c) (CAT (ALT e.2) e.c) e.a) (e.s) >; (e.n) (ALT (CAT (ALT (e.1) e.2) e.c) e.a) (e.s) = <Srch (e.n) (ALT (CAT (e.1) e.c) (CAT (ALT e.2) e.c) e.a) (e.s) >; (e.n) (ALT (CAT (ALT ) e.c) e.a) (e.s) = <Srch (e.n) (ALT e.a) (e.s) >; (e.n) (ALT (CAT (CAT e.1) e.c) e.a) (e.s) = <Srch (e.n) (ALT (CAT e.1 e.c) e.a) (e.s) >; () (ALT (CAT (ITER e.i) e.c) e.a) () = <Srch () (ALT (CAT e.c) e.a) ()>; (e.n) (ALT (CAT (ITER e.i) e.c) e.a) (e.s) = <Srch (e.n) (ALT (CAT e.c) (CAT e.i (NITER e.i) e.c) e.a) (e.s)>; (e.n) (ALT (CAT (NITER e.i) e.c) e.a) (e.s) = <Srch (e.n) (ALT e.a) (e.s)>; () (ALT (CAT ) e.a) () = (() (T)); (e.n) (ALT (CAT s.x e.c) e.a) (s.y) = <Srch ( <Add_en ( (s.x) (CAT <ReNITER e.c>)) e.n > ) (ALT e.a) (s.y) >; (e.n) (ALT (CAT e.c) e.a) (e.s) = <Srch (e.n) (ALT e.a) (e.s) >; () (ALT) () = (() (F)); * () (ALT) (e.s) = (() (F)); (e.n) (ALT) (s.x) = e.n ; } * --------------------------------------------- Add_en { ((s.x) (e.Exp1)) e.1 ((s.x) (ALT e.2)) e.3 = e.1 ((s.x) (ALT <Add_en1 (e.Exp1) e.2> )) e.3; ((s.x) (e.Exp1)) e.1 = ((s.x) (ALT (e.Exp1)) ) e.1; } Add_en1 { (e.1) e.2 (e.1) e.3 = e.2 (e.1) e.3 ; (e.1) e.2 = e.2 (e.1) ; } ReNITER { (NITER e.i) e.x = (ITER e.i) <ReNITER e.x>; s.a e.x = s.a <ReNITER e.x>; (e.a) e.x = (e.a) <ReNITER e.x>; = ; } * ------------------------------------------ RegeMin { e.1 = * <Open 'w' 7 'RE5.TXT'> <ReMin ( <Pre <Pre1 <Putout 7 ' Regular expression'> <Put 7 e.1> >> ) > ; } Pre1 { (ALT (CAT e.1)) = (ALT (CAT e.1)); (CAT e.1) = (ALT (CAT e.1)); e.1 = (ALT (CAT e.1)); } Pre { e.1 = <Br 'zam=' 1 > <Putout 7 ' Finite Automat '> <Out <Cod <REGE1 e.1>>>; } Out { (e.1) e.2 = (<Put 7 e.1>) <Out e.2>; = ; e.1 = <Put 7 e.1>; } Cod { ((e.1) '=' e.2) e5 = ( <Zam (e.1)> '=' <Cod1 e.2> ) <Cod e.5>; = ; } Cod1 { ((s.a) (e.1)) e.5 = (s.a <Zam (e.1)>) <Cod1 e.5>; (() (e.1)) e.5 = (Empty e.1) <Cod1 e.5>; = ; } Zam { e.1 = <Zam1 e.1 <Dg 'zam' >>; } Zam1 { (e.1) s.n e.5 ((e.1) s.k) e6 = s.k <Br 'zam=' s.n e.5 ((e.1) s.k) e.6 >; (e.1) s.n e.5 = s.n <Br 'zam=' <Add (s.n) 1> e.5 ( (e.1) s.n) >; } * Равенство двух автоматов * Обращение * <ReEq ( ) ((s.a s.b)) (Автомат 1) (Автомат 2) > * где s.a , s.b - номера начальных вершин автоматов * Результат замены T , F ReEq { F e.1 = F ; (e.1) ( ) (e.3) (e.4) = T ; (e.1) ((s.a s.b) e.0) (e.3 (s.a '=' e.4) e.5) (e.6 (s.b '=' e.7) e.8) = <ReEq <ReEq1 (e.1 (s.a s.b)) (e.0) (e.4) (e.7) > (e.3 (s.a '=' e.4) e.5) (e.6 (s.b '=' e.7) e.8) >; } ReEq1 { (e.1) (e.2) ( ) ( ) = (e.1) (e.2) ; (e.1) (e.2) ((s.a s.b) e.3) (e.4 (s.a s.c) e.5) = <ReEq1 <Dob (s.b s.c) (e.1) (e.2)> (e.3) (e.4 e.5) >; F e1 = F e.1 ; e1 = F e.1 ; } Dob { (F F) (e.1) (e.2) = (e.1) (e.2); (T T) (e.1) (e.2) = (e.1) (e.2); (T F) (e.1) (e.2) = F (e.1) (e.2); (F T) (e.1) (e.2) = F (e.1) (e.2); (s.b s.c) (e.1 (s.b s.c) e.2) (e.3) = (e.1 (s.b s.c) e.2) (e.3); (s.b s.c) (e.1) (e.2 (s.b s.c) e.4) = (e.1) (e.2 (s.b s.c) e.4); (s.b s.c) (e.1) (e.2) = (e.1) (e.2 (s.b s.c)); } * Построение минимального автомата. * Обращение <ReMin Automat > , - структура автомата - * (1 '=' ('1' 2) ('2' 3) ('3' 1) (() F) ) * (2 '=' ('1' 3) ('2' 2) (() T) ) ReMin { (e.1) = <ReEnd <ReMin1 (<Spis 1 <CP 'zam' >>) (e.1) >>; } ReEnd { (s.a '=' e.1) e.2 = <ReEnd1 s.a e.1> <ReEnd e.2>; = ; } ReEnd1 { s.a (Empty s.c) e1 = (<SYMB1 s.a> Empty <SYMB1 s.c>) <ReEnd1 s.a e.1>; s.a (s.b s.c) e1 = (<SYMB1 s.a> s.b <SYMB1 s.c>) <ReEnd1 s.a e.1>; s.a = ; } SYMB1 { T = T ; F = F ; s.a = <IMPLODE 'Q' <SYMB s.a>>; } Spis { s.n s.n e.1 = ; s.n s.m e.1 = s.n <Spis <Add (s.n) 1> s.m >; } ReMin1 { (s.a e.Sp) (e.Aut) = <ReMin2 ((s.a)) (() e.Sp) (e.Aut) >; } ReMin2 { (e.1 (s.a e.2)) ((e.3) s.b e.4) (e.Aut) = <ReMin3 <ReEq () ((s.a s.b)) (e.Aut) (e.Aut)> (e.1 (s.a e.2)) ((e.3) s.b e.4) (e.Aut) >; (e.1 (e.2)) (( )) (e.Aut) = <ReMin9 (e.1 (e.2)) (e.Aut) >; (e.1 (e.2)) ((s.b e.3)) (e.Aut) = <ReMin2 (e.1 (e.2) (s.b)) (() e.3) (e.Aut)>; } ReMin3 { T (e.1 (s.a e.2)) ((e.3) s.b e.4) (e.Aut) = <ReMin2 (e.1 (s.a e.2 s.b)) ((e.3) e.4) (e.Aut) >; F (e.1 (s.a e.2)) ((e.3) s.b e.4) (e.Aut) = <ReMin2 (e.1 (s.a e.2)) ((e.3 s.b) e.4) (e.Aut) >; } ReMin9 { (e.1) (e.Aut) = <Putout 7 ' Min.Automat' > <Out <ReMin8 (e.1) (e.Aut) >>; } ReMin8 { (e.1) () = ; (e.1 (s.a e.2) e3) ((s.a '=' e.4) e.5) = (s.a '=' <ZamMin (e.1 (s.a e.2) e.3) e.4 > ) <ReMin8 (e.1 (s.a e.2) e.3) (e.5) > ; (e.1) ((e.4) e.5) = <ReMin8 (e.1) (e.5)>; } ZamMin { (e.1 (s.c e.2) e.3) (s.b s.c) e.7 = (s.b s.c) <ZamMin (e.1 (s.c e.2) e.3) e7 >; (e.1 (s.a e.2 s.c e.3) e.4) (s.b s.c) e.7 = (s.b s.a) <ZamMin (e.1 (s.a e.2 s.c e.3) e.4) e.7 >; (e.1) = ; (e.1) (e.2) e.3 = (e.2) <ZamMin (e.1) e.3>; }