2013-07-06 55 views
2

ANTLR生成的java解析器能夠流式傳輸任意大的文件嗎?ANTLR4 Java解析器能夠處理非常大的文件,或者能夠傳輸文件

我嘗試用UnbufferedCharStream構造一個Lexer並將其傳遞給解析器。由於在UnbufferedCharStream上調用了大小,並且包含的​​異常解釋說您無法在UnbufferedCharStream上調用大小,所以我得到了UnsupportedOperationException。

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

你可以做這樣的:

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 ...)並根據需要進行檢索即可。這種方式創建分析樹(這是真正需要大量內存)可以避免。

+0

我有解析樹聽衆實施的解決方案。我不清楚上面的解決方案,我不生成一個解析樹,將調用監聽器。它似乎不會。 在語法中創建對象將非語法材料放入語法定義文件:(。 –

+0

@RossYoungblood您是對的,既沒有聽衆也沒有訪客。並且是的,它是非語法的東西(它被稱爲語法動作),它非常好。在antlr書中甚至有一個例子說明如何以這種方式構建計算器 – cantSleepNow

+0

我知道如何使用語法操作,我只是不想,我想用解析樹聽衆來解決大文件的問題。我正在調查的路徑。 –

相關問題