开发者

How to write small DSL parser with operator module in python

开发者 https://www.devze.com 2023-03-10 05:20 出处:网络
See below matrix data: ABCDEFG 18992187903560 262609091383050 359919881678870 4202831991618 58027661339118 68230478392232

See below matrix data:

    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

I need to define "rule" function can return "true" or "false" for below asserts string for each row data:

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

Take "A=B and B=C" for example: If I pass row 1 into this rule, I want the rule return false because it is not right in this case.

My questions are:

  1. How can I define a DSL parser to translater those "rules string" into a 开发者_如何转开发workable lambda function, then I can invoke this lambda with data row as parameter to return the assert result?

  2. I noticed the module operation has a lot of math functions I can reuse to define the rule, can I create a "mapper" for those keywords for DSL parser use? It may looks like:

    keywords = {"+": operation.add(), "/": operation.div(), "and": my_and_define() }

  3. if above 2 are possible, how can I process the "A in $listname" in the lambda and in the mapper?

Thanks for your help.

Rgs,

KC


Like this.

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 ) )

etc.

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

Edit.

  • str(A) march regex"[2-5][0-2]"
  • myfoo(A) > 100
  • A is in myfoo(B)

These are all trivial Python code. I'm not sure why the comment is even included as being interesting or difficult.

r4= Rule( "re.match( r'[2-5][0-2]', str(A) )" )
r5= Rule( "myfoo(A) > 100" )
r6= Rule( "A in myfoo(B)" )

There's a trick to this. The trick is to write the Python code; and then enclose the code in quotes. Any Python code is legal.

If the Python aspect of these rules is confusion, a Python tutorial may be helpful.


How important is the example syntax of your DSL? The simplest approach would be to use the Python expression syntax and eval(). Otherwise it might be possible to translate from your form to something eval()able.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号