76 lines
2.1 KiB
Python
76 lines
2.1 KiB
Python
import sys
|
|
|
|
def ReadDescription(file_path):
|
|
nfa = {}
|
|
accepting_states = set()
|
|
|
|
with open(file_path, 'r', encoding="utf-8") as description:
|
|
for line in description:
|
|
split_data = line.strip().split('\t')
|
|
|
|
if len(split_data) == 3:
|
|
state, next_state, symbol = split_data
|
|
key = (int(state), symbol)
|
|
if key in nfa:
|
|
nfa[key].add(int(next_state))
|
|
else:
|
|
nfa[key] = {int(next_state)}
|
|
|
|
elif len(split_data) == 2:
|
|
state, next_state = split_data
|
|
key = (int(state), '<eps>')
|
|
if key in nfa:
|
|
nfa[key].add(int(next_state))
|
|
else:
|
|
nfa[key] = {int(next_state)}
|
|
|
|
elif len(split_data) == 1:
|
|
accepting_states.add(int(split_data[0]))
|
|
|
|
return nfa, accepting_states
|
|
|
|
def Epsilon(nfa, states):
|
|
epsilon = set(states)
|
|
stack = list(states)
|
|
|
|
while stack:
|
|
currentState = stack.pop()
|
|
epsilon_key = (currentState, '<eps>')
|
|
if epsilon_key in nfa:
|
|
epsTransitions = nfa[epsilon_key]
|
|
for nextState in epsTransitions:
|
|
if nextState not in epsilon:
|
|
epsilon.add(nextState)
|
|
stack.append(nextState)
|
|
|
|
return epsilon
|
|
|
|
def IsAccepted(nfa, inputString, current_states, accepting_states):
|
|
for symbol in inputString:
|
|
new_states = set()
|
|
|
|
for state in current_states:
|
|
key = (state, symbol)
|
|
if key in nfa:
|
|
new_states.update(nfa[key])
|
|
|
|
current_states = Epsilon(nfa, new_states)
|
|
|
|
return any(state in accepting_states for state in current_states)
|
|
|
|
|
|
|
|
nfa_file = sys.argv[1]
|
|
nfa, acceptingStates = ReadDescription(nfa_file)
|
|
|
|
for line in sys.stdin:
|
|
inputString = line.strip()
|
|
if inputString =='\n':
|
|
break
|
|
start_states = Epsilon(nfa, {0})
|
|
|
|
if IsAccepted(nfa, inputString, start_states, acceptingStates):
|
|
print("TRUE", inputString)
|
|
else:
|
|
print("FALSE", inputString)
|