用PEG问题制作BBcode解析器

时间:2011-09-19 15:43:21

标签: ruby parsing bbcode treetop peg

我正在使用PEG制作bbcode解析器(用于Ruby的Citrus实现),我仍然坚持解析这个[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实施的解决方案,也可以在那里给它。我可以切换:))

3 个答案:

答案 0 :(得分:0)

这将解析任何文本,并在[不是另一个标记的开头时递归递归。

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

答案 1 :(得分:0)

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

以Parse Error

结束

我尝试继续这个想法,结果是([^\n] (!open_tag | !close_tag) text*) 但它也会失败。它将匹配"sometext[anothertext[/b]"

查找临时解决方案 ((!open_tag | !close_tag | !new_line) .) 它只能找到一个字母,但忽略所有打开和关闭标签。这些信件我可以在以后联合起来:)

答案 2 :(得分:0)

我刚才遇到过类似的问题。有一个技巧可以做到这一点:
您需要说匹配open_tag,然后是不是结束标记的所有内容,然后是closing_tag。所以这给出了以下规则

rule tag
  open_tag ((!open_tag | !close_tag | !new_line ) .)+ close_tag
end