simpleBool.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #
  2. # simpleBool.py
  3. #
  4. # Example of defining a boolean logic parser using
  5. # the operatorGrammar helper method in pyparsing.
  6. #
  7. # In this example, parse actions associated with each
  8. # operator expression will "compile" the expression
  9. # into BoolXXX class instances, which can then
  10. # later be evaluated for their boolean value.
  11. #
  12. # Copyright 2006, by Paul McGuire
  13. # Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
  14. #
  15. from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
  16. # define classes to be built at parse time, as each matching
  17. # expression type is parsed
  18. class BoolOperand(object):
  19. def __init__(self,t):
  20. self.label = t[0]
  21. self.value = eval(t[0])
  22. def __bool__(self):
  23. return self.value
  24. def __str__(self):
  25. return self.label
  26. __repr__ = __str__
  27. __nonzero__ = __bool__
  28. class BoolBinOp(object):
  29. def __init__(self,t):
  30. self.args = t[0][0::2]
  31. def __str__(self):
  32. sep = " %s " % self.reprsymbol
  33. return "(" + sep.join(map(str,self.args)) + ")"
  34. def __bool__(self):
  35. return self.evalop(bool(a) for a in self.args)
  36. __nonzero__ = __bool__
  37. __repr__ = __str__
  38. class BoolAnd(BoolBinOp):
  39. reprsymbol = '&'
  40. evalop = all
  41. class BoolOr(BoolBinOp):
  42. reprsymbol = '|'
  43. evalop = any
  44. class BoolNot(object):
  45. def __init__(self,t):
  46. self.arg = t[0][1]
  47. def __bool__(self):
  48. v = bool(self.arg)
  49. return not v
  50. def __str__(self):
  51. return "~" + str(self.arg)
  52. __repr__ = __str__
  53. __nonzero__ = __bool__
  54. TRUE = Keyword("True")
  55. FALSE = Keyword("False")
  56. boolOperand = TRUE | FALSE | Word(alphas,max=1)
  57. boolOperand.setParseAction(BoolOperand)
  58. # define expression, based on expression operand and
  59. # list of operations in precedence order
  60. boolExpr = infixNotation( boolOperand,
  61. [
  62. ("not", 1, opAssoc.RIGHT, BoolNot),
  63. ("and", 2, opAssoc.LEFT, BoolAnd),
  64. ("or", 2, opAssoc.LEFT, BoolOr),
  65. ])
  66. if __name__ == "__main__":
  67. p = True
  68. q = False
  69. r = True
  70. tests = [("p", True),
  71. ("q", False),
  72. ("p and q", False),
  73. ("p and not q", True),
  74. ("not not p", True),
  75. ("not(p and q)", True),
  76. ("q or not p and r", False),
  77. ("q or not p or not r", False),
  78. ("q or not (p and r)", False),
  79. ("p or q or r", True),
  80. ("p or q or r and False", True),
  81. ("(p or q or r) and False", False),
  82. ]
  83. print("p =", p)
  84. print("q =", q)
  85. print("r =", r)
  86. print()
  87. for t,expected in tests:
  88. res = boolExpr.parseString(t)[0]
  89. success = "PASS" if bool(res) == expected else "FAIL"
  90. print (t,'\n', res, '=', bool(res),'\n', success, '\n')