- def scan(text) :
- """scan splits apart the symbols in text into a list.
- pre: text is a string holding a proposition
- post: answer is a list of the words and symbols within text
- (spaces and newlines are removed)
- """
- OPERATORS = ("(", ")", "+", "-", ";", ":", "=") # must be one-symbol operators
- SPACES = (" ", "\n")
- SEPARATORS = OPERATORS + SPACES
- nextword = "" # the next symbol/word to be added to the answer list
- answer = []
- for letter in text:
- # invariant: answer + nextword + letter equals all the words/symbols
- # read so far from text with SPACES removed
- # see if nextword is complete and should be appended to answer:
- if letter in SEPARATORS and nextword != "" :
- answer.append(nextword)
- nextword = ""
- if letter in OPERATORS :
- answer.append(letter)
- elif letter in SPACES :
- pass # discard space
- else : # build a word or numeral
- nextword = nextword + letter
- if nextword != "" :
- answer.append(nextword)
- return answer
- EOF = "!" # a word that marks the end of the input words
- def getNextword() :
- """moves the front word in wordlist to nextword.
- If wordlist is empty, sets nextword = EOF
- """
- global nextword, wordlist
- if wordlist == [] :
- nextword = EOF
- else :
- nextword = wordlist[0]
- wordlist = wordlist[1:]
- def parseEXPR() :
- """builds an EXPR operator tree from the words
- in nextword + wordlist,
- where EXPR ::= NUMERAL | VAR | ( EXPR OP EXPR )
- OP is "+" or "-"
- also, maintains the global invariant (on wordlist and nextword)
- """
- if nextword.isdigit() : # a NUMERAL ?
- ans = nextword
- getNextword()
- elif isVar(nextword) : # a VARIABLE ?
- ans = nextword
- getNextword()
- elif nextword == "(" : # ( EXPR op EXPR ) ?
- getNextword()
- tree1 = parseEXPR()
- op = nextword
- if op == "+" or op == "-" :
- getNextword()
- tree2 = parseEXPR()
- if nextword == ")" :
- ans = [op, tree1, tree2]
- getNextword()
- else :
- error("missing )")
- else :
- error("missing operator")
- else :
- error("illegal symbol to start an expression")
- return ans
- def isVar(word) :
- """checks whether word is a legal variable name"""
- KEYWORDS = ("print", "while", "end")
- ans = ( word.isalpha() and not(word in KEYWORDS) )
- return ans
- def error(message) :
- """prints an error message and halts the parse"""
- print "parse error: " + message
- print nextword, wordlist
- raise Exception
- def parse() :
- """reads the input mini-program and builds an operator tree for it,
- where PROGRAM ::= COMMANDLIST
- Initializes the global invariant (for nextword and wordlist)
- """
- global wordlist
- text = raw_input("Type the expression: ")
- wordlist = scan(text)
- getNextword()
- # assert: invariant for nextword and wordlist holds true here
- tree = parseEXPR()
- # assert: tree holds the entire operator tree for text
- #print tree
- if nextword != EOF :
- error("there are extra words")
- return tree
Raw Paste