Я пытаюсь разобрать C-функцию, как выражения дерева, как следующее (с помощью Spirit Parser Framework):Синтаксической грамматику с Boost Духом
F(A() , B(GREAT(SOME , NOT)) , C(YES))
Для этого я пытаюсь использовать три правил по следующему грамматика:
template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {
InputGrammar() : InputGrammar::base_type() {
tag = (qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9"))[ push_back(at_c<0>(qi::_val) , qi::_1) ];
command = tag [ at_c<0>(qi::_val) = at_c<0>(qi::_1) ] >> "(" >> (*instruction >> ",")
[ push_back(at_c<1>(qi::_val) , qi::_1) ] >> ")";
instruction = (command | tag) [qi::_val = qi::_1];
}
qi::rule< Iterator , ExpressionAST() , space_type > tag;
qi::rule< Iterator , ExpressionAST() , space_type > command;
qi::rule< Iterator , ExpressionAST() , space_type > instruction;
};
Обратите внимание, что мое правило тег просто пытается захватить идентификаторы, используемые в выражениях (в «функции» имен). Также обратите внимание, что подпись правила тега возвращает ExpressionAST
вместо std::string
, как в большинстве примеров. Причина, по которой я хочу сделать это, на самом деле довольно проста: я ненавижу использовать варианты, и, если это возможно, я избегаю их. Было бы здорово сохранить торт и съесть его, я думаю.
Команда должна начинаться с тега (имя текущего узла, поля первой строки узла AST) и переменное количество аргументов, заключенных в круглые скобки, и каждый из аргументов может быть самим тегом или другой командой ,
Однако этот пример не работает вообще. Он компилируется и все, но во время выполнения он не анализирует все мои тестовые строки. И то, что меня действительно раздражает, заключается в том, что я не могу понять, как это исправить, поскольку я не могу отлаживать вышеупомянутый код, по крайней мере, в традиционном значении этого слова. В принципе, единственный способ, которым я вижу, я могу исправить вышеупомянутый код, зная, что я делаю неправильно.
Итак, вопрос в том, что я не знаю, что не так с вышеуказанным кодом. Как бы вы определили вышеупомянутую грамматику?
Тип ExpressionAST
я использую:
struct MockExpressionNode {
std::string name;
std::vector<MockExpressionNode> operands;
typedef std::vector<MockExpressionNode>::iterator iterator;
typedef std::vector<MockExpressionNode>::const_iterator const_iterator;
iterator begin() { return operands.begin(); }
const_iterator begin() const { return operands.begin(); }
iterator end() { return operands.end(); }
const_iterator end() const { return operands.end(); }
bool is_leaf() const {
return (operands.begin() == operands.end());
}
};
BOOST_FUSION_ADAPT_STRUCT(
MockExpressionNode,
(std::string, name)
(std::vector<MockExpressionNode>, operands)
)
Что-то, что я обнаружил недавно, состоит в том, что идентификаторы C и C++ могут иметь символы «$» в своих именах. Так что a-z, A-Z, 0-9 (кроме первого символа), _ и $ действительны в C/C++-идентификаторе. – Cthutu
@Cthutu MSVC позволяет акцентировать символы в идентификаторах. Это не означает, что он соответствует стандарту. –
Что еще более важно, какой смысл вы пытаетесь сделать @Cthutu? Есть ли недостаток в идентификаторах? Ваш компилятор не поддерживает правильные пространства имен? – sehe