3

parseActionwithを定義する機能は気に入っていますpyarsingが、特定のユースケースの障害に遭遇しました。入力文字列と次の簡単な文法を取ります。

from pyparsing import *

line = "[[one [two [three] two [three [four]]] one] zero]"
token = Word(alphas)

# Define the simple recursive grammar
grammar = Forward()
nestedBrackets = nestedExpr('[', ']', content=grammar) 
grammar << (token | nestedBrackets)

P = grammar.parseString(line)
print P

結果を次のようにしたいと思います。

[('one',1), [('two',2), [('three',3)], ('two',2), [('three',3), [('four',4)]]] one], ('zero',0)]

つまり、それぞれを解析tokenし、トークンと深さを持つタプルを返します。これは解析後に実行できることは知っていますが、を使用して実行できるかどうかを知りたいですparseAction。このように、グローバル変数を使った私の間違った試みは次のとおりです。

# Try to count the depth
counter = 0
def action_token(x):
    global counter
    counter += 1
    return (x[0],counter)
token.setParseAction(action_token)

def action_nest(x):
    global counter
    counter -= 1
    return x[0]
nestedBrackets.setParseAction(action_nest)

与える:

[('one', 1), ('two', 2), ('three', 3), ('two', 3), ('three', 4), ('four', 5), ('one', 3), ('zero', 3)]
4

1 に答える 1

4

これを行います(残りはそのままにしておきます):

def openB(s, l, t):
    global count
    count += 1
def closeB(s, l, t):
    global count
    count -= 1

opener = Literal("[").setParseAction(openB)
closer = Literal("]").setParseAction(closeB)

nestedBrackets = nestedExpr(opener, closer, content=grammar) 

問題は、ネストが一致したネストされたグループの数ではなく、一致した開き括弧の数と一致した閉じ括弧の数に依存することです。したがって、グループを解析するときではなく、開き/閉じ括弧を解析するときにカウントを調整する必要があります。したがって、グループ自体ではなく、グループ区切り文字に parseAction を設定する必要があります。

また、あなたの例では、ネストが 1 レベル (少なくとも私の目では) オフになっています。「ゼロ」は 1 レベルの括弧内にあるため、実際には 1 である必要があり、同様に、他のすべてのものも 1 つ上にシフトする必要があります。最も外側の「ゼロ」にレベル 0 などを本当に持たせたい場合は、初期化する必要があります。count-1に。

于 2012-07-06T02:30:44.097 に答える