0

私は PEG (Ruby の Citrus 実装) で bbcode パーサーを作成しています。[b]sometext[anothertext[/b]

コードあり

grammar BBCodeParser
  rule document
    (open_tag | close_tag | new_line | text)*
  end
  rule open_tag
    ("[" tag_name "="? tag_data? "]")
  end

  rule close_tag
    ("[/" tag_name "]") 
  end

  rule text
    [^\n\[\]]+
  end

  rule new_line
    ("\r\n" | "\n")
  end

  rule tag_name
    # [p|br|b|i|u|hr|code|quote|list|url|img|\*|color]
    [a-zA-Z\*]+
  end

  rule tag_data
    ([^\[\]\n])+
  end
end

問題はtext、テキストに \r、\n、open_tag、または close_tag 以外のすべてを含めることができるという、言い方がわからないルールにあります。この実装では、例では [ と ] が除外されているために失敗します (それは間違っています)。

最後の質問は、\r、\n、または open_tag または close_tag の完全一致以外のすべてに一致するルールを実行する方法です。

別の PEG 実装の解決策がある場合は、それも提供してください。私は切り替えることができます:)

4

3 に答える 3

0

少し前に同様の問題に遭遇しました。これを行うにはコツがあります:
match と言う必要がありopen_tag、その後に終了タグ以外のすべてを続け、次にclosing_tag. したがって、これにより次のルールが得られます

rule tag
  open_tag ((!open_tag | !close_tag | !new_line ) .)+ close_tag
end
于 2012-07-23T21:12:10.147 に答える
0

これ

rule text
    [^\n\[\]]+ (!open_tag text)?
end

解析エラーで終わる

私はこのアイデアを続けようとしましたが、結果は次の([^\n] (!open_tag | !close_tag) text*) とおりでした。しかし、それも失敗します。一致します"sometext[anothertext[/b]"

一時的なソリューションの検索 ((!open_tag | !close_tag | !new_line) .) 1 文字ずつ検索されますが、開始タグと終了タグはすべて無視されます。これらの文字は後で結合できます:)

于 2011-09-19T20:57:06.433 に答える
0

[これは、任意のテキストを解析し、別のタグの先頭ではない場合に再帰的に続行します。

rule text
    [^\n\[\]]+ (!open_tag text)?
end
于 2011-09-19T16:00:22.843 に答える