> lit('_') >>-6ren">
gpt4 book ai didi

c++ - boost spirit 解析器前瞻解析

转载 作者:行者123 更新时间:2023-11-30 05:12:59 25 4
gpt4 key购买 nike

我想解析一个字符串,它的形式是:字符串编号。我不确定如何为 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) ];

参见 Live On 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 ('')

关于c++ - boost spirit 解析器前瞻解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com