2014-04-24 57 views
2

繼精靈 - 經典常見問題中的示例以消除左遞歸之後,我無法找出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; 
}; 

任何幫助正確的方式來處理屬性將不勝感激。

謝謝。

+0

爲了讓您的問題更容易找到你應該添加更多的標籤(如[tag:boost]和/或[tag:boost-spirit])。另外,如果您添加[tag:C++],您的代碼將具有語法高亮顯示。 – llonesmiz

回答

1

我想你實際上並不想

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

'+'作爲第一個構造函數的參數,因爲類型binop<op_add>已經反映了一種運營商。所以,您可能希望將左手操作數作爲第一個參數。

這是你現在在這裏分析的論點:

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 

+0

感謝您的幫助。答案非常有道理 - 使用phx使它看起來很難! – KentH