Here’s some code to implement an expression parser:
from pyparsing import Word, nums
from string import lowercase
nonzero = ''.join([str(i) for i in range(1, 10)])
integer = Word(nonzero, nums)
varname = Word(lowercase)
equals = '='
operator = Word('+-*/', exact=1)
operand = (integer ^ varname)
unaryoperation = operand
binaryoperation = (operand + operator + operand)
operation = unaryoperation ^ binaryoperation
expression = varname + equals + operation
def main():
for i in ('foo = 1', 'bar = 1 + 2', 'baz = foo + bar', 'bat = baz', 'foo = baz / 2'):
print '%s: %s' % (i, str(expression.parseString(i)))
if __name__ == '__main__':
main()
The output:
foo = 1: ['foo', '=', '1'] bar = 1 + 2: ['bar', '=', '1', '+', '2'] baz = foo + bar: ['baz', '=', 'foo', '+', 'bar'] bat = baz: ['bat', '=', 'baz'] foo = baz / 2: ['foo', '=', 'baz', '/', '2']
Before creating our little calculator program, one minor enhancement can be done: as we know the second element in the returned array-like object will always be a ‘=’ sign, we can ignore this. This can be easily expressed in our code: every Pyparsing object got a ’suppress’ method. Currently our equals variable is a plain Python string, so we first need to convert this into a Pyparsing object. The object type to use in this case is ‘Literal’. Add this in the import statement, use a Literal object instead of a string in the expression definition, and suppress it:
expression = varname + Literal(equals).suppress() + operation
Now re-check the output of the script.














5 Responses to “Pyparsing introduction: BNF to code”
Leave a comment