I am trying to parse and evaluate expressions, given to me as input from a file, of the form:
var[3] = 0 and var[2] = 1
var[0] = 1 and var[2] = 0 and var[3] = 1
...
(actually I also allow "multibit access" (i.e. var[X:Y]) but let's ignore it for now...)
Where var is an integer, and the [] indicates bit access.
For example, for var = 0x9, the first expression above should be evaluated to False, and the second should be evaluated to True since 0x9 = b1001.
and and = are the only binary operators I allow, and for the = operator, the left operand is always var[X] and the right operand is always a number.
I tried to look around a bit and found that this could be achieved with Python's pyparsing, but I ran into some difficulties trying to implement it.
Here's what I've tried so far, based roughly on this example (which is one of many examples provided here):
#!/usr/bin/env python
from pyparsing import Word, alphas, nums, infixNotation, opAssoc
class BoolAnd():
def __init__(self, pattern):
self.args = pattern[0][0::2]
def __bool__(self):
return all(bool(a) for a in self.args)
__nonzero__ = __bool__
class BoolEqual():
def __init__(self, pattern):
self.bit_offset = int(pattern[0][1])
self.value = int(pattern[0][-1])
def __bool__(self):
return True if (0xf >> self.bit_offset) & 0x1 == self.value else False # for now, let's assume var == 0xf
__nonzero__ = __bool__
variable_name = 'var'
bit_access = variable_name + '[' + Word(nums) + ']'
multibit_access = variable_name + '[' + Word(nums) + ':' + Word(nums) + ']'
value = Word(nums)
operand = bit_access | multibit_access | value
expression = infixNotation(operand,
[
('=', 2, opAssoc.LEFT, BoolEqual),
('AND', 2, opAssoc.LEFT, BoolAnd),
])
p = expression.parseString('var[3] = 1 AND var[1] = 0', True)
print 'SUCCESS' if bool(p) else 'FAIL'
I have three problems I need help with.
- For multibit access of the form
var[X:Y] = Z, how do I enforce that:
a.X > Y
b.Z < 2^{X - Y + 1}
I assume this can't be enforced by the grammar itself (for example, for single-bit access of the formvar[X] = Y, I can enforce by the grammar thatYwill be either0or1, and this will cause theexpression.parseString()to fail with exception ifY != 0/1). - Most importantly: Why does it always print
SUCCESS? What am I doing wrong?
For the inputvar[3] = 1 AND var[1] = 0it should be printFAIL(you can see in my example that I hardcodedvarto be0xf, sovar[3] = 1isTruebutvar[1] = 0isFalse). - Which brings me to my third problem:
varis not a class member ofBoolEqualnor is it global... is there a way to somehow send it toBoolEqual's__init__function?
print('SUCCESS' if bool(p[0]) else 'FAIL')