2012-03-15 44 views
8

Tôi đã sử dụng thành công boost::spirit::qi để phân tích luồng bao gồm các trình phân tích cú pháp tích hợp (ví dụ: byte_, little_word, v.v.). Tuy nhiên, bây giờ tôi cần phải phân tích cú pháp dữ liệu không gọn gàng vào một trong các danh mục này. Ví dụ, tôi muốn chuyển đổi một số nhị phân 16.16 điểm cố định thành một đôi; ví dụ. do đó, little_word << little_16p16 sẽ phân tích cú pháp một số uint16_t theo sau là double (phân tích cú pháp từ số điểm cố định).Thay đổi loại thuộc tính khi phân tích cú pháp nhị phân bằng tăng :: tinh thần

Lần đầu tiên tôi xem là hành động ngữ nghĩa, nhưng (tôi nghĩ ...) rằng chúng không phù hợp vì chúng không thay đổi loại thuộc tính được kết hợp với trình phân tích cú pháp. Tôi cũng không thể tìm ra cách thích ứng với tình huống này vì nó dựa trên các phôi ngầm được cung cấp bởi boost::fusion. Cách tiếp cận đó sẽ không hoạt động ở đây vì tôi rõ ràng không thể xác định một diễn viên tiềm ẩn từ uint32_t đến double mà không gây ra các vấn đề lớn.

Độ nghiêng của tôi là tôi cần thêm không phải thiết bị đầu cuối để bọc các trình phân tích cú pháp nguyên thủy nhị phân tích hợp hoặc viết trình phân tích cú pháp đầu cuối từ đầu. Ngay cả sau khi nhìn vào nguồn của qi_binary.hpp, tôi không chắc chắn làm thế nào để làm một trong hai. Bất cứ ai có thể cung cấp một số mã mẫu và/hoặc hướng dẫn tôi đến các tài liệu tham khảo có liên quan để bắt đầu?

Trả lời

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

Cảm ơn! Tôi đã có thể lấy mã mẫu của bạn để làm chính xác những gì tôi muốn bằng cách loại bỏ tham số mẫu 'ascii :: space_type' và thay thế hàm' operator() 'thích hợp. –

Các vấn đề liên quan