我试图分析和评估表达式,从文件给我作为输入,形式为:Python的pyparsing:实现语法解析逻辑与表达
var[3] = 0 and var[2] = 1
var[0] = 1 and var[2] = 0 and var[3] = 1
...
(其实我也让“多位访问“(即var[X:Y]
),但让我们忽略它现在...)
其中var是一个整数,[]
指示位访问。
例如,对于var = 0x9
,上面的第一个表达式应该评估为False
,第二个表达式应该从0x9 = b1001
开始评估为True
。
and
和=
是我允许的唯一二元运算符,对于=
运算符,左操作数始终为var[X]
,右操作数始终为数字。
我试着环顾了一下,发现这可能与使用Python的pyparsing
可以实现,但我遇到了一些困难,努力实现它。
这是我到目前为止已经试过,在this example大致基于(这是提供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'
我有三个问题,我需要帮助。
- 对于形式
var[X:Y] = Z
的多位访问,我该如何强制执行:
一个。X > Y
b。Z < 2^{X - Y + 1}
我认为这不能由语法本身来实施(例如,对于形式var[X] = Y
的单位的访问,我可以由语法强制执行Y
将或者0
或1
,并且这将导致expression.parseString()
如果Y != 0/1
)失败。 - 更重要的是:为什么总是打印
SUCCESS
?我究竟做错了什么?
对于输入var[3] = 1 AND var[1] = 0
应该是打印FAIL
(你可以在我的例子,我硬编码var
是0xf
看,所以var[3] = 1
是True
但var[1] = 0
是False
)。 - 这将我带到我的第三个问题:
var
是不是BoolEqual
的类成员也不是全球...有没有办法以某种方式将它发送到BoolEqual
的__init__
函数?
对#2的简单回答:p是一个非空的ParseResults,因此无论内容如何,它都将始终评估为True。试试'print('SUCCESS'if bool(p [0])else'FAIL')' – PaulMcG