【问题标题】:Spirit semantic actions after eliminating Left Recursion消除左递归后的精神语义动作
【发布时间】:2014-04-24 00:32:09
【问题描述】:

按照精神经典常见问题解答中的示例消除左递归后,我无法找出 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;
};

任何有关处理属性的正确方法的帮助将不胜感激。

谢谢。

【问题讨论】:

  • 为了让您的问题更容易找到,您可能应该添加更多标签(如boost 和/或boost-spirit)。此外,如果您添加c++,您的代码将具有语法高亮。

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


【解决方案1】:

我想你实际上并不想

>> *( (char_('+') >> term)  [_val = phx::construct<binop<op_add>>(_1, _2)]
    | (char_('-') >> term)  [_val = phx::construct<binop<op_sub>>(_1, _2)]

传递'+' 作为第一个构造函数参数,因为binop&lt;op_add&gt; 类型已经反映了运算符的种类。因此,您可能希望将左侧操作数作为第一个参数。

这是您现在在此处解析的参数:

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

)]

【讨论】:

  • 感谢您的帮助。答案非常有道理——使用 phx 只是让它看起来很难!
猜你喜欢
  • 2017-02-18
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
相关资源
最近更新 更多