段故障试图在类中使用boost::spirit::qi解析器
Segfault trying to use boost::spirit::qi parser in a class
我一直在使用boost::spirit编写一些解析器代码,并开始获得段错误。
我已经尽可能地简化了我的代码,以便于发布,见下文。
段错误发生在解析器回调addModule时回推int的过程中。
Valgrind声明vector v_modules没有初始化。在代码的早期,我可以看到它是初始化的,所以我假设一些内存垃圾正在发生。我曾多次尝试用这个较小的测试用例重写它,但都无济于事。任何帮助,感谢!
verilog.cpp:
#include "verilog.h"
#include <string>
#include <boost/spirit/include/qi.hpp>
Verilog::Verilog() {
m_parser.verilog = this;
}
Verilog::~Verilog(){}
void Verilog::parse(string contents) {
string::const_iterator iter = contents.begin();
string::const_iterator end = contents.end();
bool r = phrase_parse(iter,end,m_parser,boost::spirit::ascii::space);
}
void Verilog::addModule() {
int new_mod = 1;
v_modules.push_back(new_mod);
}
int main()
{
Verilog* verilog = new Verilog();
string contents = "hello";
verilog->parse(contents);
}
verilog.h
#ifndef VERILOG_H
#define VERILOG_H
#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>
using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
class Verilog
{
public:
Verilog();
~Verilog();
void parse(string contents);
void addModule() ;
template <typename Iterator>
struct verilog_parser : qi::grammar<Iterator, ascii::space_type>
{
verilog_parser() : verilog_parser::base_type(module)
{
module = qi::eps[boost::bind(&Verilog::addModule, verilog)];
}
qi::rule<Iterator, ascii::space_type> module;
Verilog* verilog;
};
private:
std::vector<int> v_modules;
verilog_parser<string::const_iterator> m_parser;
};
#endif
您使用的boost::bind
导致一个临时函数对象,该对象引用verilog
成员在语法构建期间指向的任何内容。
没用的。
您需要一个phoenix lazy actor,如果您希望它在您从Verilog
构造函数中设置它后拾取更改的值,那么您最好让它通过_reference引用this->verilog
。
老实说,代码看起来有点笨拙。为什么不使用Spirit的属性兼容性规则来自动构建向量(或列表、集合、映射……)等等)给你?
这里有一个修复:
#include <boost/spirit/include/phoenix.hpp>
namespace phx = boost::phoenix;
// ... later
module = qi::eps[phx::bind(&Verilog::addModule, phx::ref(verilog))];
注意,这仍然在
main
中留下泄漏的Verilog实例。为什么在现代c++中使用new
?
集成:
Live On Coliru
#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/bind.hpp>
using namespace std;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
class Verilog {
public:
Verilog();
~Verilog();
void parse(string contents);
void addModule();
template <typename Iterator> struct verilog_parser : qi::grammar<Iterator, ascii::space_type> {
verilog_parser() : verilog_parser::base_type(module) {
module = qi::eps[phx::bind(&Verilog::addModule, phx::ref(verilog))];
}
qi::rule<Iterator, ascii::space_type> module;
Verilog *verilog;
};
private:
std::vector<int> v_modules;
verilog_parser<string::const_iterator> m_parser;
};
#include <string>
#include <boost/spirit/include/qi.hpp>
Verilog::Verilog() { m_parser.verilog = this; }
Verilog::~Verilog() {}
void Verilog::parse(string contents) {
string::const_iterator iter = contents.begin();
string::const_iterator end = contents.end();
bool r = phrase_parse(iter, end, m_parser, boost::spirit::ascii::space);
}
void Verilog::addModule() {
int new_mod = 1;
v_modules.push_back(new_mod);
}
int main() {
Verilog verilog;
string contents = "hello";
verilog.parse(contents);
}
相关文章:
- Boost Spirit,获取迭代器内部语义动作
- boost::spirit::karma 替代生成器,带有 boost::variant 由字符串和字符串别名组成
- boost::spirit::x3 中的通用解析器生成器
- Boost.Spirit将表达转换为AST
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?
- 如何处理Boost Spirit X3导致Visual Studio 2019 "static initialization order fiasco"?
- Boost Spirit X3:将(一些)空格解析为枚举
- Boost Spirit x3 条件(三元)运算符解析器
- 你如何从 Boost Spirit X3 词法解析器中获取字符串?
- 将 Boost.Spirit.X3 解析器拆分为多个 TU
- boost::spirit::x3 中的简单字符串解析器不起作用
- boost::spirit指针属性是用nullptr初始化的吗?
- Boost.Spirit Alternative Parser parallelization
- 如何在 boost::spirit::qi 中将某些语义操作排除在 AST 之外
- 自定义预期失败的完整错误消息(boost::spirit::x3)
- boost::spirit--试图编译大多数简单代码的编译器错误
- Boost.Spirit.Qi 语法,用于 Boost.Fusion 自适应结构中的默认值
- 使用 Boost.Spirit 解析嵌套列表
- (如何)我可以在不安装完整的提升库的情况下使用 boost::spirit X3 吗?
- n-ary布尔语法从中缀到前缀的Boost::Spirit转换?