如何在python中编写带有运算符模块的小型DSL解析器

How to write small DSL parser with operator module in python

日期:见下面的矩阵

1
2
3
4
5
6
7
8
9
    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

我需要定义"规则"的功能,可以返回"true"或"false"是下面的字符串的每一asserts日期:

1
2
3
4
5
6
7
8
9
10
11
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 = c和b",例如:if I通排1到这个规则,因为我想让它返回false的规则是不正确的,在这一案件。

我的问题是:

  • 我怎么能到translater DSL解析器定义这些规则对workable lambda函数的字符串,然后用这个我可以调用的参数λ的日期返回的行的断言的结果吗?

  • 我发现有很多的模块操作的数学函数定义的规则可以复用到一,我可以创建一个"映射"是DSL解析器是使用这些关键字?它可能看起来像:

    关键词:= {("+"),operation.add"/",operation.div():"和":我的_和_定义()}

  • 2,如果上述过程是可能的,我怎么能"在listname美元和"λ的映射?

  • 谢谢你的帮助。

    RGS

    KC


    这样地。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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 ) )

    等。

    1
    2
    >>> r1.test( 89,  92,  18,  7,   90,  35, 60 )
    False

    编辑。

    • str(a)三月regex"【2-5】【0-2】"
    • MyFoO(a)>100
    • a在myfoo(b)

    这些都是普通的Python代码。我不知道为什么这个评论会被认为是有趣或困难的。

    1
    2
    3
    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的示例语法有多重要?最简单的方法是使用python表达式语法和eval()。否则,可能会从窗体转换为eval()所能转换的内容。