[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

self.lex.scan()
left = left / self.Term()
else:
raise SyntaxError()


def Term(self):
if self.lex.token == 'num':
val = self.lex.match('num') # numbers
return val
elif self.lex.token == 'var':
if self.lex.value in self.vars.keys(): # keys(): EIBTI!
val = self.vars[self.lex.value] # look up name's value
self.lex.scan()
return val
else:
raise UndefinedError(self.lex.value)
elif self.lex.token == '(':
self.lex.scan()
val = self.Expr() # sub-expression
self.lex.match(')')
return val
else:
raise SyntaxError()


if name == 'main':
import testparser # self-test code
testparser.test(Parser, 'parser1') # test local Parser


If you study this code closely, you’ll notice that the parser keeps a dictionary
(self.vars) to manage variable names: they’re stored in the dictionary on a set com-
mand and are fetched from it when they appear in an expression. Tokens are repre-
sented as strings, with an optional associated value (a numeric value for numbers and
a string for variable names).


The parser uses iteration (while loops) rather than recursion for the expr-tail and
factor-tail rules. Other than this optimization, the rules of the grammar map directly
onto parser methods: tokens become calls to the scanner, and nested rule references
become calls to other methods.


When the file parser1.py is run as a top-level program, its self-test code is executed,
which in turn simply runs a canned test in the module shown in Example 19-15. Notice
how the scanner converts numbers to strings with int; this ensures that all integer math
invoked by the parser supports unlimited precision, simply because it uses Python
integers which always provide the extra precision if needed (the separate Python 2.X
long type and syntax is no more).


Also notice that mixed integer/floating-point operations cast up to floating point since
Python operators are used to do the actual calculations along the way. The expression
language’s / division operator also inherits Python 3.X’s true division model which
retains remainders and returns floating point results regardless of operand types. We


Custom Language Parsers| 1445
Free download pdf