1

クレオール マークアップを HTMLに変換する Pyparsing 文法を作成しています。これらの 2 つの構造を解析しようとすると、少し競合が発生するため、行き詰まりました。

画像リンク: {{image.jpg|title}}
フォーマットを無視: {{{text}}}

画像リンクを解析する方法は次のとおりです (これは完全に正常に変換されることに注意してください)。

def parse_image(s, l, t):
    try:
        link, title = t[0].split("|")
    except ValueError:
        raise ParseFatalException(s,l,"invalid image link reference: " + t[0])
    return '<img src="{0}" alt="{1}" />'.format(link, title)

image = QuotedString("{{", endQuoteChar="}}")
image.setParseAction(parse_image)

次に、{{{text}}} が検出されたときに、書式を設定せずに左中括弧と右中括弧の間を単純に返すようにルールを作成しました。

n = QuotedString("{{{", endQuoteChar="}}}")
n.setParseAction(lambda x: x[0])

ただし、次のテストケースを実行しようとすると:

text = italic | bold | hr | newline | image | n
print text.transformString("{{{ //ignore formatting// }}}")

次のスタック トレースを取得します。

Traceback (most recent call last):
File "C:\Users\User\py\kreyol\parser.py", line 36, in <module>
print text.transformString("{{{ //ignore formatting// }}}")
File "C:\Python27\lib\site-packages\pyparsing.py", line 1210, in transformString
raise exc
pyparsing.ParseFatalException: invalid image link reference: { //ignore formatting//  (at char 0), (line:1, col:1)

私が理解していることから、パーサーは最初に {{ に遭遇し、テキストを書式設定なしのテキストではなく画像として解析しようとします。このあいまいさをどのように解決できますか?

4

1 に答える 1

3

問題は次の式にあります。

text = italic | bold | hr | newline | image | n

Pyparse は厳密に左から右に動作し、先読みはありません。「|」の使用 演算子を使用すると、後で一致する方が優れている場合でも、すべての選択肢の最初の一致に一致する pyparsing MatchFirst 式を作成します。

代わりに「^」演算子を使用して、「最長一致」を使用するように評価を変更できます。

text = italic ^ bold ^ hr ^ newline ^ image ^ n

これにより、より適切な一致の可能性がない場合でも、すべての式がテストされるため、パフォーマンスが低下します。

より簡単な解決策は、選択肢のリストで式を並べ替えることです:n前のテストimage:

text = italic | bold | hr | newline | n | image

{{{代替を評価するとき、先頭の のn前に先頭{{のを探すようになりましたimage

これは、人々が数値用語を定義し、誤って次のようなものを定義したときによく発生します。

integer = Word(nums)
realnumber = Combine(Word(nums) + '.' + Word(nums))
number = integer | realnumber

この場合、先頭の整数部分が整数として解析されるため、 はnumbera と一致しません。realnumberあなたの場合のように、修正は「^」演算子を使用するか、単に並べ替えることです:

number = realnumber | integer
于 2015-04-15T03:33:29.550 に答える