是否有可能解析大文件,ANTLR?(Is it possible to parse big file

2019-09-02 05:17发布

是否有可能指示ANTLR不是整个文件加载到内存? 它可以将规则应用于一招一式生成顺序节点的最上面的列表,阅读文件一起? 也可能是有可能以某种方式降分析节点?

Answer 1:

是的,你可以使用:

  • UnbufferedCharStream您的字符流(传递给词法分析器)
  • UnbufferedTokenStream为您的令牌流(传递给解析器)
    • 此令牌流实现不区分令牌渠道,所以一定要使用->skip代替->channel(HIDDEN)在你的词法规则的命令不应被发送到解析器。
  • 请确保调用setBuildParseTree(false)在您的解析器或一个巨大的解析树将整个文件被创建。

有一些额外的评论编辑:

  • 我把相当多的工作纳入确保UnbufferedCharStreamUnbufferedTokenStream最“理智”的方式可能进行操作,特别是在涉及到markreleaseseekgetText方法。 我的目标是尽可能多地保留的那些方法尽可能的功能而不影响流的释放未使用的内存的能力。
  • ANTLR 4允许无限真实先行。 如果你的语法需要先行到EOF作出决定,那么你就无法避免整个输入加载到内存中。 你必须非常谨慎,写你的语法时要避免出现这种情况。


Answer 2:

有地方埋Antlr.org这充分说明你的问题一个Wiki页面; 似乎无法找到刚才。

实质上,词法分析器读取使用标准的InputStream接口,具体ANTLRInputStream.java数据。 典型的实现是ANTLRFileStream.java是先发制人读取整个输入数据文件到内存中。 你需要做的是写自己的缓存版本 - “ANTLRBufferedFileStream.java” - 即根据需要从源文件中读取。 或者,只是设定一个标准的BufferedInputStream /的FileInputStream作为数据源到AntlrInputStream。

一个需要注意的是,Antlr4有做一个无界的预测先行的潜力。 不太可能在正常操作的合理大小的缓冲区的问题。 当解析器尝试错误恢复的可能性较大。 Antlr4允许误差恢复策略的定制,所以这个问题是可控的。

其他详细信息:

事实上,ANTLR的实现上拉解析器。 当你调用第一个解析器规则,解析器请求从词法分析器,它从输入流请求字符数据令牌。 解析器/词法接口由一个缓冲令牌流实现,名义上BufferedTokenStream 。

解析树比令牌树数据结构更小。 好了,多了很多,但不是在数据大小方面。 每个令牌是由匹配的令牌定义输入数据流的片段典型地支持一个int值。 词法分析器本身不需要lex'd输入字符流的完整副本被保存在内存中。 而且,令牌文本片段可以zero'd出来。 对于词法分析器临界存储器要求是输入字符流先行扫描,给定缓存文件输入流。

根据您的需求,在内存中的解析树可以很小,甚至赋予了100GB +输入文件。

为了进一步帮助,你需要更多地解释什么是你正在尝试了在ANTLR中可以做,什么决定最低临界内存要求。 这将引导其更多的策略可以推荐。 例如,如果源数据是适合,则可以使用多个词法/语法分析器运行,每次在源数据进行处理的词法不同部分subselecting。 相较于文件读取和写入数据库,即使有快速的磁盘,ANTLR的执行将可能几乎感觉不到。



文章来源: Is it possible to parse big file with ANTLR?