Parsing 可以用ANTLR解析大文件吗?
是否可以指示ANTLR不要将整个文件加载到内存中?它能否一个接一个地应用规则,并在读取文件的同时按顺序生成最顶层的节点列表?也可能会以某种方式删除分析的节点?在Antlr.org的某个地方有一个维基页面,可以回答您的问题;刚才似乎找不到 实际上,lexer使用标准的InputStream接口读取数据,特别是antlInputStream.java。典型的实现是抢占式地将整个输入数据文件读入内存。您需要做的是编写自己的缓冲版本-“ANTLRBufferedFileStream.java”-根据需要从源文件读取。或者,只需将标准BufferedInputStream/FileInputStream设置为AntlInputStream的数据源 需要注意的一点是,Antlr4具有无限前瞻性的潜力。在正常操作中,大小合理的缓冲区不太可能出现问题。更可能是在解析器尝试错误恢复时。Antlr4允许定制错误恢复策略,因此问题是可控的 其他细节: 实际上,Antlr实现了一个pull解析器。当您调用第一个解析器规则时,解析器从lexer请求令牌,lexer从输入流请求字符数据。解析器/lexer接口名义上由缓冲令牌流实现 解析树只不过是令牌的树数据结构。嗯,还有很多,但不是在数据大小方面。每个令牌都是一个INT值,通常由与令牌定义匹配的输入数据流片段支持。lexer本身不需要将lex的输入字符流的完整副本保存在内存中。而且,令牌文本片段可能被归零。lexer的关键内存需求是给定缓冲文件输入流的输入字符流前瞻扫描 根据您的需要,即使给定一个100GB以上的输入文件,内存中的解析树也可以很小 为了进一步提供帮助,您需要更多地解释您在Antlr中尝试做什么,以及什么定义了您的最低关键内存需求。这将指导可以推荐哪些附加策略。例如,如果源数据是可修改的,则可以使用多个lexer/解析器运行,每次在lexer中选择源数据的不同部分进行处理。与文件读取和数据库写入相比,即使使用快速磁盘,Antlr执行也可能不太明显。是的,您可以使用:Parsing 可以用ANTLR解析大文件吗?,parsing,antlr,grammar,antlr4,Parsing,Antlr,Grammar,Antlr4,是否可以指示ANTLR不要将整个文件加载到内存中?它能否一个接一个地应用规则,并在读取文件的同时按顺序生成最顶层的节点列表?也可能会以某种方式删除分析的节点?在Antlr.org的某个地方有一个维基页面,可以回答您的问题;刚才似乎找不到 实际上,lexer使用标准的InputStream接口读取数据,特别是antlInputStream.java。典型的实现是抢占式地将整个输入数据文件读入内存。您需要做的是编写自己的缓冲版本-“ANTLRBufferedFileStream.java”-根据需要
- 用于字符流(传递给lexer)
- 用于令牌流(传递给解析器)
- 此令牌流实现在令牌通道上没有区别,因此请确保使用
而不是->skip
作为lexer规则中不应发送到解析器的命令->channel(HIDDEN)
- 此令牌流实现在令牌通道上没有区别,因此请确保使用
- 确保调用解析器,否则将为整个文件创建一个巨大的解析树
- 我投入了大量的工作来确保
和无缓冲Harstream
以最“理智”的方式运行,特别是在无缓冲TokenStream
、标记
、释放
和搜索
方法方面。我的目标是在不影响流释放未使用内存的能力的情况下,尽可能多地保留这些方法的功能获取文本
- ANTLR 4允许真正的无限制前瞻。如果您的语法需要对EOF进行前瞻以做出决定,那么您将无法避免将整个输入加载到内存中。在写语法时,你必须非常小心避免这种情况