【发布时间】:2010-11-11 02:10:35
【问题描述】:
我不想重复 the Cthulhu answer,但我想使用 Treetop 匹配成对的开始和结束 HTML 标记。使用this grammar,我可以匹配开始标签和结束标签,但现在我想要一个规则将它们绑定在一起。我尝试了以下方法,但使用它会使我的解析器永远运行(无限循环):
rule html_tag_pair
html_open_tag (!html_close_tag (html_tag_pair / '' / text / newline /
whitespace))+ html_close_tag <HTMLTagPair>
end
我试图以递归括号示例和负前瞻示例on the Treetop Github page 为基础。我引用的其他规则如下:
rule newline
[\n\r] {
def content
:newline
end
}
end
rule tab
"\t" {
def content
:tab
end
}
end
rule whitespace
(newline / tab / [\s]) {
def content
:whitespace
end
}
end
rule text
[^<]+ {
def content
[:text, text_value]
end
}
end
rule html_open_tag
"<" html_tag_name attribute_list ">" <HTMLOpenTag>
end
rule html_empty_tag
"<" html_tag_name attribute_list whitespace* "/>" <HTMLEmptyTag>
end
rule html_close_tag
"</" html_tag_name ">" <HTMLCloseTag>
end
rule html_tag_name
[A-Za-z0-9]+ {
def content
text_value
end
}
end
rule attribute_list
attribute* {
def content
elements.inject({}){ |hash, e| hash.merge(e.content) }
end
}
end
rule attribute
whitespace+ html_tag_name "=" quoted_value {
def content
{elements[1].content => elements[3].content}
end
}
end
rule quoted_value
('"' [^"]* '"' / "'" [^']* "'") {
def content
elements[1].text_value
end
}
end
我知道我需要允许匹配单个开始或结束标记,但如果存在一对 HTML 标记,我希望将它们组合在一起。将它们与我的语法相匹配似乎最干净,但也许有更好的方法?
【问题讨论】:
-
<html_open_tag>和(!html_close_tag(etc之间应该有一个“+”吗?此外(我承认 Treetop 中的前瞻让我感到困惑)似乎负前瞻适用于不匹配的标签(如
,而正前瞻则适用于匹配标签。 -
嗯,好像不应该有+,因为整个规则是递归的,所以里面可能已经有多个打开的标签了,因为里面还有其他的标签对。
标签: ruby regex parsing grammar treetop