Разрешены ли рекурсивные грамматики буст-спирта?

Я собираюсь написать синтаксический анализатор для языка, подобного математике, и обнаружил, что было бы неплохо иногда вызывать мою духовную грамматику для парсинга части выражения.

т.е. если я собираюсь разобрать

a+b*c+d

было бы удобно позвонить parse() в части ‘b * c’ при запросе знака ‘+’.

Можно ли это сделать при использовании так же экземпляр моей грамматики? (Параметр грамматики будет «* это»)

Хотя я еще не до конца убежден, является ли это наилучшим способом решения этой конкретной задачи, я нахожу вопрос довольно интересным, поскольку я не смог ничего найти в документации.

Очевидно, я не должен зависеть от локальных или глобальных переменных класса, если бы я использовал эту технику. Но я хотел бы знать, допускается ли это главным образом замыслом духа.

РЕДАКТИРОВАТЬ:

Мои примеры грамматики выглядят следующим образом:

class MyGrammar : public boost::spirit::qi::grammar<...>
{
/* a few rules. Some with local and/or inherited attributes */
MyGrammar( void )
{
/* assign all the rules, use a few 'on_error' statements */
// In one or two rules I would like to invoke parse(...,*this,...)
// on a subrange of the expression
}
}

Спасибо!

5

Решение

Конечно вы можете:

// In one or two rules I would like to invoke parse(...,*this,...)
// on a subrange of the expression

^ Это не то, как правила составлены в декларативной грамматике. Вы, кажется, думаете об этом в процедурных терминах (что может указывать на то, что вы могли иметь предыдущий опыт написания парсеров с рекурсивным спуском?).


На мой взгляд, простая грамматика выражения в духе может выглядеть так:

  literal     = +qi::int_;
variable    = lexeme [ qi::alpha >> *qi::alnum ];
term        =  literal
| variable
| (qi::lit('(') > expression >> ')');

factor      = term >> *(qi::char_("+-") >> term);
expression  = factor >> *(qi::char_("*/%") >> term);

Обратите внимание на рекурсию в последней ветви term: это парсеры выражений в скобках.

Этот упрощенный образец на самом деле не приведет к дереву разбора, которое отражает приоритет оператора. Но образцы и тесты в библиотеке Spirit содержат много примеры, которые делают.

Смотрите также другие мои ответы, которые показывают, как это работает более подробно (с полными образцами):

надеюсь, это поможет

7

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

Других решений пока нет …