c++ - 消除左递归后的精神语义 Action

标签 c++ boost-spirit boost-spirit-qi

按照 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/

相关文章:

c++ - 计算字符串中的单词

c++ - Spirit X3,如何让属性类型匹配规则类型?

c++ - 使用 Boost.Spirit.Lex 和流迭代器

c++ - 在运行时动态组合 Boost.Spirit.Qi 规则(任意数量的备选方案)

c++ - boost spirit qi解析器发布失败,调试通过

c++ - QDateTime::fromstring( __DATE__, "MMM d yyyy") 返回无效

c++ - 在C++中实现多个接口(interface)

c++ - Boost.Spirit X3 中的错误处理和注释

c++ - 模板和重载运算符 <<

c++ - 为什么 boost::recursive_wrapper 在这种情况下不起作用