2011-03-29 72 views
1

我已經寫了基於所示的代碼工作令牌解析器在spirit lex example 4令牌分析器的語義動作

我的一個規則是這樣的

set_name 
     = ( tok.set_ >> tok.name_ >> tok.identifier) 
      [ 
       std::cout << val("set name statement to: ") << _3 << "\n" 
      ] 
     ; 

這種運作良好。當

SET NAME xyz 

呈現其輸出如我所料

集名稱聲明:XYZ

現在我想要做一些有用的東西,發現存儲到一個類名。從parser semantic examples工作我寫這篇文章的代碼

class writer 
    { 
    public: 
     void print(string const& s) const 
     { 
      std::cout << s << std::endl; 
     } 
    }; 

    writer w; 

    ... 

    set_name 
     = ( tok.set_ >> tok.name_ >> tok.identifier) 
      [ 
       boost::bind(&writer::print, &w, ::_3) 
      ] 
     ; 

這並不編譯

 
1>C:\Program Files\boost\boost_1_44\boost/bind/bind.hpp(318) : error C2664: 'R boost::_mfi::cmf1::operator()(const U &,A1) const' : cannot convert parameter 2 from 'bool' to 'const std::basic_string ' 
1>  with 
1>  [ 
1>   R=void, 
1>   T=eCrew::rule::writer, 
1>   A1=const std::string &, 
1>   U=eCrew::rule::writer * 
1>  ] 
1>  and 
1>  [ 
1>   _Elem=char, 
1>   _Traits=std::char_traits, 
1>   _Ax=std::allocator 
1>  ] 
1>  Reason: cannot convert from 'bool' to 'const std::string' 
1>  No constructor could take the source type, or constructor overload resolution was ambiguous 

爲什麼編譯器抱怨一個試圖從布爾到字符串轉換?我看不到任何布爾。

+0

在...爲w被重新聲明爲bool?如果您爲作者使用更獨特的變量名稱會發生​​什麼? – 2011-03-29 21:03:16

+0

@jon將「w」改爲「the_writer」。同樣的結果。 – ravenspoint 2011-03-29 21:10:27

回答

3

佔位符在

std::cout << val("set name statement to: ") << _3 << "\n" 

boost::spirit::_3,這是一個boost.phoenix v2的佔位符。佔位符在

boost::bind(&writer::print, &w, ::_3) 

是一個boost.bind佔位符(自然地)。

這些佔位符做不是共享相同的行爲,甚至引用相同的數據。形式的鳳凰佔位符_ ň指解析器的第N子屬性,而綁定的佔位符有不同的含義:

  • _1指的是你的解析器的屬性作爲一個整體
  • _2指解析器的上下文
  • _3指bool&「重災區」參數

你的情況,最簡單的解決方案是使用boost::phoenix::bind,而不是boost::bind,這樣就可以繼續使用_3來引用分析器的第三個子屬性,而不必在writer::print內手動挑選它。

或者,只有當你希望連接的語義動作tok.identifier使boost.bind的::_1作品:

set_name 
    = tok.set_ 
    >> tok.name_ 
    >> tok.identifier[boost::bind(&writer::print, &w, ::_1)] 
; 
+0

這聽起來像個好主意。我會嘗試並回復你。 – ravenspoint 2011-03-29 21:18:59

+0

@ravenspoint:編輯顯示另一種選擇。 – ildjarn 2011-03-29 21:20:25