程序错误
<section>
<try>[Section]\nkey1 = val</try>
<key>
<try>Section]\nkey1 = valu</try>
<success>]\nkey1 = value1\nkey2</success>
<attributes>[]</attributes>
</key>
<fail/>
</section>
--------------------
Parsing failed
--------------------
代码#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
using namespace std;
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct ini_grammar : qi::grammar<Iterator, ascii::space_type>
{
ini_grammar() : ini_grammar::base_type(section)
{
using qi::char_;
key = +char_("a-zA-Z_0-9");
pair = key >> '=' >> key;
section =
'[' >> key >> ']'
>> '\n'
>> *(pair >> '\n')
;
BOOST_SPIRIT_DEBUG_NODES((key)(pair)(section))
}
qi::rule<Iterator, ascii::space_type> section, pair, key;
};
}
int main()
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::ascii::space;
string ini_section =
"[Section]\n"
"key1 = value1\n"
"key2 = value2\n";
typedef client::ini_grammar<string::const_iterator> ini_grammar;
ini_grammar grammar;
string::const_iterator iter = ini_section.begin();
string::const_iterator end = ini_section.end();
bool r = phrase_parse(iter, end, grammar, space);
if (r == true)
{
cout << "-------------------------\n";
cout << "Parsing succeeded\n";
cout << "-------------------------\n";
}
else
{
cout << "-------------------------\n";
cout << "Parsing failed\n";
cout << "-------------------------\n";
}
return 0;
}
对于某些上下文,我读了这个SO
接下来,
'\n'
永远无法匹配,因为你的船长已经吃掉了它。由于您希望这些规则中的空格无关紧要,而不是换行符,因此请使用
qi::blank
,而不是
qi::space
。另外,匹配
qi::eol
以获得更多可移植性(DOS/UNIX 行结束)。 对于最后的修饰,如果接受空白/空行,则接受多个行结束。当你这样做时,不要暴露船长的选择,因为这对你的语法至关重要。
我还选择使用
qi::space
/
qi::blank
与
qi::char_
保持一致。
// #define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <iostream>
namespace qi = boost::spirit::qi;
namespace client {
template <typename Iterator> struct ini_grammar : qi::grammar<Iterator> {
ini_grammar() : ini_grammar::base_type(start) {
key = +qi::char_("a-zA-Z_0-9");
pair = key >> '=' >> key;
section = '[' >> key >> ']' >> +qi::eol >> *(pair >> +qi::eol);
start = qi::skip(qi::blank)[section];
BOOST_SPIRIT_DEBUG_NODES((key)(pair)(section))
}
private:
qi::rule<Iterator> start;
qi::rule<Iterator, qi::blank_type> section, pair;
qi::rule<Iterator> key;
};
} // namespace client
int main() {
std::string const ini_section = R"([Section]
key1 = value1
key2 = value2
)";
using It = std::string::const_iterator;
client::ini_grammar<It> grammar;
It iter = ini_section.begin(), end = ini_section.end();
bool r = parse(iter, end, grammar);
if (r == true) {
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
} else {
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
打印
-------------------------
Parsing succeeded
-------------------------
参见