Antlr4 在堆上分配 ParseTree
Antlr4 allocate ParseTree on heap
我有一个类似这样的函数来从文件中获取 AST。
antlr4::tree::ParseTree *get_ast(std::string &filename) {
std::ifstream stream;
stream.open(filename);
antlr4::ANTLRInputStream input(stream);
Lexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
Parser parser(&tokens);
antlr4::tree::ParseTree *tree = parser.program();
return tree;
}
但是当使用return值时,似乎指向的树已经被清除(在堆栈上),我需要知道如何在堆上分配树,所以我可以使用 return 值(并手动释放)。
编辑:基于@sepp2k 评论,我尝试通过堆分配保持解析器活动。
Parser *get_parser(std::string filename) {
std::ifstream stream;
stream.open(filename);
antlr4::ANTLRInputStream input(stream);
Lexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
return new Parser(&tokens);
}
但是,当我从解析器
调用规则时,这现在在 Parser.cpp 生成的文件中出现分段错误
您不仅要让解析器保持活动状态,还要让令牌流保持活动状态,因为解析树使用令牌引用。
我建议创建一个包装器 class 来保存所有与解析器相关的对象并使其保持活动状态。这样所有的引用都保持有效。您始终可以重新使用该对象进行新的解析运行。
For MySQL Workbench I created a parser context 为应用程序提供所有解析功能。将其用作您的实施模板。
我有一个类似这样的函数来从文件中获取 AST。
antlr4::tree::ParseTree *get_ast(std::string &filename) {
std::ifstream stream;
stream.open(filename);
antlr4::ANTLRInputStream input(stream);
Lexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
Parser parser(&tokens);
antlr4::tree::ParseTree *tree = parser.program();
return tree;
}
但是当使用return值时,似乎指向的树已经被清除(在堆栈上),我需要知道如何在堆上分配树,所以我可以使用 return 值(并手动释放)。
编辑:基于@sepp2k 评论,我尝试通过堆分配保持解析器活动。
Parser *get_parser(std::string filename) {
std::ifstream stream;
stream.open(filename);
antlr4::ANTLRInputStream input(stream);
Lexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
return new Parser(&tokens);
}
但是,当我从解析器
调用规则时,这现在在 Parser.cpp 生成的文件中出现分段错误您不仅要让解析器保持活动状态,还要让令牌流保持活动状态,因为解析树使用令牌引用。
我建议创建一个包装器 class 来保存所有与解析器相关的对象并使其保持活动状态。这样所有的引用都保持有效。您始终可以重新使用该对象进行新的解析运行。
For MySQL Workbench I created a parser context 为应用程序提供所有解析功能。将其用作您的实施模板。