simpleArith.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #
  2. # simpleArith.py
  3. #
  4. # Example of defining an arithmetic expression parser using
  5. # the infixNotation helper method in pyparsing.
  6. #
  7. # Copyright 2006, by Paul McGuire
  8. #
  9. from pyparsing import *
  10. integer = Word(nums).setParseAction(lambda t:int(t[0]))
  11. variable = Word(alphas,exact=1)
  12. operand = integer | variable
  13. expop = Literal('^')
  14. signop = oneOf('+ -')
  15. multop = oneOf('* /')
  16. plusop = oneOf('+ -')
  17. factop = Literal('!')
  18. # To use the infixNotation helper:
  19. # 1. Define the "atom" operand term of the grammar.
  20. # For this simple grammar, the smallest operand is either
  21. # and integer or a variable. This will be the first argument
  22. # to the infixNotation method.
  23. # 2. Define a list of tuples for each level of operator
  24. # precendence. Each tuple is of the form
  25. # (opExpr, numTerms, rightLeftAssoc, parseAction), where
  26. # - opExpr is the pyparsing expression for the operator;
  27. # may also be a string, which will be converted to a Literal
  28. # - numTerms is the number of terms for this operator (must
  29. # be 1 or 2)
  30. # - rightLeftAssoc is the indicator whether the operator is
  31. # right or left associative, using the pyparsing-defined
  32. # constants opAssoc.RIGHT and opAssoc.LEFT.
  33. # - parseAction is the parse action to be associated with
  34. # expressions matching this operator expression (the
  35. # parse action tuple member may be omitted)
  36. # 3. Call infixNotation passing the operand expression and
  37. # the operator precedence list, and save the returned value
  38. # as the generated pyparsing expression. You can then use
  39. # this expression to parse input strings, or incorporate it
  40. # into a larger, more complex grammar.
  41. #
  42. expr = infixNotation( operand,
  43. [("!", 1, opAssoc.LEFT),
  44. ("^", 2, opAssoc.RIGHT),
  45. (signop, 1, opAssoc.RIGHT),
  46. (multop, 2, opAssoc.LEFT),
  47. (plusop, 2, opAssoc.LEFT),]
  48. )
  49. test = ["9 + 2 + 3",
  50. "9 + 2 * 3",
  51. "(9 + 2) * 3",
  52. "(9 + -2) * 3",
  53. "(9 + -2) * 3^2^2",
  54. "(9! + -2) * 3^2^2",
  55. "M*X + B",
  56. "M*(X + B)",
  57. "1+2*-3^4*5+-+-6",]
  58. for t in test:
  59. print(t)
  60. print(expr.parseString(t))
  61. print('')