Я не хочу повторения Ктулху answer, но я хочу сопоставить пары открывающих и закрывающих тегов HTML с помощью Treetop. Используя эту грамматику, я могу сопоставлять открывающие и закрывающие теги , но теперь я хочу правило, чтобы связать их вместе. Я пробовал следующее, но использование этого заставляет мой парсер работать вечно (бесконечный цикл):
rule html_tag_pair
html_open_tag (!html_close_tag (html_tag_pair / '' / text / newline /
whitespace))+ html_close_tag <HTMLTagPair>
end
Я пытался взять за основу пример с рекурсивными круглыми скобками и пример отрицательного просмотра вперед на странице Treetop Github . Другие правила, на которые я ссылался, следующие:
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 смущает Кнута из меня), кажется, что отрицательный просмотр вперед будет для несопоставленных тегов (например, ‹br /›, и положительный просмотр для совпадающих тегов). - person philosodad   schedule 11.11.2010