2015-04-20 34 views
4

我正試圖按照以下說明創建自定義解析器:http://boost-spirit.com/home/articles/qi-example/creating-your-own-parser-component-for-spirit-qi/。在這篇文章中,解析器沒有參數,即我不能寫如qi::parse(first, input.end(), +qi::alpha >> custom_parser::iter_pos("my argument"));之類的東西。我怎樣才能修改這個例子來傳遞參數?我嘗試這樣做:傳遞參數以提升精靈自定義解析器

using namespace boost::spirit; 

namespace parsernm { BOOST_SPIRIT_TERMINAL(aparser); } 

namespace boost { namespace spirit { 
    template <typename A0> 
    struct use_terminal< 
     qi::domain 
     , terminal_ex< 
      parsernm::tag::aparser 
      , fusion::vector1<A0> 
      > 
     > : mpl::true_ 
    {}; 
}} 

namespace parsernm 
{ 
    struct aparser_impl : boost::spirit::qi::primitive_parser<aparser_impl> 
    { 
     aparser_impl(int _param) 
      : param(_param) 
     {} 

     template <typename Iterator, typename Context, typename Skipper, typename Attribute> 
     bool parse(Iterator& first, Iterator const& last, Context&, 
        Skipper const& skipper, Attribute& attr) const 
     { 
      return true; 
     } 

     template <typename Context> 
     boost::spirit::info what(Context&) const { 
      return boost::spirit::info("aparser"); 
     } 

     int param; 
    }; 
} 

namespace boost { namespace spirit { namespace qi { 
    template <typename Modifiers> 
    struct make_primitive<parsernm::tag::aparser, Modifiers> 
    { 
     typedef parsernm::aparser_impl result_type; 

     template <typename Terminal> 
     result_type operator()(Terminal const& term, unused_type) const 
     { 
      return result_type(fusion::at_c<0>(term.args)); 
     } 
    }; 
}}} 

int main(int argc, char* argv[]) 
{ 
    std::string input(""); 
    std::string::iterator first = input.begin(); 
    bool result = qi::parse(first, input.end(), parsernm::aparser(10)); 

    return 0; 
} 

結果是升壓\精神\家\氣\詳細\ parse.hpp(32):錯誤C2338:error_invalid_expression。

回答

4

我明白了。 BOOST_SPIRIT_TERMINAL必須更改爲BOOST_SPIRIT_TERMINAL_EXmake_primitive應如下所示:

namespace boost { namespace spirit { namespace qi { 
    template <typename Modifiers, typename A0> 
    struct make_primitive< 
     terminal_ex< 
      parsernm::tag::aparser 
      , fusion::vector1<A0> 
      > 
     , Modifiers 
     > 
    { 
     typedef parsernm::aparser_impl result_type; 

     template <typename Terminal> 
     result_type operator()(Terminal const& term, unused_type) const 
     { 
      return result_type(fusion::at_c<0>(term.args)); 
     } 
    }; 
}}} 
+2

感謝您將答案放在此處以便於參考。我確定這會對某人有幫助(我?)。 – sehe

+0

我現在實際上正在努力如何使它有可能與參數或沒有。你能提出一個想法嗎? – noxmetus

+0

更一般的說法:編譯器如何從error_invalid_expression中決定使用哪個use_terminal? – noxmetus