मैं एक स्ट्रिंग को पार्स करना चाहता हूं जो फॉर्म का है: 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 ("")