Boost.Spirit не анализирует весь ввод - PullRequest
2 голосов
/ 12 января 2012

У меня есть импульс :: дух :: правила ци:

auto dquote = qi::char_('\"');
auto comma = qi::char_(',');
auto newline = qi::char_('\n');
auto nonEscaped = *(qi::char_ - newline - comma - dquote);
auto escaped = *qi::blank >> dquote >> *((qi::char_ - dquote) | (dquote >> dquote)) >> dquote >> *qi::blank;
auto field = nonEscaped | escaped;

Когда я пытаюсь проанализировать ввод:

string input(" \"e\"\"e\" ");
qi::phrase_parse(begin(input), end(input), field, qi::char_('\r'));

Вход не полностью соответствует правилу escaped, но применяется только правило nonEscaped. Таким образом, только первый пробел соответствует. Как мне убедить дух разобрать весь ввод или разобрать как можно больше?

Когда я меняю порядок вариантов в правиле field на следующий, тогда он работает. Но правильное ли это решение?

auto field = escaped | nonEscaped;

1 Ответ

3 голосов
/ 13 января 2012

Да, изменение порядка является правильным решением.

Boost Spirit генерирует так называемый LL parsers, что означает

Он анализирует ввод слева направо и создает крайний левый вывод предложения(следовательно, LL, по сравнению с LR-парсером)

Проще говоря, он соответствует первому возможному токену и не выполняет возврат , если правило не выполнено.Вы могли бы "утверждать" пост-условие сортов в конце правила nonEscaped, см.

Использование семантических действий:

  • присваивание _pass в семантических действиях
  • использование объекта функции семантического действия, возвращая bool (false для сбоя)

Однако на практике это будетпривести к неоптимальным парсерам (например, ненужный возврат)

HTH

...