Reputation: 1175
I have based my code on http://pyparsing.wikispaces.com/file/view/simpleBool.py/451074414/simpleBool.py I want to parse language generating words like this:
ABC:"a" and BCA:"b" or ABC:"d"
After parsing I want to evaluate bool value of this expresion. In code I have dict with key ABC and BCA, and ABC:"a" mean "a" in dict[ABC].
Somewhere I make mistake but I can not find where, conversion to bool always return True.
output:
DEBUG self.value=True
[ABC:"a"[True]] True
DEBUG self.value=False
[ABC:"h"[False]] True
code:
from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas, dblQuotedString, removeQuotes
d = {
"ABC": "TEST abc TEST",
"BCA": "TEST abc TEST",
}
class BoolOperand:
def __init__(self, t):
self.value = t[2] in d[t[0]]
print(F"DEBUG self.value={self.value}")
self.label = f"{t[0]}:\"{t[2]}\"[{str(self.value)}]"
def __bool__(self):
print("GET V")
return self.value
def __str__(self):
return self.label
__nonzero__ = __bool__
__repr__ = __str__
class BoolBinOp:
def __init__(self, t):
self.args = t[0][0::2]
def __str__(self):
sep = " %s " % self.reprsymbol
return "(" + sep.join(map(str, self.args)) + ")"
def __bool__(self):
print("DEBUG BoolBinOp")
return self.evalop(bool(a) for a in self.args)
__nonzero__ = __bool__
__repr__ = __str__
class BoolAnd(BoolBinOp):
reprsymbol = '&'
evalop = all
class BoolOr(BoolBinOp):
reprsymbol = '|'
evalop = any
class BoolNot:
def __init__(self, t):
self.arg = t[0][1]
def __bool__(self):
print("DEBUG BoolNot")
v = bool(self.arg)
return not v
def __str__(self):
return "~" + str(self.arg)
__repr__ = __str__
__nonzero__ = __bool__
EXPRESSION = Word(alphas) + ":" + dblQuotedString().setParseAction(removeQuotes)
TRUE = Keyword("True")
FALSE = Keyword("False")
boolOperand = TRUE | FALSE | EXPRESSION
boolOperand.setParseAction(BoolOperand)
boolExpr = infixNotation(boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
if __name__ == "__main__":
res = boolExpr.parseString('ABC:"a"')
print(res, "\t", bool(res))
print("\n\n")
res = boolExpr.parseString('ABC:"h"')
print(res, "\t", bool(res))
Upvotes: 1
Views: 378
Reputation: 63747
If at the end of your program you add:
print(type(res), bool(res))
print(type(res[0]), bool(res[0]))
You'll see
<class 'pyparsing.ParseResults'> True
GET V
<class '__main__.BoolOperand'> False
res
is not your parsed operand, it is a ParseResults
container of your parsed operand. If you evaluate res[0]
you'll see how your operand is evaluating.
ParseResults
will have similar behavior as lists with respect to bool
. If non-empty, they will be True
, if empty they will be False
. Add these lines to your program:
res.pop(0)
print(bool(res))
And you'll see the ParseResults
is False
, indicating that it has no contents.
Upvotes: 1