मैं एक वाक्य को पार करना चाहता हूं जहां कुछ तारों को 'उद्धृत' या "उद्धृत" किया जा सकता है। नीचे दिया गया कोड लगभग काम करता है - लेकिन यह बंद उद्धरण मिलान करने में विफल रहता है। मुझे अनुमान है कि यह qq संदर्भ की वजह से है। कोड में एक संशोधन की टिप्पणी की जाती है, संशोधित "उद्धृत" या 'उद्धृत "में संशोधन का परिणाम भी विश्लेषण करता है और मूल समस्या को समापन उद्धरण के साथ दिखाने में मदद करता है। कोड सटीक व्याकरण का भी वर्णन करता है।पार्स को बढ़ावा देने के साथ स्ट्रिंग उद्धृत :: भावना
पूरी तरह स्पष्ट होने के लिए: अनगिनत स्ट्रिंग पार्स। 'hello'
जैसे उद्धृत स्ट्रिंग खुले उद्धरण '
को पार्स करेगा, सभी वर्ण hello
, लेकिन फिर अंतिम उद्धरण '
को पार्स करने में असफल हो जाएंगे।
मैंने boost tutorials में प्रारंभ/समाप्ति टैग मिलान के समान प्रयास किया, लेकिन सफलता के बिना।
template <typename Iterator>
struct test_parser : qi::grammar<Iterator, dectest::Test(), ascii::space_type>
{
test_parser()
:
test_parser::base_type(test, "test")
{
using qi::fail;
using qi::on_error;
using qi::lit;
using qi::lexeme;
using ascii::char_;
using qi::repeat;
using namespace qi::labels;
using boost::phoenix::construct;
using boost::phoenix::at_c;
using boost::phoenix::push_back;
using boost::phoenix::val;
using boost::phoenix::ref;
using qi::space;
char qq;
arrow = lit("->");
open_quote = (char_('\'') | char_('"')) [ref(qq) = _1]; // Remember what the opening quote was
close_quote = lit(val(qq)); // Close must match the open
// close_quote = (char_('\'') | char_('"')); // Enable this line to get code 'almost' working
quoted_string =
open_quote
>> +ascii::alnum
>> close_quote;
unquoted_string %= +ascii::alnum;
any_string %= (quoted_string | unquoted_string);
test =
unquoted_string [at_c<0>(_val) = _1]
> unquoted_string [at_c<1>(_val) = _1]
> repeat(1,3)[any_string] [at_c<2>(_val) = _1]
> arrow
> any_string [at_c<3>(_val) = _1]
;
// .. <snip>set rule names
on_error<fail>(/* <snip> */);
// debug rules
}
qi::rule<Iterator> arrow;
qi::rule<Iterator> open_quote;
qi::rule<Iterator> close_quote;
qi::rule<Iterator, std::string()> quoted_string;
qi::rule<Iterator, std::string()> unquoted_string;
qi::rule<Iterator, std::string()> any_string; // A quoted or unquoted string
qi::rule<Iterator, dectest::Test(), ascii::space_type> test;
};
// main()
// This example should fail at the very end
// (ie not parse "str3' because of the mismatched quote
// However, it fails to parse the closing quote of str1
typedef boost::tuple<string, string, vector<string>, string> DataT;
DataT data;
std::string str("addx001 add 'str1' \"str2\" -> \"str3'");
std::string::const_iterator iter = str.begin();
const std::string::const_iterator end = str.end();
bool r = phrase_parse(iter, end, grammar, boost::spirit::ascii::space, data);
बोनस ऋण के लिए: एक समाधान है कि एक स्थानीय डेटा सदस्य (उपरोक्त उदाहरण में char qq
जैसे) से बचने को प्राथमिकता दी जाएगी, लेकिन देखने का एक व्यावहारिक बिंदु से मैं कुछ भी है कि काम करता है उपयोग करेंगे!
रिकॉर्ड के लिए, 'बनाने चार' के एक सदस्य चर struct test_parser' बिल्कुल उसी तरह विफल रहता है qq'। – Zero
क्या "वैसे ही" में विफल रहता है? आपने हमें यह नहीं बताया है कि यह कैसे विफल रहता है (हालांकि मैं छवि कर सकता हूं यह 'qq' संदर्भ के कारण है)। –
@ निकोलबोलस यह कोड में एक टिप्पणी थी - मैंने तब से प्रश्न स्पष्ट किया है, इंगित करने के लिए धन्यवाद।मुझे रेफरी (क्यूक) पर भी संदेह है, लेकिन बूंद लैम्ब्डा और सह का नकारात्मक पक्ष यह है कि वे डीबग करने के लिए मुश्किल हैं क्योंकि आप पारंपरिक अर्थ में कदम नहीं उठा सकते हैं! – Zero