Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3.1
- import sys
- ''' Undeterministic machina which accept/decline input sequence of word
- Example of running:
- python3.1 NFA.py zadani.txt < vstupy.txt
- '''
- class Table:
- ''' Contains table of transitions '''
- __states = [] ## 3dimensional array which holds array of transits for each state
- __tr = [] ## transits in this table
- __map = {}
- __final = []
- __numStates = 0
- __closures = []
- def __init__( self, config ):
- ''' Build table based on cofig file '''
- fh = None
- try:
- fh = open(config, 'r');
- arr = fh.readline().strip().split()[1:]
- self.__tr = [ tr for tr in arr ]
- # map holds indexes in table of states based on characted for input
- for num, tr in enumerate(arr):
- self.__map[tr] = num
- # fill table of states
- line = fh.readline()
- state = 0
- while len(line) > 0:
- arr = line.strip().split()
- if arr[0].startswith("<"): self.__final.append( state )
- self.__states.append( [] )
- for num, tr in enumerate(arr[1:]):
- self.__states[state].append( set() )
- for i, st in enumerate(tr.split("|")):
- if st != "-":
- self.__states[state][num].add(int(st))
- state += 1
- line = fh.readline()
- #endwhile
- except IOError as io:
- print("Cannot load file " + config )
- finally:
- if fh != None:
- fh.close()
- self.__numStates = len( self.__states )
- # recursively building eps-closures
- for st in range( self.__numStates ):
- self.__closures.append( set() )
- self.buildClosures( st, self.__closures[st] )
- def buildClosures(self, state, closures) :
- ''' Recursive function for building eps-closures
- state int for which state we append eps-closures
- closures set where to append closures
- '''
- arr = self.__states[ state ] [ self.__map["\eps"] ]
- if len( arr ) > 0:
- closures.update( arr )
- for a in arr:
- self.buildClosures( a, closures )
- def __str__(self):
- out = "Table of transitions\n"
- for i,st in enumerate(self.__states):
- out += str(i) + ". prechody:" + str(st) + "uzavery:" + str(self.__closures[i]) + "\n"
- out += "\nKonecne stavy: " + str (self.__final) + "\n\n"
- return out
- def getState( self, state, transit ):
- '''Returns set of states even from eps-closures'''
- out = set()
- # adding transitions for given state
- out.update(self.__states[ state ] [self.__map[transit]])
- # adding eps-closures from transitions
- for tr in self.__states[ state ] [ self.__map[transit] ]:
- out.update(self.__closures[ tr ])
- # adding transitions from eps-closures
- for tr in self.__closures[state]:
- out.update(self.__states[ tr ][ self.__map[transit] ])
- # adding eps-closures for given state WRONG!
- # out.update(self.__closures[state])
- return out
- def isFinal(self, state):
- return state in self.__final
- class Machine:
- def __init__(self, table):
- self.__states = set([0])
- self.__table = table
- self.__nextStates = set()
- def parseString( self, string ):
- ''' Raise self.changeState() for every char in input string '''
- self.__states = set([0])
- for c in string:
- for st in self.__states:
- self.changeState( self.__table.getState(st, c) )
- self.swapStates()
- #print( "Pro '"+ str(c) + "' :" + str ( self.__states ))
- for st in self.__states:
- if self.__table.isFinal( st ) == True:
- return True
- return False
- def swapStates( self ):
- '''Perform union of current states and desired states'''
- self.__states = self.__nextStates
- self.__nextStates = set()
- def changeState(self, states):
- '''Prepare new array with actual states. Doesnt change inner states of object'''
- self.__nextStates.update( states )
- if __name__ == '__main__':
- if len( sys.argv ) != 2:
- print("Usage: {0} konfiguracni_soubor".format( sys.argv[0] ))
- sys.exit()
- table = Table( sys.argv[-1] )
- # print( table )
- machine = Machine( table )
- while True:
- try:
- s = input()
- # if len(s) == 0:
- # break
- ret = machine.parseString ( s )
- print( str( int(ret) ) )
- except EOFError:
- break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement