Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # simpleArith.py
- #
- # Example of defining an arithmetic expression parser using
- # the operatorGrammar helper method in pyparsing.
- #
- # Copyright 2006, by Paul McGuire
- #
- from pyparsing import *
- ParserElement.enablePackrat() #comment this out once for comparison
- # To use the operatorGrammar helper:
- # 1. Define the "atom" operand term of the grammar.
- # For this simple grammar, the smallest operand is either
- # and integer or a variable. This will be the first argument
- # to the operatorGrammar method.
- # 2. Define a list of tuples for each level of operator
- # precedence. Each tuple is of the form
- # (opExpr, numTerms, rightLeftAssoc, parseAction), where
- # - opExpr is the pyparsing expression for the operator;
- # may also be a string, which will be converted to a Literal
- # - numTerms is the number of terms for this operator (must
- # be 1 or 2)
- # - rightLeftAssoc is the indicator whether the operator is
- # right or left associative, using the pyparsing-defined
- # constants opAssoc.RIGHT and opAssoc.LEFT.
- # - parseAction is the parse action to be associated with
- # expressions matching this operator expression (the
- # parse action tuple member may be omitted)
- # 3. Call operatorGrammar passing the operand expression and
- # the operator precedence list, and save the returned value
- # as the generated pyparsing expression. You can then use
- # this expression to parse input strings, or incorporate it
- # into a larger, more complex grammar.
- #
- #dummy parse actions
- def action_op_prefix(s, loc, toks):
- # print "pre: ", toks
- return
- def action_op_infix(s, loc, toks):
- # print "in : ", toks
- return
- def action_op_infix_left(s, loc, toks):
- # print "inL: ", toks
- return
- #The leaf nodes of the parse tree: integer numbers and variable names
- integer = Word(nums).setParseAction(lambda t:int(t[0]))
- variable = (NotAny(Keyword('not') | Keyword('and') | Keyword('or')) +
- Word(alphas,exact=1))
- #Let parentheses work with power and unary '-' too
- expression = Forward()
- primary = integer | variable | Suppress('(') + expression + Suppress(')')
- #Power and unary operations are intertwined to get correct operator precedence:
- # -a**-b == -(a ** (-b))
- power, u_expr = Forward(), Forward()
- #Exponentiation: a**b;
- #Strongest binding on left side, weaker than unary operations (-a) on right side.
- power1 = Group(primary + '**' + u_expr) .setParseAction(action_op_infix)
- power << (power1 | primary)
- #Unary arithmetic operations: -a; +a
- u_expr1 = Group(oneOf('- +') + u_expr) .setParseAction(action_op_prefix)
- u_expr << (u_expr1 | power)
- #All other operators are defined here. Those with the strongest binding come first.
- expression << operatorPrecedence( u_expr,
- [(oneOf('* /'), 2, opAssoc.LEFT, action_op_infix_left),
- (oneOf('+ -'), 2, opAssoc.LEFT, action_op_infix_left),
- (oneOf('< > <= >= == !='), 2, opAssoc.LEFT, action_op_infix_left),
- (Keyword('not'), 1, opAssoc.RIGHT, action_op_prefix),
- (Keyword('and'), 2, opAssoc.LEFT, action_op_infix_left),
- (Keyword('or'), 2, opAssoc.LEFT, action_op_infix_left),
- ])
- test = [
- "1**2**3**4",
- "-2**-3 == -(2**(-3))", #why does this expression take so long?
- "3----++-2",
- "1 and 2 or not a and b",
- "not a <= a and c > d",
- "9 + 2 - 3 + 4",
- "9 + 2 * 4",
- "(9 + 2) * 3",
- "(9 + -2) * 3**-4**5",
- "M*X + B",
- "M*(X + B)",
- # "2+3*4-2+3*4-2+3*4**-2**+3*4-2+3*4 and -2+3*4-2+3*4 or -2+3*4**-2**+3*4**-2**+3*4\
- # -2+3*4-2+3*4-2+3*4-2+3*4-2+3*4-2 or 3*4-2 and not 3*4*2+3*4-2+3*4-2+3*4**-2**3*4\
- # -2+3*4-2+3*(4-2+3)*4*-2+3*4**-2**+3**4**-2**+3**(4-(2+3)*4-2+3*4-2+3*4-2)+3*4-+3\
- # *4-2+3*4-2+3*4*2+3*4-2+3*4-2+3*4**-2**+3**4**-2 < +3*4-2 or 3**4-2+3*4-2+3*4**-2\
- # **+3**-4**-2*+3*4-2+3*4-2==+3*4 or -2+3*4<-2+3*4-2+3*4-2+3*4-2+3*4+1-2-3-------4"
- ]
- #test the parser
- print
- for t in test:
- print t
- print expression.parseString(t)
- # print power.parseString(t)
- print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement