按照 spirit-classic FAQ 中的示例消除左递归后,我无法找出 Phoenix 语义操作的正确占位符。我的非工作语法如下所示:
template <typename It, typename Skipper = qi::space_type>
struct parser : qi::grammar<It, expr(), Skipper>
{
parser() : parser::base_type(expression)
{
using namespace qi;
expression =
term [_val = _1]
>> *( (char_('+') >> term) [_val = phx::construct<binop<op_add>>(_1, _2)]
| (char_('-') >> term) [_val = phx::construct<binop<op_sub>>(_1, _2)]
) ;
term =
factor [_val = _1]
>> *( (char_('*') >> factor) [_val = phx::construct<binop<op_mul>>(_1, _2)]
| (char_('/') >> factor) [_val = phx::construct<binop<op_div>>(_1, _2)]
);
factor =
uint_ [_val = _1]
| var_ [_val = _1]
| ('(' >> expression >> ')') [_val = _1]
| (char_('-') > factor) [_val = phx::construct<unop<op_uminus>>(_1)]
| (char_('+') > factor) [_val = _1]
;
var_ = qi::lexeme[ +alpha ];
BOOST_SPIRIT_DEBUG_NODE(expression);
BOOST_SPIRIT_DEBUG_NODE(term);
BOOST_SPIRIT_DEBUG_NODE(factor);
BOOST_SPIRIT_DEBUG_NODE(var_);
}
private:
qi::rule<It, var() , Skipper> var_;
qi::rule<It, expr(), Skipper> expression, term, factor;
};
如能提供有关正确处理属性的任何帮助,我们将不胜感激。
谢谢。
最佳答案
我猜你真的不想
>> *( (char_('+') >> term) [_val = phx::construct<binop<op_add>>(_1, _2)]
| (char_('-') >> term) [_val = phx::construct<binop<op_sub>>(_1, _2)]
通过 '+'
作为第一个构造函数参数,因为类型 binop<op_add>
已经反射(reflect)了运营商的类型。因此,您可能希望将左侧操作数作为第一个参数。
这是您现在在这里解析的参数:
term [_val = _1]
这可能会提示您:您刚刚将其分配给... _val
!那么,这就是您的解决方案:
>> *( (char_('+') >> term) [_val = phx::construct<binop<op_add>>(_val, _2)]
| (char_('-') >> term) [_val = phx::construct<binop<op_sub>>(_val, _2)]
但是,由于来自 char_(...)
的暴露属性没有使用,可以更换:
>> *( (lit('+') >> term) [_val = phx::construct<binop<op_add>>(_val, _1)]
| (lit('-') >> term) [_val = phx::construct<binop<op_sub>>(_val, _1
)]
关于c++ - 消除左递归后的精神语义 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23257701/