# Parsing a text file of nested structures using a state machine

My goal is to have something really simple with as small an amount of code as possible. The real code is used to parse a text file of nested structures. This code is highly simplified but is the general way that the state machine would work.

Is there a replacement for the global?

# python doesn't support enums but can do this way
class state:
OUT = 0
DNARRAY = 1            # under "DN array" heading
CSTA_REQUEST = 2       # aPDU-rose : invoke :
CSTA_RESPONSE = 3      # aPDU-rose : retResult :
END_OF_FILE   = 4

currentstate = state.OUT

def do_out():
print "doing OUT - transitioning to DNARRAY"
global currentstate
currentstate = state.DNARRAY

def do_dnarray():
print "doing dn array - transitioning to csta request"
global currentstate
currentstate = state.CSTA_REQUEST

def do_csta_request():
print "doing csta request - transitioning to csta response"
global currentstate
currentstate = state.CSTA_RESPONSE

def do_csta_response():
print "doing csta response - transitioning to END_OF_FILE"
global currentstate
currentstate = state.END_OF_FILE

statemap = {state.OUT : do_out,
state.DNARRAY : do_dnarray,
state.CSTA_REQUEST : do_csta_request,
state.CSTA_RESPONSE : do_csta_response,
}

def decisions():
while(currentstate != state.END_OF_FILE):
statemap[currentstate]()

print "done!"

decisions()


The obvious answer is to make currentstate an explicit return value from your functions, for example:

def do_out():
print "doing OUT - transitioning to DNARRAY"
return state.DNARRAY


Then handle it appropriately in the final loop:

def decisions():
currentstate = state.OUT
while(currentstate != state.END_OF_FILE):
currentstate = statemap[currentstate]()
print "done!"


First, use a enum for the states. Yes, enums exist in Python now.

Your parser should be an object, and currentstate should be an instance variable. Its name should be shortened as well, since "current" should already be assumed. So, it would become self.state.

• I need to provide my script to many others here who just have default install of python 2.6 or 2.7. If I update my python to use these new enums would I be correct in assuming that they would need to do the same to use if my script contained enums new feature. – arcomber Aug 28 '14 at 16:01
• Then don't use enums. Instead, put your code in a CstaParser class. The constants can be defined in that class directly. – 200_success Aug 28 '14 at 16:06