我想创建一个解析器,它将某些数学转换为C.这归结为必须找到表单的嵌套表达式...^x,并用pow替换(..., x)(这里x是一个数字)。解析器失败 - pyparsing
一些假设:
- ^只会出现在地方表明幂
- 的“X”将永远是一个实数为代表用C
- 之前的指数^,在.. 。将是某种变量,数字或者括号中的分组表达式。变量将是一个带有(可能)下划线的字母数字字符串。
我可以澄清更多的假设,如果我错过了什么(只是问)。
我的代码如下所示,以及一个失败的例子。为什么这是失败的?
代码:
from pyparsing include *
def parse(s):
identifier = Regex(r'-?[a-zA-Z0-9_]+')
real = Regex(r'-?[0-9]+(\.?[0-9]+)?(e-?[0-9]+)?')
oper = Regex(r'[\*\+/-]-?')
#oper = oneOf("* + - /")
# define arithOperand as a Forward, since it could contain nested power expression
arithOperand = Forward()
arithExpr = arithOperand + ZeroOrMore(oper + arithOperand)
groupedArithExpr = '(' + arithExpr + ')'
# define expression for x^y, where x could be any kind of arithmetic term
powerOp = Literal('^')
powerExpr = (groupedArithExpr|real|identifier) + powerOp + real #order matters?
powerExpr.setParseAction(lambda tokens: 'pow(%s,%s)' % (tokens[0], tokens[2]))
# now define the possible expressions for arithOperand, including a powerExpr
arithOperand <<= powerExpr | real | identifier | groupedArithExpr
# convert parsed list of strings to a single string
groupedArithExpr.setParseAction(''.join)
return arithExpr.transformString(s)
这是造成失败的字符串:
s = ((s9*(s4*s6+c4*c6*s5)-c5*c6*c9)*(-(c4*s6-c6*s4*s5)*(x1*(1.0/2.0)+BASE_ORIGIN_Z*(s4*s6+c4*c6*s5)+(c4*s6-c6*s4*s5)*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0))+BASE_ORIGIN_X*c5*c6)+(c4*c6+s4*s5*s6)*(x2*(1.0/2.0)-BASE_ORIGIN_Z*(c6*s4-c4*s5*s6)-(c4*c6+s4*s5*s6)*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0))+BASE_ORIGIN_X*c5*s6)+c5*s4*(x3*(1.0/2.0)-BASE_ORIGIN_X*s5+BASE_ORIGIN_Z*c4*c5-c5*s4*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0))))+(c4*s6-c6*s4*s5)*((c9*s5+c4*c5*s9)*(x3*(1.0/2.0)-BASE_ORIGIN_X*s5+BASE_ORIGIN_Z*c4*c5-c5*s4*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0)))+(s9*(s4*s6+c4*c6*s5)-c5*c6*c9)*(x1*(1.0/2.0)+BASE_ORIGIN_Z*(s4*s6+c4*c6*s5)+(c4*s6-c6*s4*s5)*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0))+BASE_ORIGIN_X*c5*c6)-(s9*(c6*s4-c4*s5*s6)+c5*c9*s6)*(x2*(1.0/2.0)-BASE_ORIGIN_Z*(c6*s4-c4*s5*s6)-(c4*c6+s4*s5*s6)*(-BASE_ORIGIN_Y+BASE_LINK_EXTENTS_Y*(1.0/2.0)+LEG_LINK_EXTENTS_Y*(1.0/2.0))+BASE_ORIGIN_X*c5*s6)))^2
这里的指数不转换为一个POW和整个输入表达式保持完好,没有变化。我的解析器出了什么问题?
你是对的,你发布这个就像我去发布,我得到它的工作。谢谢!唯一的问题是,这使得事情变得难以忍受 - 要花20个小时来分析我的20MB文件,每个2MB元素一个小时。我想知道如果你知道有什么方法可以加速packrat的速度,那就是使用大量的内存? – user650261
如果在实际和标识符中删除可选的前导' - ',并将操作符还原为“oneOf(”+ - * /“)”,那么事情会更好吗? – PaulMcG
我只是去检查一下,但看到你做了一些编辑 - 哪些建议应该在你看来测试? – user650261