/ / बूस्ट स्पिरिट पार्सर आगे पार्सिंग देखें - सी ++, पार्सिंग, सी ++ 11, बूस्ट, बूस्ट-स्पिरिट

बूस्ट स्पिरिट पार्सर आगे पार्सिंग देखें - सी ++, पार्सिंग, सी ++ 11, बढ़ावा, बूस्ट-स्पिरिट

मैं एक स्ट्रिंग को पार्स करना चाहता हूं जो फॉर्म का है: string_number मुझे यकीन नहीं है कि बूस्टर क्यूई पार्सर के लिए एक व्याकरण कैसे लिखा जाए।

अभी मेरा व्याकरण जैसा दिखता है: +qi::char_("a-zA-Z0-9_-") >> lit("_") >> क्यूई :: int_ </ Code>

लेकिन यह काम नहीं करता है। उदाहरण के तार हैं: ab_bcd_123 -> टोकन (ab_bcd, 123) ab_123 ---> टोकन (ab, 123)

उत्तर:

उत्तर № 1 के लिए 1

लेकिन यह काम नहीं करता है।

ऐसा इसलिए है क्योंकि 0-9 अंक खाता है। यह काम करना चाहिए:

+qi::char_("a-zA-Z_") >> "_" >> qi::uint_

यदि आप अनुमति देना चाहते हैं ab-3_bcd_123 भी, यह जानने के लिए कि आप अंत तक पहुँच चुके हैं, उदा। डिवाइस देखें। eoi:

qi::raw[
(+qi::alnum|"-") % (!("_" >> qi::uint_ >> eoi))
] >> "_" >> qi::uint_

हालांकि अब तक, मैं "बस इसके बारे में भूल जाता हूं और करता हूं:

qi::lexeme [ +qi::char_("a-zA-Z0-9_-") ] [ _val = split_ident(_1) ];

देख Coliru पर लाइव

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

namespace qi = boost::spirit::qi;

using NumberedIdent = std::pair<std::string, int>;

namespace Demo {
struct SplitIdent {
NumberedIdent operator()(std::vector<char> const& v, bool& pass) const {
std::string s(v.begin(), v.end());
try {
auto n = s.rfind("_");
pass = n > 0;
return { s.substr(0, n), std::stoi(s.substr(n+1)) };
} catch(...) {
pass = false; return {s, 0};
}
}
};

using It = std::string::const_iterator;
using namespace qi;

static boost::phoenix::function<SplitIdent> split_ident;

rule<It, NumberedIdent()> const rule
= lexeme [ +char_("a-zA-Z0-9_-") ] [ _val = split_ident(_1, _pass) ];
}

int main() {
for (std::string const input : {
"ab_bcd_123",
"ab-3_bcd_123 = "something"",
// failing:
"ab_bcd_123_q = "oops"",
"ab_bcd_123_ = "oops"",
"_123 = "oops"",
"_",
"q",
""
})
{
NumberedIdent parsed;
Demo::It f = input.begin(), l = input.end();

bool ok = parse(f, l, Demo::rule, parsed);

if (ok) {
std::cout << "SUCCESS: ["" << parsed.first << "", " << parsed.second << "]n";
} else {
std::cout << "parse failed ("" << input << "")n";
}

if (f != l) {
std::cout << "  remaining input "" << std::string(f,l) << ""n";
}
}

}

प्रिंटों:

SUCCESS: ["ab_bcd", 123]
SUCCESS: ["ab-3_bcd", 123]
remaining input " = "something""

और फिर सभी असफल परीक्षण मामलों (डिजाइन द्वारा):

parse failed ("ab_bcd_123_q = "oops"")
remaining input "ab_bcd_123_q = "oops""
parse failed ("ab_bcd_123_ = "oops"")
remaining input "ab_bcd_123_ = "oops""
parse failed ("_123 = "oops"")
remaining input "_123 = "oops""
parse failed ("_")
remaining input "_"
parse failed ("q")
remaining input "q"
parse failed ("")