Skip to content

Commit

Permalink
Update the factor and and operations
Browse files Browse the repository at this point in the history
  • Loading branch information
dejavudwh committed Sep 20, 2019
1 parent e2ce827 commit 56a2d0e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 19 deletions.
72 changes: 68 additions & 4 deletions nfa/construction.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)


Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
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
17 changes: 11 additions & 6 deletions nfa/nfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
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)
19 changes: 10 additions & 9 deletions test.py
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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)

0 comments on commit 56a2d0e

Please sign in to comment.