2013-02-21 13 views
5

मैं बढ़ावा भावना ढांचे का उपयोग कर अपने खुद के व्याकरण को परिभाषित करने के लिए कोशिश कर रहा हूँ के रूप में पूरे मैच हो और मैं इस तरह के एक मिलान नियम परिभाषित कर रहा हूँ:बूस्ट भावना एक स्ट्रिंग

value = (
     char_('"') >> 
     (*qi::lexeme[ 
       char_('\\') >> char_('\\') | 
       char_('\\') >> char_('"') | 
       graph - char_('"') | 
       char_(' ') 
     ])[some_func] >> 
     char_('"') 
); 

मैं एक कार्य assing करना चाहते हैं - some_func - इसके हिस्से में, और पैरामीटर के रूप में संपूर्ण मिलान स्ट्रिंग को पास करें। लेकिन दुर्भाग्य से मुझे कुछ vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...> मिल जाएगा। क्या मैं किसी भी तरह से char *, std :: string या आकार के साथ शून्य डेटा के रूप में पूरा डेटा प्राप्त कर सकता हूं? qi::as_string पर

+0

क्या वेक्टर साथ कुछ गड़बड़ है ? –

+0

मैं इसे एक वेक्टर >>> के रूप में वर्णित करता हूं लेकिन इसे sehe द्वारा संपादित किया गया था। – Dejwi

उत्तर

8

देखो: डेमो कार्यक्रम के

आउटपुट:

DEBUG: 'some\\"quoted\\"string.' 
parse success 

ईमानदारी से कहूं तो ऐसा लगता है कि तुम सच में संभव भागने वर्ण के साथ 'शब्दशः' तार पार्स करने के लिए कोशिश कर रहे हैं लग रहा है। सम्मान में, lexeme का उपयोग गलत लगता है (रिक्त स्थान खाया जाता है)। यदि आप बच निकले स्ट्रिंग पार्सिंग के नमूने देखना चाहते हैं, तो देखें।

एक साधारण पुनर्व्यवस्था कि मुझे लगता है कि कम से कम, बनाया जा सकता है (दोहराव से बचने के लिए) Boost Spirit Implement small one-line DSL on a server application ऐसा लगता है:

value = qi::lexeme [ 
      char_('"') >> 
      qi::as_string [ 
      *(
       string("\\\\") 
       | string("\\\"") 
       | (graph | ' ') - '"' 
      ) 
      ] [some_func(_1)] >> 
      char_('"') 
     ]; 

नोट तथापि कि आप बस एक कप्तान के बिना शासन की घोषणा और alltogether lexeme छोड़ सकता है: http://liveworkspace.org/code/1oEhei$0

संहिता (liveworkspace पर रहते हैं)

#include <boost/fusion/adapted.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

namespace qi = boost::spirit::qi; 
namespace phx = boost::phoenix; 

struct some_func_t 
{ 
    template <typename> struct result { typedef void type; }; 
    template <typename T> 
     void operator()(T const& s) const 
     { 
      std::cout << "DEBUG: '" << s << "'\n"; 
     } 
}; 

template <typename It, typename Skipper = qi::space_type> 
    struct parser : qi::grammar<It, Skipper> 
{ 
    parser() : parser::base_type(value) 
    { 
     using namespace qi; 
     // using phx::bind; using phx::ref; using phx::val; 

     value = (
       char_('"') >> 
        qi::as_string 
        [ 
         (*qi::lexeme[ 
          char_('\\') >> char_('\\') | 
          char_('\\') >> char_('"') | 
          graph - char_('"') | 
          char_(' ') 
          ]) 
        ] [some_func(_1)] >> 
       char_('"') 
      ); 
     BOOST_SPIRIT_DEBUG_NODE(value); 
    } 

    private: 
    qi::rule<It, Skipper> value; 
    phx::function<some_func_t> some_func; 
}; 

bool doParse(const std::string& input) 
{ 
    typedef std::string::const_iterator It; 
    auto f(begin(input)), l(end(input)); 

    parser<It, qi::space_type> p; 

    try 
    { 
     bool ok = qi::phrase_parse(f,l,p,qi::space); 
     if (ok) 
     { 
      std::cout << "parse success\n"; 
     } 
     else  std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; 

     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; 
     return ok; 
    } catch(const qi::expectation_failure<It>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cerr << e.what() << "'" << frag << "'\n"; 
    } 

    return false; 
} 

int main() 
{ 
    bool ok = doParse("\"some \\\"quoted\\\" string.\""); 
    return ok? 0 : 255; 
} 
+1

+1 मैं पहले 'as_string' के साथ जवाब देने जा रहा था, लेकिन मेरे जीवन के लिए इसे दस्तावेज़ों में नहीं ढूंढ सका -' पार्सर निर्देश ', दोह! – ildjarn

+0

'lexeme' के उपयोग में _needs_ को ठीक करने के लिए मुझे क्या लगता है कि एक ठोस चित्रण जोड़ा गया। – sehe

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