python 2.7中的pyparsing setParseAction方法抛出异常

时间:2012-10-23 07:53:41

标签: python parsing python-2.7 pyparsing

这是pyparsing和python 2.7的一般问题(在3中它可以正常工作)。一般结构如下:

class SomeParser(object):

    def some_action(self, string, loc, tok):
         print("action")

    def gramma(self):
          ...pyparsing gramma for some 

             language....
         some_rule = (token + token2).setParseAction(self.some_action)
         return some_rule

     def parse(self, string):
         self.gramma().parseString(string)
         return True

在python3中pyparsing工作正常,但在2.7中我得到了

Parsing error : some_action() takes exactly 4 arguments (1 given)

我的问题是如何让它在两个版本中都有效?

编辑:经过一些测试后,我发现这是一般问题,不仅仅是类方法。

1 个答案:

答案 0 :(得分:1)

我想我发现了一个问题(在朋友的帮助下),它位于pyparsing 1.5.6及其_trim_arity函数中,它试图猜测{{1}中func的参数个数1}}正在接受。我把它改成了:

setParseAction(func)

为:

if not _PY3K:                                                                                                                                                               
    def _trim_arity(func, maxargs=2):                                                                                                                                                 
        limit = [0]                                                                                                                                                                   
        def wrapper(*args):                                                                                                                                                           
            while 1:                                                                                                                                                                  
                try:                                                                                                                                                                  
                    return func(*args[limit[0]:])                                                                                                                                     
                except TypeError:                                                                                                                                                     
                    if limit[0] <= maxargs:                                                                                                                                           
                        limit[0] += 1                                                                                                                                                 
                        continue                                                                                                                                                      
                    raise                                                                                                                                                             
        return wrapper                                                                                                                                                                
    else:                                                                                                                                                                                 
        def _trim_arity(func, maxargs=2):                                                                                                                                                 
            limit = maxargs                                                                                                                                                             
            def wrapper(*args):                                                                                                                                                                                                                                                                                                             
                #~ nonlocal limit                                                                                                                                                         
                while 1:                                                                                                                                                                  
                    try:                                                                                                                                                                  
                        return func(*args[limit:])                                                                                                                                        
                    except TypeError:                                                                                                                                                     
                        if limit:                                                                                                                                                         
                            limit -= 1                                                                                                                                                    
                            continue                                                                                                                                                      
                        raise                                                                                                                                                             
            return wrapper   

不是很优雅,但我可以看到在if not _PY3K and False: def _trim_arity(func, maxargs=2): limit = [0] def wrapper(*args): while 1: try: return func(*args[limit[0]:]) except TypeError: if limit[0] <= maxargs: limit[0] += 1 continue raise return wrapper else: def _trim_arity(func, maxargs=2): # limit = maxargs def wrapper(*args): limit = maxargs #~ nonlocal limit while 1: try: return func(*args[limit:]) except TypeError: if limit: limit -= 1 continue raise return wrapper 版本的pyparsing上它已经修复了。