ANTLR4 java 解析器可以处理非常大的文件还是可以流式传输文件

dod*_*air 3 java streaming antlr4

ANTLR生成的java解析器能够流式传输任意大的文件吗?

我尝试使用 UnbufferedCharStream 构建 Lexer 并将其传递给解析器。由于调用 UnbufferedCharStream 上的 size,我收到了 UnsupportedOperationException,并且该异常包含一个解释,说明您无法在 UnbufferedCharStream 上调用 size。

    new Lexer(new UnbufferedCharStream( new CharArrayReader("".toCharArray())));
    CommonTokenStream stream = new CommonTokenStream(lexer);
    Parser parser = new Parser(stream);
Run Code Online (Sandbox Code Playgroud)

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

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

    parser.lines().line()
Run Code Online (Sandbox Code Playgroud)

这会给我一个列表,从概念上讲我可以对其进行迭代。但当我得到它时,列表似乎已经固定大小了。这意味着解析器可能已经解析了整个文件。

API 的另一部分是否允许您传输非常大的文件?就像使用访问者或侦听器在读取文件时被调用的某种方式一样?但它无法将整个文件保留在内存中。它不适合。

can*_*Now 5

你可以这样做:

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();
Run Code Online (Sandbox Code Playgroud)

如果文件很大,请忘记侦听器或访问者 - 我将直接在语法中创建对象。只需将它们全部放入某种结构中(即 HashMap、Vector...)并根据需要进行检索。通过这种方式,可以避免创建解析树(这确实需要大量内存)。