Я собираюсь написать синтаксический анализатор для языка, подобного математике, и обнаружил, что было бы неплохо иногда вызывать мою духовную грамматику для парсинга части выражения.
т.е. если я собираюсь разобрать
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
}
}
Спасибо!
Конечно вы можете:
// 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 содержат много примеры, которые делают.
Смотрите также другие мои ответы, которые показывают, как это работает более подробно (с полными образцами):
Boost :: анализатор выражений духа
Полноценный пример со ссылками на образцы документации и объяснениями улучшений исходного кода от автора
Ошибка компиляции с boost :: spirit parser еще один подход
надеюсь, это поможет
Других решений пока нет …