Как я могу остановить мою простую грамматику сложения, заканчивающуюся рано в Boost Spirit?

У меня возникают трудности при создании игрушечной грамматики для разбора сложения по желанию в Boost Spirit.

Вот моя грамматика и код:

Syntax.h:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

void test();

template <typename Iterator>
struct ExpressionGrammar : qi::grammar<Iterator, double(), ascii::space_type>
{
qi::rule<Iterator, double(), ascii::space_type> expression;
qi::rule<Iterator, double(), ascii::space_type> addsub;

ExpressionGrammar()
: ExpressionGrammar::base_type(expression)
{
using qi::lit;
using qi::_val;
using qi::_1;
using qi::_2;

addsub = (expression >> '+' >> expression)[_val = _1 + _2];
expression = (qi::double_ | addsub);
}
};

Syntax.cpp:

#include "Syntax.h"
namespace qi = boost::spirit::qi;

void test()
{
ExpressionGrammar<const char*> grammar;
std::string s = "3 + 5";
const char* c = s.c_str();
double result = -42;
bool r = qi::phrase_parse(c, c+strlen(c), grammar, ascii::space, result);
if (r)
std::cout << "Success. result: "<<result<<". Still to parse: "<<c<<std::endl;
else
std::cout << "Fail. parsing failed at: "<< c <<std::endl;
}

Выход:

Success. result: 3. Still to parse: + 5

Похоже, что double_ потребляет 3 и тогда нет правила, которое может разобрать просто + 5, Однако, если я изменю свое правило выражения на

expression = (addsub | qi::double_);

тогда моя программа входит в бесконечную рекурсию.

Какое решение для этого? Я знаю, что в примерах чаще используется звезда Клини, чтобы иметь дело с произвольным списком бинарных комбинаций (вдоль линий expression *('+' >> expression)). Является ли это необходимостью использования грамматики синтаксического анализа? Если это так, пожалуйста, объясните, почему.

1

Решение

Boost Spirit — это анализатор рекурсивного спуска, который не способен анализировать грамматики, содержащие левые рекурсии. Взгляни на эта статья в Википедии о том, как переписать леворекурсивные произведения. Возможные решения в духе включают использование выражений Kleene Star или оператора списка (%).

1

Другие решения


По вопросам рекламы [email protected]