我想創建一個解析器,它將某些數學轉換爲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