3

次の最小限の作業例を考えます。

from pyparsing import *
latex_h  = QuotedString("$")('latex')
reg_text = Word(alphas)('text')
grammar  = OneOrMore( latex_h | reg_text )('line')

sol = grammar.parseString('''dog $x^2$ cat''')
print sol.dump()

出力は次のようになると予想していました。

['dog', 'x^2', 'cat']
- line: ['dog', 'x^2', 'cat']
  - text: dog
  - latex: x^2
  - text: cat

しかし、代わりに私は得ました:

['dog', 'x^2', 'cat']
- latex: x^2
- line: ['dog', 'x^2', 'cat']
  - latex: x^2
  - text: cat
- text: cat

dog解析ツリーでget が取り残された理由がわかりません。さらに、 の 2 つの要素が のtext, latex 外側にあるのはなぜlineですか?

4

1 に答える 1

3

Russell Borogoveが言うように、同じ解析レベルにある場合、名前付きの結果は一意である必要があります。同じタイプの2つ以上の名前付き要素(たとえば、2つの「テキスト」または2つの「ラテックス」)を含む「行」を作成することはできません。これらは両方とも、基になるディクショナリで同じキーを使用するためです。listAllMatches最新のPyParsingのソリューションについては、Paul McGuireが書いたとおりに見て、すべてを延期します:)

「latex_h」または「reg_text」に解析アクションをアタッチすることでこれを回避することもできますが、「latex_h」要素に兄弟の「reg_text」要素の知識が必要な場合、これは役に立ちません。その場合、おそらく文法をもう少し分割するか、ツリーベースのアプローチを使用して解析する必要があります(最下位の要素からルートまで、解析アクションによって、および/または結果のリストを反復処理することによって) 、辞書ベースのアプローチではなく。

解析ツリーが「犬」を残さなかったことに注意することが重要です。正しく解析されました。解析された結果が辞書に割り当てられなかっただけです。次のように、解析された値にアクセスできます。sol.line[0]

「latex」と「cat」が「line」の外に表示される理由については、OneOrMore定義をGroup()内に配置する必要があります。

reg_textこれは、要素が解析されるときに(のような親要素が解析されるときではなく)要素に解析アクションを適用する例grammarです。それはあなたが抱えている「名前付き結果」の問題を解決しませんが、パーサーで何を達成しようとしているのかについての文脈がなければ、解決策を提案することはできません。

from pyparsing import *
latex_h  = QuotedString("$")('latex')
reg_text = Word(alphas)('text')
grammar  = Group(OneOrMore( latex_h | reg_text ))('line')

def parse_reg_text(s, loc, toks):
    if toks.text == 'dog':
        return "atomic " + toks.text
    else:
        return "ninja " + toks.text

reg_text.setParseAction(parse_reg_text)

sol = grammar.parseString('''dog $x^2$ cat $y^3$''')
print sol.dump()

これにより、次の出力が得られます。

[['atomic dog', 'x^2', 'ninja cat', 'y^3']]
- line: ['atomic dog', 'x^2', 'ninja cat', 'y^3']
  - latex: y^3
  - text: ninja cat
于 2012-11-06T03:03:42.540 に答える