【发布时间】:2019-04-18 12:56:12
【问题描述】:
使用recursive,我可以生成简单的 AST,例如
from hypothesis import *
from hypothesis.strategies import *
def trees():
base = integers(min_value=1, max_value=10).map(lambda n: 'x' + str(n))
@composite
def extend(draw, children):
op = draw(sampled_from(['+', '-', '*', '/']))
return (op, draw(children), draw(children))
return recursive(base, draw)
现在我想改变它,这样我就可以生成除算术运算之外的布尔运算。我最初的想法是给trees添加一个参数:
def trees(tpe):
base = integers(min_value=1, max_value=10).map(lambda n: 'x' + str(n) + ': ' + tpe)
@composite
def extend(draw, children):
if tpe == 'bool':
op = draw(sampled_from(['&&', '||']))
return (op, draw(children), draw(children))
elif tpe == 'num':
op = draw(sampled_from(['+', '-', '*', '/']))
return (op, draw(children), draw(children))
return recursive(base, draw)
到目前为止还可以。但是我该如何混合它们呢?也就是说,我还想要比较运算符和三元运算符,这需要“使用不同的参数调用children”,可以这么说。
树需要很好的类型:如果操作是'||'或'&&',两个参数都需要是布尔值,'+'或'<'的参数需要是数字,等等。如果我只有两种类型,我可以只使用filter(给定type_of函数):
if op in ('&&', '||'):
bool_trees = children.filter(lambda x: type_of(x) == 'bool')
return (op, draw(bool_trees), draw(bool_trees))
但在实际情况下是不能接受的。
recursive 支持这个吗?还是有其他方法?显然,我可以直接递归地定义trees,但这会遇到the standard problems。
【问题讨论】: