2012-03-15 3 views
8

boost::spirit::qiを使用して、組み込みパーサーで構成されるストリームを解析することに成功しました(byte_little_wordなど)。しかし、私は今これらのカテゴリの1つにうまく収まらないデータを解析する必要があります。例えば、私は16.16の固定小数点2進数を2倍に変換したいと思います。例えばそうlittle_word << little_16p16double(固定小数点数から解析)し、続いてuint16_tを解析することになります。boost :: spiritでバイナリを解析するときに属性タイプを変更する

私はまずセマンティックアクションを考えましたが、パーサーに関連付けられた属性のタイプを変更しないため、意味的なアクションは適切ではないと思いました。 boost::fusionによって提供される暗黙的なキャストに依存するため、employee struct-parsing exampleをこのような状況に適応させる方法もわかりません。このアプローチは、明らかに暗黙のキャストをuint32_tからdoubleに定義することができないため、ここでは機能しません。

私の傾斜は、私は、組み込みのバイナリ原始的なパーサーをラップするか、最初からターミナルパーサを書くために非端子を追加する必要があるということです。 qi_binary.hppの出所を見た後でさえ、私はどちらかを行う方法がわかりません。誰かがサンプルコードを提供したり、関連する参考文献に私を案内したりすることができますか?

答えて

7
template < typename Iterator > 
    struct parser : boost::spirit::qi::grammar < Iterator, double(), boost::spirit::ascii::space_type > 
    { 
     struct cast_impl 
     { 
      template < typename A > 
      struct result { typedef double type; }; 

      double operator()(boost::fusion::vector < boost::uint16_t, boost::uint16_t > arg) const 
      { 
       // cast here 
       return 0; 
      } 
     }; 

     parser() : parser::base_type(main) 
     { 
      pair = boost::spirit::qi::little_word >> '.' >> boost::spirit::qi::little_word; 
      main = pair[boost::spirit::qi::_val = cast(boost::spirit::qi::_1)]; 
     } 

     boost::spirit::qi::rule < Iterator, boost::fusion::vector < boost::uint16_t, boost::uint16_t >(), boost::spirit::ascii::space_type > pair; 
     boost::spirit::qi::rule < Iterator, double(), boost::spirit::ascii::space_type > main; 

     boost::phoenix::function<cast_impl> cast; 
    }; 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 
     typedef std::string container; 

     container data_ = "\x01\x02.\x01\x02"; 

     container::iterator iterator_ = data_.begin(); 

     double value_; 

     bool result_ = 
      boost::spirit::qi::phrase_parse(iterator_, data_.end(), 
      parser <container::iterator>(), 
      boost::spirit::ascii::space, 
      value_); 

     return 0; 
    } 
+0

ありがとう! 'ascii :: space_type'テンプレート・パラメータを削除し、適切な' operator() '関数を置き換えることで、サンプル・コードを私が望むものにすることができました。 –

関連する問題