這裏是一個解析器,可能是類似你寫的一個:
import pyparsing as pp
LPAR, RPAR = map(pp.Suppress, "()")
OR = pp.Keyword("OR")
term = pp.pyparsing_common.identifier
or_expr = pp.Forward()
or_expr <<= pp.Group(OR + pp.Group(LPAR + pp.delimitedList(or_expr | term)) + RPAR)
當它分析你給的字符串,它提供了相同的嵌套輸出。
打造「EXPN」表達的名稱,你可以用一個解析動作收拾的表達,以及相關的表達ID,在全局列表VAR:
# add parse action to convert OR's to exprs
exprs = []
def generate_expr_definition(tokens):
expr_name = "exp{}".format(len(exprs)+1)
exprs.append((expr_name, tokens.asList()[0]))
return expr_name
or_expr.addParseAction(generate_expr_definition)
當你運行這個解析器中,創造的結果不是重要的部分。最重要的是一個建在解析exprs
列表:
or_expr.parseString(sample)
# generate assignments for each nested OR expr
for name, expr in exprs:
print("{} = {}".format(name, expr))
這給:
exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', ['exp1', 'in3']]
現在我看這一點,問:「我怎麼會知道這是'exp1'
之間的區別從輸入中解析出來,'exp1'
應該表示解析後的表達式,如果這被解釋爲Python賦值,那麼它應該看起來如下:
exp2 = ['OR', [exp1, 'in3']]
變量名稱周圍沒有引號。
要做到這一點,我們需要從分析動作中返回一個對象,該對象將以repr
作爲沒有周圍引號的名稱。就像這樣:
class ExprName:
def __init__(self, name):
self._name = name
def __repr__(self):
return self._name
變化解析動作return語句:
return ExprName(expr_name)
而產生的輸出現在看起來像:
exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', [exp1, 'in3']]
現在,您可以區分產生expN
瓦爾來自已解析的輸入。
哇,它就像一個魅力,不知道pyparsing是如此強大,我正在考慮遍歷解析樹來獲取表達式,而這實際上是我想要的第一個地方,這是得到有序從底部到根的表達 – dpalma
我還有一個問題,當我沒有嵌套表達時會發生什麼?因爲當我有一個簡單的表達式,如OR(in1,in2) – dpalma
時,我不想替換名稱這是否會發生?我不認爲我的測試能夠做到這一點(在我的回答中查看發佈的輸出)。 – PaulMcG