gpt4 book ai didi

c++ - boost::spirit::qi 奇怪的属性打印出来

转载 作者:搜寻专家 更新时间:2023-10-31 01:33:28 27 4
gpt4 key购买 nike

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;

namespace test {
template< typename Rng,typename Expr >
bool parse(Rng const& rng,Expr const& expr) noexcept {
auto itBegin = boost::begin(rng);
auto itEnd = boost::end(rng);
try {
return qi::parse(itBegin,itEnd,expr);
} catch(qi::expectation_failure<decltype(itBegin)> const& exfail) {
exfail;
return false;
}
}
template< typename Rng,typename Expr,typename Attr >
bool parse(Rng const& rng,Expr const& expr,Attr& attr) noexcept {
auto itBegin = boost::begin(rng);
auto itEnd = boost::end(rng);
try {
return qi::parse(itBegin,itEnd,expr,attr);
} catch(qi::expectation_failure<decltype(itBegin)> const&) {
return false;
}
}
}

void print1(std::string const& s) {
std::cout<<"n1 = "<<s<<std::endl;
}

void print2(std::string const& s) {
std::cout<<"n2 = "<<s<<std::endl;
}

int main() {
qi::rule<std::string::const_iterator, std::string()> number = +qi::digit;
std::string input = "1+2";
std::string result;
if( test::parse(input, number[print1] >> *( qi::char_("+-") >> number[print2]) >> qi::eoi, result) ) {
std::cout<<"Match! result = "<<result<<std::endl;
} else {
std::cout<<"Not match!"<<std::endl;
}
return 0;
}

我期望这个程序的输出是,

n1 = 1
n2 = 2
Match! result = 1+2

但是n2的输出其实很奇怪,

n1 = 1
n2 = 1+2
Match! result = 1+2

为什么第二个数字的属性是“1+2”而不是“2”?

我知道还有其他一些方法可以解析这个表达式,例如使用 qi::int_。我只是想知道为什么我会从中得到这个奇怪的属性。谢谢!

最佳答案

回溯不会撤消对容器属性的更改。相邻的兼容解析器表达式绑定(bind)到相同的容器属性。

这两个属性都绑定(bind)到相同的容器属性 (result),这意味着您正在打印相同的变量两次。

如果您不想这样,请明确说明,例如

Live On Coliru

std::string result;
std::vector<std::string> v;
if( test::parse(input, number[px::bind(print1, qi::_1)] >> *qi::as_string[qi::char_("+-") >> number[print2]] >> qi::eoi, result, v) ) {
std::cout<<"Match! result = "<<result<<std::endl;
for (auto s : v)
std::cout << s << "\n";
} else {

打印

n1 = 1
n2 = +2
Match! result = 1
+2

现在我不知道你想要实现什么,但这可能很接近:

if (test::parse(input, qi::raw [number[print_("n1",_1)] > *(qi::char_("+-") >> number[print_("n2",_1)]) ] >> qi::eoi, result)) {

Live On Coliru

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

namespace test {
template< typename Rng,typename Expr,typename... Attr >
bool parse(Rng const& rng,Expr const& expr,Attr&... attr) noexcept {
auto itBegin = boost::begin(rng);
auto itEnd = boost::end(rng);
try {
return qi::parse(itBegin,itEnd,expr,attr...);
} catch(qi::expectation_failure<decltype(itBegin)> const&) {
return false;
}
}
}

void printn(std::string const& label, std::string const& s) {
std::cout << label << " = " << s << std::endl;
}

BOOST_PHOENIX_ADAPT_FUNCTION(void, print_, printn, 2)

int main() {
qi::rule<std::string::const_iterator, std::string()> number = +qi::digit;
std::string input = "1+2";
std::string result;
using qi::_1;

if (test::parse(input, qi::raw [number[print_("n1",_1)] > *(qi::char_("+-") >> number[print_("n2",_1)]) ] >> qi::eoi, result)) {
std::cout<<"Match! result = "<<result<<std::endl;
} else {
std::cout<<"Not match!"<<std::endl;
}
return 0;
}

打印

n1 = 1
n2 = 2
Match! result = 1+2

奖金

多一点关注点分离:

Live On Coliru

void printn(int n, std::string const& s) {
std::cout << "n" << n << " = " << s << std::endl;
}

BOOST_PHOENIX_ADAPT_FUNCTION(void, print_, printn, 2)

int main() {
qi::rule<std::string::const_iterator, std::string()> number;

int n = 1;
number %= qi::as_string[+qi::digit] [print_(px::ref(n)++, qi::_1)];

std::string input = "1+2";
std::string result;

if (test::parse(input, qi::raw [number > *(qi::char_("+-") >> number) ] >> qi::eoi, result)) {
std::cout << "Match! result = " << result << std::endl;
} else {
std::cout << "Not match!" << std::endl;
}
return 0;
}

关于c++ - boost::spirit::qi 奇怪的属性打印出来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41348152/

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