parsy解析器的参数

2024-06-16 11:35:06 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑下面的代码,它解析和评估Python中的字符串,如^ {< CD1>}。

import parsy as pr                                                                        
from parsy import generate                                                                
                                                                                          
def lex(p):                                                                               
    return p << pr.regex('\s*')                                                           
                                                                                          
numberP = lex(pr.regex('[0-9]+').map(int))                                                
                                                                                          
@generate                                                                                 
def sumP():                                                                               
    a = yield numberP                                                                     
    yield lex(pr.string('+'))                                                             
    b = yield numberP                                                                     
    return a+b                                                                            
                                                                                          
exp = sumP.parse('567 + 323')                                                             
print(exp)

@generate对我来说完全是个谜。有人知道更多关于这个把戏是如何运作的吗?它确实允许我们以类似于Haskell的一元do符号的风格书写。是否需要代码反射来生成自己的@generate,或者是否有一种聪明的方法来逐字解释代码

现在我的主要问题来了,我想把sumP推广到opP,它也需要一个运算符符号和一个组合函数:

import parsy as pr                                                                        
from parsy import generate                                                                
                                                                                          
def lex(p):                                                                               
    return p << pr.regex('\s*')                                                           
                                                                                          
numberP = lex(pr.regex('[0-9]+').map(int))                                                
                                                                                          
@generate                                                                                 
def opP(symbol, f):                                                                       
    a = yield numberP                                                                     
    yield lex(pr.string(symbol))                                                          
    b = yield numberP                                                                     
    return f(a,b)                                                                            
                                                                                          
exp = opP('+', lambda x,y:x+y).parse('567 + 323')                                         
print(exp)

这是一个错误。似乎生成的opP已经有两个参数,我不知道如何处理


Tags: 代码fromimportreturndefasprgenerate
1条回答
网友
1楼 · 发布于 2024-06-16 11:35:06

修饰符在Python中的工作方式是,它们是以修饰符方法作为参数调用的函数,然后将其返回值指定给方法名。换言之:

@foo
def bar():
    bla

相当于:

def bar():
    bla
bar = foo(bar)

这里foo可以用bar做任何它想做的事情。它可能会用某种东西来包装它,它可能会反思它的代码,它可能会调用它

@generate所做的是将给定函数包装到解析器对象中。解析时,parser对象将调用不带参数的函数,这就是为什么在将@generate应用于带参数的函数时会出现缺少参数的错误

要创建参数化规则,可以将@generate应用于内部0参数函数并返回:

def opP(symbol, f):
    @generate
    def op():
        a = yield numberP                                                                  
        yield lex(pr.string(symbol))
        b = yield numberP
        return f(a,b)

    return op

相关问题 更多 >