Я жестко программирую рекурсивный приличный парсер, в основном для целей обучения, и у меня возникли некоторые проблемы.
Я буду использовать этот короткий отрывок из грамматики CSS3 в качестве примера:
simple_selector = type_selector | universal;
type_selector = [ namespace_prefix ]? element_name;
namespace_prefix = [ IDENT | '*' ]? '|';
element_name = IDENT;
universal = [ namespace_prefix ]? '*';
Во-первых, я не осознавал, что namespace_prefix
является необязательной частью в обоих type_selector
и universal
.Это приводило к тому, что type_selector
всегда терпел неудачу при вводе с подачей, например *|*
, потому что он вслепую рассматривался для любого ввода, который соответствует производству namespace_prefix
.
Рекурсивное приличное достаточно просто, но я понимаю эточто мне нужно сделать много (из-за отсутствия лучшего слова) исследовательской рекурсии , прежде чем заняться производством.Поэтому я изменил подпись своих произведений, чтобы они возвращали логические значения.Таким образом, я мог бы легко определить, привел ли конкретный производственный процесс к успеху или нет.
Я использую структуру данных связанного списка для поддержки произвольного просмотра и могу легко нарезать этот список, чтобы попытаться произвести, а затем вернуться кмоя отправная точка, если производство не удается.Однако, пробуя производство, я передаю изменяемое состояние, пытаясь построить объектную модель документа.Это на самом деле не работает, потому что я не знаю, будет ли производство успешным или нет.И если производство не увенчалось успехом, мне нужно как-то отменить любые сделанные изменения.
У меня такой вопрос.Должен ли я использовать абстрактное синтаксическое дерево в качестве промежуточного представления, а затем перейти оттуда?Это то, что вы обычно делаете, чтобы обойти эту проблему?Поскольку проблема, по-видимому, в первую очередь связана с тем, что объектная модель документа не является подходящей древовидной структурой данных для рекурсии.