我试图解析C函数像树这样的表达式如下(使用Spirit Parser Framework):解析与升压灵语法
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 2013-11-20 15:47:53
@Cthutu MSVC允许在标识符中使用重音字符。这并不意味着它符合标准。 – 2013-11-20 23:02:10
更重要的是,您试图制作@Cthutu的重点是什么?标识符是否有短缺?你的编译器不正确地支持名字空间吗? – sehe 2013-11-20 23:03:50