2011-03-18 17 views
8

मैं बढ़ावा के बारे में एक गहरी प्रशंसा के बीच में हूँ :: भावना और अनन्त निराशा इसे समझने की नहीं;)बूस्ट भावना भी लालची है

मुझे लगता है कि बहुत लालची हैं तार के साथ समस्या है और इसलिए यह मेल नहीं खाता । एक न्यूनतम उदाहरण के नीचे जो txt नियम के रूप में पार्स नहीं करता है अंत तक खाता है।

मैं जो करना चाहता हूं उसके बारे में अधिक जानकारी: लक्ष्य कुछ छद्म-एसक्यूएल को पार्स करना है और मैं सफेद जगहों को छोड़ना चाहता हूं।

select foo.id, bar.id from foo, baz 

मुझे एक विशेष कीवर्ड के रूप में from का इलाज करने की आवश्यकता है। नियम

"select" >> txt % ',' >> "from" >> txt % ',' 

की तरह कुछ है, लेकिन यह एक आइटम के रूप में देखता है bar.id from foo में यह स्पष्ट रूप से काम नहीं करता।

#include <boost/spirit/include/qi.hpp> 
#include <iostream> 
namespace qi = boost::spirit::qi; 
int main(int, char**) { 
    auto txt = +(qi::char_("a-zA-Z_")); 
    auto rule = qi::lit("Hello") >> txt % ',' >> "end"; 
    std::string str = "HelloFoo,Moo,Bazend"; 
    std::string::iterator begin = str.begin(); 
    if (qi::parse(begin, str.end(), rule)) 
     std::cout << "Match !" << std::endl; 
    else 
     std::cout << "No match :'(" << std::endl; 
} 

उत्तर

10

यहाँ मेरी संस्करण है, परिवर्तन चिह्नित के साथ:

#include <boost/spirit/include/qi.hpp> 
#include <iostream> 
namespace qi = boost::spirit::qi; 
int main(int, char**) { 
    auto txt = qi::lexeme[+(qi::char_("a-zA-Z_"))];  // CHANGE: avoid eating spaces 
    auto rule = qi::lit("Hello") >> txt % ',' >> "end"; 
    std::string str = "Hello Foo, Moo, Baz end";  // CHANGE: re-introduce spaces 
    std::string::iterator begin = str.begin(); 
    if (qi::phrase_parse(begin, str.end(), rule, qi::ascii::space)) {   // CHANGE: used phrase_parser with a skipper 
    std::cout << "Match !" << std::endl << "Remainder (should be empty): '"; // CHANGE: show if we parsed the whole string and not just a prefix 
    std::copy(begin, str.end(), std::ostream_iterator<char>(std::cout)); 
    std::cout << "'" << std::endl; 
    } 
    else { 
    std::cout << "No match :'(" << std::endl; 
    } 
} 

यह संकलित करता है तथा जीसीसी 4.4.3 के साथ चलाता है और 1.4something बूस्ट; उत्पादन:

Match ! 
Remainder (should be empty): '' 

lexeme का उपयोग करके आप सशर्त रिक्त स्थान खाने से बचने कर सकते हैं ताकि एक शब्द सीमा केवल अप करने के लिए txt मैचों। यह वांछित परिणाम उत्पन्न करता है: क्योंकि "Baz" को अल्पविराम के बाद नहीं किया जाता है, और txt रिक्त स्थान नहीं खाते हैं, हम गलती से "end" का उपभोग नहीं करते हैं।

वैसे भी, मैं 100% यकीन है कि यह आप के लिए क्या देख रहे है नहीं कर रहा हूँ - विशेष रूप से, str एक उदाहराणदर्शक उदाहरण के रूप में याद आ रही रिक्त स्थान है, या आप किसी भी तरह इस (अपार) स्वरूप का उपयोग करने के लिए मजबूर कर रहे हैं?

साइड नोट: यदि आप यह सुनिश्चित करना चाहते हैं कि आपने पूरी स्ट्रिंग को पार्स किया है, तो यह देखने के लिए चेक जोड़ें कि begin == str.end() है या नहीं। जैसा कि कहा गया है, आपका कोड एक मैच की रिपोर्ट करेगा भले ही str का केवल एक गैर-खाली उपसर्ग पार्स किया गया हो।

अद्यतन: जोड़ा प्रत्यय मुद्रण।

+0

धन्यवाद! यह लेक्सम वह चीज थी जो मैं याद कर रहा था। आप रिक्त स्थान जोड़ने के लिए पूरी तरह से सही थे (मैंने उन्हें कुछ कम करने की कोशिश में उदाहरण में छोड़ दिया, लेकिन मुझे लगता है कि यह किसी भी चीज़ से अधिक भ्रमित था) –

+0

भाग्यशाली अनुमान;) धन्यवाद। – phooji

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