2012-03-15 13 views
8

के साथ बाइनरी पार्स करते समय विशेषता प्रकार बदलें I अंतर्निहित पार्सर्स (उदा। byte_, little_word, आदि) वाली स्ट्रीम को पार्स करने के लिए सफलतापूर्वक boost::spirit::qi का उपयोग कर रहा है। हालांकि, अब मुझे डेटा को पार्स करने की आवश्यकता है जो इन श्रेणियों में से किसी एक में अच्छी तरह से नहीं आती है। उदाहरण के लिए, मैं 16.16 फिक्स्ड-पॉइंट बाइनरी नंबर को डबल में बदलना चाहता हूं; जैसे इसलिए little_word << little_16p16uint16_t को double (एक निश्चित-बिंदु संख्या से पारदर्शी) के बाद पार्स करेगा।बूस्ट :: भावना

मैंने पहली बार अर्थपूर्ण कार्रवाइयों पर विचार किया, लेकिन (मुझे लगता है ...) कि वे उचित नहीं हैं क्योंकि वे एक पार्सर से जुड़े गुण के प्रकार को नहीं बदलते हैं। मैं इस स्थिति में employee struct-parsing example को अनुकूलित करने का तरीका भी नहीं समझ सकता क्योंकि यह boost::fusion द्वारा प्रदान किए गए निहित कास्ट पर निर्भर करता है। वह दृष्टिकोण यहां काम नहीं करेगा क्योंकि मैं स्पष्ट रूप से 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' टेम्पलेट पैरामीटर को हटाकर और उपयुक्त' ऑपरेटर() 'फ़ंक्शन को प्रतिस्थापित करके वही करना चाहता था जो मैं चाहता था। –

संबंधित मुद्दे