[英]PyParsing simple language expressions
我正在嘗試編寫一些可以解析一些代碼的東西。 我能夠成功解析foo(spam)
和spam+eggs
,但foo(spam+eggs)
(遞歸下降?我的編譯器術語有點生疏)失敗了。
我有以下代碼:
from pyparsing_py3 import *
myVal = Word(alphas+nums+'_')
myFunction = myVal + '(' + delimitedList( myVal ) + ')'
myExpr = Forward()
mySubExpr = ( \
myVal \
| (Suppress('(') + Group(myExpr) + Suppress(')')) \
| myFunction \
)
myExpr << Group( mySubExpr + ZeroOrMore( oneOf('+ - / * =') + mySubExpr ) )
# SHOULD return: [blah, [foo, +, bar]]
# but actually returns: [blah]
print(myExpr.parseString('blah(foo+bar)'))
幾個問題:delimitedList正在尋找逗號分隔的myVal列表,即標識符,作為唯一可接受的參數列表形式,所以當然它不能匹配'foo + bar'(不是逗號分隔的myVal列表! ); 修復顯示另一個 - myVal和myFunction以相同的方式啟動,因此他們在mySubExpr中的順序很重要; 修復揭示了另一個 - 兩個級別的嵌套而不是一個。 這個版本似乎沒問題......:
myVal = Word(alphas+nums+'_')
myExpr = Forward()
mySubExpr = (
(Suppress('(') + Group(myExpr) + Suppress(')'))
| myVal + Suppress('(') + Group(delimitedList(myExpr)) + Suppress(')')
| myVal
)
myExpr << mySubExpr + ZeroOrMore( oneOf('+ - / * =') + mySubExpr )
print(myExpr.parseString('blah(foo+bar)'))
根據需要發出['blah', ['foo', '+', 'bar']]
。 我還刪除了冗余反斜杠,因為在括號內無論如何都會發生邏輯行延續; 它們無害但卻妨礙了可讀性。
我發現在向前使用'<<'運算符時要養成的好習慣是將RHS括在括號中。 那是:
myExpr << mySubExpr + ZeroOrMore( oneOf('+ - / * =') + mySubExpr )
更好的是:
myExpr << ( mySubExpr + ZeroOrMore( oneOf('+ - / * =') + mySubExpr ) )
這是我不幸選擇“<<”作為將表達式插入Forward的“插入”運算符的結果。 在這種特殊情況下,括號是不必要的,但在這一個中:
integer = Word(nums)
myExpr << mySubExpr + ZeroOrMore( oneOf('+ - / * =') + mySubExpr ) | integer
我們明白為什么我說“不幸”。 如果我將其簡化為“A << B | C”,我們很容易看到操作的優先級導致評估被執行為“(A << B)| C”,因為'<<'的優先級高於'| ”。 結果是,前向A只獲得插入其中的表達式B. “| C”部分確實執行了,但是會發生“A | C”,它會創建一個MatchFirst對象,然后立即將其丟棄,因為它沒有分配給任何變量名。 解決方案是將括號內的語句分組為“A <<(B | C)”。 在僅使用'+'操作組成的表達式中,沒有實際需要括號,因為'+'的優先級高於'<<'。 但這只是幸運的編碼,當有人后來使用'|'添加替代表達式時會導致問題 並沒有意識到優先含義。 所以我建議采用“A <<(表達式)”這一格式來避免這種混淆。
(總有一天我會編寫pyparsing 2.0 - 這將允許我破壞與現有代碼的兼容性 - 並將其更改為使用'<< ='運算符,它修復了所有這些優先級問題,因為'<< ='的優先級低於pyparsing使用的任何其他運算符。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.