首页 > 解决方案 > 在 ANTLR4 的 Lexer 中切换流

问题描述

我正在尝试在词法分析器中实现包含功能,以便当它点击'#include“filename”'时它将切换到该文件的流。我使用如下所示的词法分析器操作让它工作。当我运行它时,它会出现故障。

antlr4::ANTLRInputStream new_source(new_file); // new file is an open ifstream

int pos = _input->index();

filestack.push(std::make_pair(_input,pos)); //my stack to keep track of previous files
reset();
_input= static_cast<antlr4::CharStream*>(&new_source);

我检查了 static_cast<> 是否有效并返回一个非空指针,并且分配成功。但是,当它在进入重新编译的 ANLTR 运行时后继续运行时会出现段错误。有什么我想念的吗?

更新:我刚刚重新编译了带有调试标志的 c++ 运行时,现在我看到它在返回 _prevAccept.dfaState->prediction 时在 LexerATNSimulator::failOrAccept 处失败。

此外,这是在段错误之前发生的情况:

It exits out of the custom lexer action and the LexerActionExecutor.
It enters LexerATNSimulator::accept.
exits LexerATNSimulator::accept.
Enters LexerATNSimulator::failOrAccept
Segfault

我在切换时正在重置词法分析器,这可能与失败有关吗?

标签: c++antlr4c++17

解决方案


只是替换输入流的值不会削减它。到处都有可能导致崩溃的参考资料。相反,您必须重置词法分析器 + 令牌源。它是这样的:

lexer.reset();
lexer.setInputStream(&input); // Not just reset(), which only rewinds the current position.
tokens.setTokenSource(&lexer);

请参阅Github 上的 MySQL Workbench 代码以获取完整的完整代码。

关于令牌来源:词法分析器是令牌来源,您所能做的就是调用.reset(). 在C++ 运行时源中查找此函数的详细信息。


推荐阅读