使用提升精神表达
Using boost spirit expression
我的boost spirit有问题expression.The原代码比较复杂,我做了一个小快照。
这段代码在调试模式下按预期工作,在发布时没有,解析 returns false,但应该 return true(我在 Visual Studio 2019 测试它)
int main() {
namespace qi = boost::spirit::qi;
auto X19 = qi::lit(" ") | qi::lit(" 0.000000000000D+00");
auto i4 = qi::uint_;
string str = "1234 1234";
auto f = str.cbegin();
auto l = str.cend();
bool ret = qi::parse(f, l, ( i4 >> X19 >> i4 ));
}
下一个快照适用于两种模式:
int main() {
namespace qi = boost::spirit::qi;
auto i4 = qi::uint_;
string str = "1234 1234";
auto f = str.cbegin();
auto l = str.cend();
bool ret = qi::parse(f, l, ( i4 >> (qi::lit(" ") | qi::lit(" 0.000000000000D+00")) >> i4 ));
cout << ret << endl;
return ret;
}
我做错了什么,这样划分长表达式?
谢谢
你运行 一头扎进了带有 Spirit 的 Proto 表达式的悬空临时陷阱。简短规则是:
Don't use auto
with Spirit expressions
您的程序展示了 Undefined Behaviour: see it Live On Compiler Explorer
解决方法涉及 BOOST_SPIRIT_AUTO
或 qi::copy
(在最近的提升版本之前仅作为 boost::proto::deep_copy
可用)。
固定
#include <boost/spirit/include/qi.hpp>
int main() {
namespace qi = boost::spirit::qi;
auto i4 = qi::copy(qi::uint_);
auto X19 = qi::copy( //
qi::lit(" ") //
| qi::lit(" 0.000000000000D+00")//
);
std::string str = "1234 1234";
auto f = str.cbegin(), l = str.cend();
bool ret = qi::parse(f, l, (i4 >> X19 >> i4));
std::cout << std::boolalpha << ret << "\n";
}
版画
true
奖金
请注意,Spirit X3 不再具有此 restriction/problem:Live On Coliru
#include <boost/spirit/home/x3.hpp>
int main() {
namespace x3 = boost::spirit::x3;
auto i4 = x3::uint_;
auto X19 = //
x3::lit(" ") //
| x3::lit(" 0.000000000000D+00") //
;
std::string str = "1234 1234";
auto f = str.cbegin(), l = str.cend();
bool ret = parse(f, l, (i4 >> X19 >> i4));
std::cout << std::boolalpha << ret << "\n";
}
你可能真的想要
qi::uint_parser<int, 10, 4, 4> i4;
// or
x3::uint_parser<int, 10, 4, 4> i4;
看起来很像是在解析类似 COBOL 的(固定宽度)记录,在这种情况下,我认为有更好的方法来组织语法以使其可靠。
我的boost spirit有问题expression.The原代码比较复杂,我做了一个小快照。 这段代码在调试模式下按预期工作,在发布时没有,解析 returns false,但应该 return true(我在 Visual Studio 2019 测试它)
int main() {
namespace qi = boost::spirit::qi;
auto X19 = qi::lit(" ") | qi::lit(" 0.000000000000D+00");
auto i4 = qi::uint_;
string str = "1234 1234";
auto f = str.cbegin();
auto l = str.cend();
bool ret = qi::parse(f, l, ( i4 >> X19 >> i4 ));
}
下一个快照适用于两种模式:
int main() {
namespace qi = boost::spirit::qi;
auto i4 = qi::uint_;
string str = "1234 1234";
auto f = str.cbegin();
auto l = str.cend();
bool ret = qi::parse(f, l, ( i4 >> (qi::lit(" ") | qi::lit(" 0.000000000000D+00")) >> i4 ));
cout << ret << endl;
return ret;
}
我做错了什么,这样划分长表达式? 谢谢
你运行 一头扎进了带有 Spirit 的 Proto 表达式的悬空临时陷阱。简短规则是:
Don't use
auto
with Spirit expressions
您的程序展示了 Undefined Behaviour: see it Live On Compiler Explorer
解决方法涉及 BOOST_SPIRIT_AUTO
或 qi::copy
(在最近的提升版本之前仅作为 boost::proto::deep_copy
可用)。
固定
#include <boost/spirit/include/qi.hpp>
int main() {
namespace qi = boost::spirit::qi;
auto i4 = qi::copy(qi::uint_);
auto X19 = qi::copy( //
qi::lit(" ") //
| qi::lit(" 0.000000000000D+00")//
);
std::string str = "1234 1234";
auto f = str.cbegin(), l = str.cend();
bool ret = qi::parse(f, l, (i4 >> X19 >> i4));
std::cout << std::boolalpha << ret << "\n";
}
版画
true
奖金
请注意,Spirit X3 不再具有此 restriction/problem:Live On Coliru
#include <boost/spirit/home/x3.hpp> int main() { namespace x3 = boost::spirit::x3; auto i4 = x3::uint_; auto X19 = // x3::lit(" ") // | x3::lit(" 0.000000000000D+00") // ; std::string str = "1234 1234"; auto f = str.cbegin(), l = str.cend(); bool ret = parse(f, l, (i4 >> X19 >> i4)); std::cout << std::boolalpha << ret << "\n"; }
你可能真的想要
qi::uint_parser<int, 10, 4, 4> i4; // or x3::uint_parser<int, 10, 4, 4> i4;
看起来很像是在解析类似 COBOL 的(固定宽度)记录,在这种情况下,我认为有更好的方法来组织语法以使其可靠。