ANTLR4 java解析器可以处理非常大的文件,也可以流文件

时间:2013-07-06 06:19:21

标签: java streaming antlr4

ANTLR生成的java解析器是否能够传输任意大的文件?

我尝试使用UnbufferedCharStream构建一个Lexer并将其传递给解析器。我得到了UnsupportedOperationException,因为在UnbufferedCharStream上调用了大小,并且异常包含一个解释,你不能在UnbufferedCharStream上调用大小。

    new Lexer(new UnbufferedCharStream( new CharArrayReader("".toCharArray())));
    CommonTokenStream stream = new CommonTokenStream(lexer);
    Parser parser = new Parser(stream);

我基本上有一个我使用猪从hadoop导出的文件。它有大量的行以'\ n'分隔。每列用'\ t'分隔。这很容易在java中解析,因为我使用缓冲读取器来读取每一行。然后我用'\ t'分割得到每一列。但我也希望进行某种模式验证。第一列应该是格式正确的日期,后面是一些价格列,后面是一些十六进制列。

当我查看生成的解析器代码时,我可以这样称呼它

    parser.lines().line()

这会给我一个概念上我可以迭代的列表。但似乎列表在我得到它时会有一个固定的大小。这意味着解析器可能已经解析了整个文件。

API的其他部分是否允许您流式传输大型文件?就像在读取文件时使用Visitor或Listener来调用一些方法一样?但它无法将整个文件保留在内存中。它不合适。

1 个答案:

答案 0 :(得分:2)

你可以这样做:

InputStream is = new FileInputStream(inputFile);//input file is the path to your input file
ANTLRInputStream input = new ANTLRInputStream(is);
GeneratedLexer lex = new GeneratedLexer(input);
lex.setTokenFactory(new CommonTokenFactory(true));
TokenStream tokens = new UnbufferedTokenStream<CommonToken>(lex);
GeneratedParser parser = new GeneratedParser(tokens);
parser.setBuildParseTree(false);//!!
parser.top_level_rule();

如果文件很大,忘记了监听器或访问者 - 我将直接在语法中创建对象。只需将它们全部放在某个结构中(即HashMap,Vector ...)并根据需要进行检索。这样就可以避免创建解析树(这就是真正占用大量内存的东西)。