Python 使用解析将**运算符更改为幂函数时出错?

Python 使用解析将**运算符更改为幂函数时出错?,python,pyparsing,Python,Pyparsing,我有以下pyparsing代码,用于使用解析将**运算符更改为幂函数。Paul McGuire在这个论坛上帮助我编写了以下代码 # define some basic operand expressions number = Regex(r'\d+(\.\d*)?([Ee][+-]?\d+)?') ident = Word(alphas+'_', alphanums+'_') #fn_call = ident + '(' + Optional(delimited_list(expr)) + ')

我有以下pyparsing代码,用于使用解析将**运算符更改为幂函数。Paul McGuire在这个论坛上帮助我编写了以下代码

# define some basic operand expressions
number = Regex(r'\d+(\.\d*)?([Ee][+-]?\d+)?')
ident = Word(alphas+'_', alphanums+'_')
#fn_call = ident + '(' + Optional(delimited_list(expr)) + ')'

# forward declare our overall expression, since a slice could 
# contain an arithmetic expression
expr = Forward()
#slice_ref = '[' + expr + ']'

slice_ref = '[' + expr + ZeroOrMore("," + expr) + ']'

# define our arithmetic operand
operand = number | Combine(ident + Optional(slice_ref))
#operand = number | fn_call | Combine(ident + Optional(slice_ref))
inequalities = oneOf("< > >= <= = == !=")

# parse actions to convert parsed items
def convert_to_pow(tokens):
    tmp = tokens[0][:]
    ret = tmp.pop(-1)
    tmp.pop(-1)
    while tmp:
        base = tmp.pop(-1)
        # hack to handle '**' precedence ahead of '-'
        if base.startswith('-'):
            ret = '-power(%s,%s)' % (base[1:], ret)
        else:
            ret = 'power(%s,%s)' % (base, ret)
        if tmp:
            tmp.pop(-1)
    return ret

def unary_as_is(tokens):
    return '(%s)' % ''.join(tokens[0])

def as_is(tokens):
    return '%s' % ''.join(tokens[0])


# simplest infixNotation - may need to add a few more operators, but start with this for now
arith_expr = infixNotation( operand,
    [
    ('-', 1, opAssoc.RIGHT, as_is),
    ('**', 2, opAssoc.LEFT, convert_to_pow),
    ('-', 1, opAssoc.RIGHT, unary_as_is),
    ((inequalities,inequalities), 3, opAssoc.LEFT, as_is),
    (inequalities, 2, opAssoc.LEFT, as_is),
    (oneOf("* /"), 2, opAssoc.LEFT, as_is),
    (oneOf("+ -"), 2, opAssoc.LEFT, as_is),
    (oneOf('and or'), 2, opAssoc.LEFT, as_is),
    ])
#('-', 1, opAssoc.RIGHT, as_is),
# now assign into forward-declared expr
expr <<= arith_expr.setParseAction(lambda t: '(%s)' % ''.join(t))

#Changing function of the formate f(n) to f[n]. It assist the pasring 

def transferToFunctionSyntax(expression):
    if "(" in expression and ")" in expression:
        p = regex.compile(r'\b[a-zA-Z_]\w*(\((?>[^()]|(?1))*\))')
        result=(p.sub(lambda m: m.group().replace("(", "[").replace(")", "]"), expression))
    else:
        result=expression
    return result

def translatepowerToFun(expression):
    expression=transferToFunctionSyntax(str(expression))
    xform = expr.transformString(expression)[1:-1]
    xform=xform.replace('[','(')
    expression=xform.replace(']',')')

有人能建议我如何避免这种情况吗?

您使用的是packrat解析模式吗?当您有一个深层
infixNotation
表达式时,启用packrat解析可以解决性能和内存问题。另外,您使用的是哪种版本的pyparsing?Packrat解析在2.0.4左右被完全重写,速度和内存都有所提高。我使用的是2.1.5版,是的,我启用了Packrat解析模式(ParseRelation.enablePackrat()),你能从一个更简单的表达式开始,然后慢慢添加到它,直到达到递归极限吗?有时,您可能只需要比默认值1000更多的递归堆栈。这个限制是为了避免失控的编码错误,但我很确定这段代码会终止。
translatepowerToFun('(((2.00000000000000)*(((xn8(_n1, __v2(_n1))+((-__v2(_n1)*xn8(_n1, __VERIFIER_nondet_double2(_n1))**3 + xn8(_n1, __v2(_n1)))/(2.00000000000000)))-xn8(_n1, __v2(_n1)))))>((1.00000000000000e-6)*(((xn8(_n1, __v2(_n1))+((-__VERIFIER_nondet_double2(_n1)*xn8(_n1, __v2(_n1))**3 + xn8(_n1, __VERIFIER_nondet_double2(_n1)))/(2.00000000000000)))+(xn8(_n1, __v2(_n1))+((-__v2(_n1)*xn8(_n1, __v2(_n1))**3 + xn8(_n1, __v2(_n1)))/(2.00000000000000)))))))')