From 56a2d0e023d6751c60d497abd0f791ce15a91351 Mon Sep 17 00:00:00 2001 From: dejavudwh <494319000@qq.com> Date: Fri, 20 Sep 2019 16:11:22 +0800 Subject: [PATCH] Update the factor and and operations --- nfa/construction.py | 72 ++++++++++++++++++++++++++++++++++++++++++--- nfa/nfa.py | 17 +++++++---- test.py | 19 ++++++------ 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/nfa/construction.py b/nfa/construction.py index 2239052..5738a44 100644 --- a/nfa/construction.py +++ b/nfa/construction.py @@ -1,7 +1,10 @@ from lex.token import Token from lex.lexer import scanner from lex.lexer import Lexer -from nfa.nfa import Nfa +from nfa.nfa import ( + Nfa, + NfaPair, +) from nfa.nfa import EPSILON from nfa.nfa import CCL from nfa.nfa import EMPTY @@ -13,12 +16,13 @@ # 对 . a (单个字符) [] 进行匹配 +# term -> a | [] | . def term(pair_out): if lexer.match(Token.L): nfa_single_char(pair_out) elif lexer.match(Token.ANY): nfa_dot_char(pair_out) - elif lexer.match(Token.CCL_START): + elif lexer.match(Token.CCL_START): nfa_set_char(pair_out) @@ -77,6 +81,47 @@ def dodash(input_set): lexer.advance() +# factor connect +# factor -> factor factor +def factor_conn(pair_out): + if is_conn(lexer.current_token): + factor(pair_out) + + while is_conn(lexer.current_token): + pair = NfaPair() + factor(pair) + pair_out.end_node.next_1 = pair.start_node + pair_out.end_node = pair.end_node + + return True + + +def is_conn(token): + nc = [ + Token.CLOSE_PAREN, + Token.AT_EOL, + Token.EOS, + Token.CLOSURE, + Token.PLUS_CLOSE, + Token.CCL_END, + Token.AT_BOL, + ] + print(lexer.current_token, token not in nc) + return token not in nc + + +# factor * + ? closure +# factor -> term* | term+ | term? +def factor(pair_out): + term(pair_out) + if lexer.match(Token.CLOSURE): + nfa_star_closure(pair_out) + elif lexer.match(Token.PLUS_CLOSE): + nfa_plus_closure(pair_out) + elif lexer.match(Token.OPTIONAL): + nfa_option_closure(pair_out) + + # * 闭包操作 def nfa_star_closure(pair_out): if not lexer.match(Token.CLOSURE): @@ -105,10 +150,29 @@ def nfa_plus_closure(pair_out): start.next_1 = pair_out.start_node pair_out.end_node.next_1 = pair_out.start_node - pair_out.end_node.next_2 = end + pair_out.end_node.next_2 = end pair_out.start_node = start pair_out.end_node = end lexer.advance() - return True \ No newline at end of file + return True + + +# ? +def nfa_option_closure(pair_out): + if not lexer.match(Token.OPTIONAL): + return False + start = Nfa() + end = Nfa() + + start.next_1 = pair_out.start_node + start.next_2 = end + pair_out.end_node.next_1 = end + + pair_out.start_node = start + pair_out.end_node = end + print(lexer.current_token, '****') + lexer.advance() + print(lexer.current_token, '****') + return True diff --git a/nfa/nfa.py b/nfa/nfa.py index 7efea15..05dcf36 100644 --- a/nfa/nfa.py +++ b/nfa/nfa.py @@ -36,13 +36,18 @@ def __init__(self): def log_nfa(start_node): - if start_node is None or (start_node.next_1 is None and start_node.next_2 is None) or start_node.visited: - return - log('from: ', start_node.status_num, 'to: ', - start_node.next_1.status_num, 'in: ', start_node.edge) + log('NFA: ******** ') + if start_node.next_1 is not None: + log('from: ', start_node.status_num) + log('to: ', start_node.next_1.status_num) + log('in: ', start_node.edge) + else: + log('accept: ', start_node.status_num) start_node.visited = True if hasattr(start_node, 'input_set'): log('input set: ', start_node.input_set) - log_nfa(start_node.next_1) - log_nfa(start_node.next_2) \ No newline at end of file + if start_node.next_1 is not None and not start_node.next_1.visited: + log_nfa(start_node.next_1) + if start_node.next_2 is not None and not start_node.next_2.visited: + log_nfa(start_node.next_2) diff --git a/test.py b/test.py index a19d142..b4c0e0e 100644 --- a/test.py +++ b/test.py @@ -1,10 +1,11 @@ from nfa.construction import ( - term, - nfa_star_closure, - nfa_plus_closure, + factor, + factor_conn, ) from nfa.nfa import NfaPair -from nfa.nfa import log_nfa +from nfa.nfa import ( + log_nfa, +) nfa_pair = NfaPair() @@ -16,9 +17,9 @@ # node2.next_2 = Nfa() # 5 # term(nfa_pair) # nfa_star_closure(nfa_pair) -term(nfa_pair) -nfa_plus_closure(nfa_pair) +# term(nfa_pair) +# nfa_option_closure(nfa_pair) # debugNfa(nfa_pair.start_node) -log_nfa(nfa_pair.start_node) -# print(nfa_pair.start_node.next_1) - +# factor(nfa_pair) +factor_conn(nfa_pair) +log_nfa(nfa_pair.start_node) \ No newline at end of file