助推精神语法不一致的行为
inconsistent behavior of boost spirit grammar
我有一个小语法,我想在一个工作项目中使用。最小可执行示例如下:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic ignored "-Wunused-variable"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#pragma GCC diagnostic pop // pops
#include <iostream>
int main()
{
typedef unsigned long long ull;
std::string curline = "1;2;;3,4;5";
std::cout << "parsing: " << curline << "n";
namespace qi = boost::spirit::qi;
auto ids = -qi::ulong_long % ','; // '-' allows for empty vecs.
auto match_type_res = ids % ';' ;
std::vector<std::vector<ull> > r;
qi::parse(curline.begin(), curline.end(), match_type_res, r);
std::cout << "got: ";
for (auto v: r){
for (auto i : v)
std::cout << i << ",";
std::cout << ";";
}
std::cout <<"n";
}
在我个人的机器上,这会产生正确的输出:解析:1,2,3,4,5有:1,,2,,3,4,5,
但在工作中它产生:解析:1,2,3,4,5有:1,,2,,3,
换句话说,只要长整数向量中有多个元素,它就无法解析。
现在,我已经确定工作系统正在使用boost 1.56,而我的私人计算机正在使用1.57。这是原因吗?
知道我们这里有一些真正的精神专家在堆栈溢出,我希望有人可能知道这个问题是从哪里来的,或者至少可以缩小我需要检查的东西的数量。
如果是boost版本的问题,我可能会说服公司升级,但在任何情况下,一个解决方案将是受欢迎的。
你在代码中调用了未定义行为。
特别是在使用 UB意味着任何事情都可能发生。两个编译器都是正确的!最好的部分是,您可能会看到不同的行为取决于所使用的编译器标志。 可以使用: 使用 还请注意,Spirit X3承诺取消对使用auto的限制。由于使用了c++14的特性,它基本上更加轻量级。请记住它还不稳定 显示-O2的GCC显示未定义的结果;Live On Coliru 固定版本: Live On Coliru 打印(也使用GCC -O2!): ¹(这里基本上是"在下一个分号";但在标准中)auto
存储解析器表达式的地方。表达式模板包含对临时变量的引用,这些临时变量会在包含完整表达式的末尾悬垂。qi::copy
(或v1.55 IIRC之前的boost::proto::deep_copy
)BOOST_SPIRIT_AUTO
而不是BOOST_AUTO
(如果您也支持c++ 03,则非常有用)qi::rule<>
和qi::grammar<>
(非终结符)对表达式进行类型擦除。这对性能也有影响,但也提供了更多的特性,如递归规则
lexeme[]
(见这里)//#pragma GCC diagnostic push
//#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
//#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
//#pragma GCC diagnostic ignored "-Wunused-variable"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi.hpp>
//#pragma GCC diagnostic pop // pops
#include <iostream>
int main() {
typedef unsigned long long ull;
std::string const curline = "1;2;;3,4;5";
std::cout << "parsing: '" << curline << "'n";
namespace qi = boost::spirit::qi;
#if 0 // THIS IS UNDEFINED BEHAVIOUR:
auto ids = -qi::ulong_long % ','; // '-' allows for empty vecs.
auto grammar = ids % ';';
#else // THIS IS CORRECT:
auto ids = qi::copy(-qi::ulong_long % ','); // '-' allows for empty vecs.
auto grammar = qi::copy(ids % ';');
#endif
std::vector<std::vector<ull> > r;
qi::parse(curline.begin(), curline.end(), grammar, r);
std::cout << "got: ";
for (auto v: r){
for (auto i : v)
std::cout << i << ",";
std::cout << ";";
}
std::cout <<"n";
}
parsing: '1;2;;3,4;5'
got: 1,;2,;;3,4,;5,;
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- void 函数中的指针参数返回不一致的值
- 如何查找导致结果不一致的代码
- 跨平台 mySQL 与字符集不一致
- C++:不一致的 std::p ow( 类型 ) 定义
- 助推精神语法不一致的行为