我想解析一个字符串,它的形式是: 字符串编号。 我不确定如何为 boost qi 解析器编写语法。
现在我的语法是这样的:
+qi::char_("a-zA-Z0-9_-") >> lit('<code>_</code>') >> qi::int_
但是看起来好像不行。 示例字符串是: ab_bcd_123 --> token (ab_bcd, 123) ab_123 ---> token (ab, 123)
最佳答案
But doesn't look like it works.
那是因为 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) ];
#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 ('')
关于c++ - boost spirit 解析器前瞻解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169514/