如何用python编写带有运算符模块的小型DSL解析器
见以下矩阵数据:如何用python编写带有运算符模块的小型DSL解析器,python,dsl,operation,Python,Dsl,Operation,见以下矩阵数据: A B C D E F G 1 89 92 18 7 90 35 60 2 62 60 90 91 38 30 50 3 59 91 98 81 67 88 70 4 20 28 31 9 91 6 18 5 80 27 66 1 33 91 18 6 82 30 47 8 39 22 32 7 14 11 70 39 18 1
A B C D E F G
1 89 92 18 7 90 35 60
2 62 60 90 91 38 30 50
3 59 91 98 81 67 88 70
4 20 28 31 9 91 6 18
5 80 27 66 1 33 91 18
6 82 30 47 8 39 22 32
7 14 11 70 39 18 10 56
8 98 95 84 47 28 62 99
我需要定义“rule”函数,它可以为每行数据的以下断言字符串返回“true”或“false”:
A=B and B=C
A>C
B>C
C>D and D<E or D>F
A+B<30
A+B<=30 # this may using "A+B<30 or A+B=30" as alternative
str(A) march regex"[2-5][0-2]"
myfoo(A) > 100
A in myfoo(B)
A not_in $listname
A in $listname
A=B和B=C
A> C
B> C
C> D和DF
A+BDSL的示例语法有多重要?最简单的方法是使用Python表达式语法和eval()。否则,可能会将表单转换为可评估的内容。如下所示
class Rule( object ):
def __init__( self, text ):
self.text= text
def test( self, A, B, C, D, E, F, G ):
return eval( self.text )
r1= Rule( "A==B" )
r2= Rule( "A==B and B==C" )
r3= Rule( "A in {listname!s}".format( listname=someList ) )
等等
编辑
- str(A)march regex“[2-5][0-2]”
- myfoo(A)>100
- A在myfoo中(B)
这些都是微不足道的Python代码。我不知道为什么评论会被认为是有趣或困难的
r4= Rule( "re.match( r'[2-5][0-2]', str(A) )" )
r5= Rule( "myfoo(A) > 100" )
r6= Rule( "A in myfoo(B)" )
这有个窍门。诀窍是编写Python代码;然后用引号将代码括起来任何Python代码都是合法的
如果这些规则的Python方面比较混乱,那么Python教程可能会有所帮助。谢谢您的回复,但我认为设计外部DSL是一个更好的主意,至少它会更具可扩展性。这是从我上一篇文章的答案中得到启发的,但坦率地说,到目前为止我还不知道如何做到这一点。我正在考虑使用eval(),问题是如何在一行中处理规则字符串?我的意思是,A B C D和$listname?如果规则不是精确的Python表达式,这将失败。OP的例子并非如此。@delnan:尽管如此,我怀疑OP的DSL是否已经被法律或其他标准所固定。我怀疑在指定的DSL中有一点机动空间。@s.Lott,感谢您的示例,它非常清晰简单。虽然我仍然对使用eval()代替DSL有疑问,但如何处理以下3个规则字符串:str(A)march regex“[2-5][0-2]”,myfoo(A)>100,A在myfoo(B)@delnan中,如果eval()可以解决我想要的所有请求,我认为它也是可以接受的,因为毕竟它是一个内部DSL,而设计外部DSL相当复杂,但我怀疑eval()可能不那么可扩展later@user478514:请更新问题,使其完整且符合所有要求。
r4= Rule( "re.match( r'[2-5][0-2]', str(A) )" )
r5= Rule( "myfoo(A) > 100" )
r6= Rule( "A in myfoo(B)" )