"""Correctness parser for S-expression grammar. Note that this program commits a massive style faux pas: the variables token and tokens are global variables. In other words, they are accessible from anywhere in the program. I chose to do this because this any attempt to do this 'right' results in a bunch of parameters getting passed around that obscures the idea that this demonstration program is trying to convey. Sometimes 'proper' isn't always 'simplest.'""" import sys def tokenize(lexemes): global tokens # Make a copy of lexemes (don't just point tokens at it) tokens = list(lexemes) for i in range(len(tokens)): if tokens[i] not in ["(" , ")" , "'" , None]: tokens[i] = 'atom' def nextToken(): """Grab the next token. Set the current token to None if there are no more tokens.""" global token #print 'Matched',token if len(tokens)>0: token = tokens.pop(0) else: token = None def match(expected): """Match the current token against the expected value. If successful, grab the next token. Set the current token to None if there are no more tokens.""" if token==expected: nextToken() else: raise Exception('Parse error',token,expected) def P(): if token in ['atom' , "'" , '(']: E() else: raise Exception('Parse error') def E(): if token == 'atom': match('atom') elif token == "'": match("'") E() elif token == "(": match("(") E() Es() match(")") else: raise Exception('Parse error') def Es(): if token in ['atom' , "'" , '(']: E() Es() elif token == ")": pass """Open up the file, grab the program, and parse it.""" file = open(sys.argv[1],'r') data = file.read() file.close() lexemes = data.split() tokenize(lexemes) token = tokens.pop(0) P() print "Success"