Допустим, мы хотим разобрать такой рекурсивный блок. Когда к блоку добавляется префикс «skip_comments_tag
», мы рекурсивно пропускаем все комментарии (/*...*/
) в этом блоке.
{
{}
{
skip_comments_tag{
{} /*comments*/
{ /*comments*/ }
}
}
}
Легко придумать рекурсивный синтаксический анализатор, как в Coliru.
namespace Parser {
auto const ruleComment = x3::lit("/*") >> *(x3::char_ - "*/") >> "*/" | x3::space;
x3::rule<struct SBlockId> const ruleBlock;
auto const ruleBlock_def = x3::lit('{') >> *(ruleBlock | "skip_comments_tag" >> x3::skip(ruleComment)[ruleBlock]) >> '}';
BOOST_SPIRIT_DEFINE(ruleBlock)
}
Но он не компилируется (при вызове функции parse
), поскольку генерирует бесконечный контекст (по x3::make_context
в x3::skip_directive
). x3::no_case
и x3::with
также имеют эту проблему, потому что все они используют x3::make_context
в реализации.
Вопросы:
- Всегда ли есть лучший способ написать парсеры для такого рода вопросов, чтобы избежать такой ошибки компиляции, и как?
- Или реализация
x3::make_context
считается ошибочной для таких вопросов?