2016-04-13 10 views
1

Ich benutze eine Antlr für einen einfachen CSV-Parser. Ich mag es auf einer 29gig-Datei verwenden, aber es läuft aus dem Speicher auf dem ANTLRInputStream Aufruf:Gibt es Beispiele für Referenzen, wo setBuildParseTree = false?

CharStream cs = new ANTLRInputStream(new BufferedInputStream(input,8192)); 
    CSVLexer lexer = new CSVLexer(cs); 
    CommonTokenStream tokens = new CommonTokenStream(lexer); 
    CSVParser parser = new CSVParser(tokens); 
    ParseTree tree = parser.file(); 
    ParseTreeWalker walker = new ParseTreeWalker(); 
    walker.walk(myListener, tree); 

Ich habe versucht, es zu ändern, um einen ungepufferten Stream

CharStream cs= new UnbufferedCharStream(input) 
    CSVLexer lexer = new CSVLexer(cs); 
    lexer.setTokenFactory(new CommonTokenFactory(true)); 
    TokenStream tokens = new UnbufferedTokenStream(lexer); 
    CSVParser parser = new CSVParser(tokens); 

zu sein, wenn ich laufe Die Funktion walker.walk() verarbeitet keine Datensätze. Wenn ich etwas wie

versuchen

Es schlägt auch fehl. Es sieht so aus, als müsste ich die Datei anders analysieren, wenn ich keinen Syntaxbaum erstelle, also würde ich gerne Dokumentation oder Beispiele dafür haben.

Wenn ich ungepufferten Char-Stream nicht verwende, aber ungepufferten Token-Stream verwende, gibt es einen Fehler: Ungepufferter Stream kann seine Größe nicht kennen. Ich habe verschiedene Permutationen ausprobiert, aber normalerweise gibt es einen Java-Heap-Fehler oder ein "GC-Overhead-Limit überschritten".

Ich verwende this csv grammar

+2

Dies ist ein Java, nicht Antlr, Problem. Verwenden Sie die Java-CLI-Schalter, um den für Java verfügbaren Speicher erheblich zu erweitern. Übrigens bedeutet die Einstellung von setBuildParseTree auf false, dass der Walker nichts zu laufen hat. – GRosenberg

+0

Ich habe versucht, 15 Gigs mit CLI-Flag zuzuteilen, aber immer noch scheißt. Ich bin mir nicht sicher, was das Problem ist. Wissen Sie, wie man Parse-Tree ohne einen Parse-Tree-Walker durchläuft? – ForeverConfused

+1

Wenn kein übergeordneter Grund vorhanden ist, besteht der beste Ansatz darin, den eingegebenen Text in Blöcke mit überschaubarer Größe zu unterteilen. Andernfalls benötigen Sie Java-Speicher, der wahrscheinlich so groß wie der eingegebene Text ist, wenn nicht sogar mehr. Das heißt, CommonTokens enthalten nominell eine Lazy-Kopie ihres zugrunde liegenden Textes, der durch den Eingabetext unterstützt wird, um Token # getText() zu unterstützen. Wenn 'getText()' Unterstützung erwünscht ist, dann ist die minimale Java-Speicheranforderung die Summengröße des Eingabetextes, der Token- und Parsing-Baum-Overheads, der Antlr-Laufzeit und Ihres Programms. – GRosenberg

Antwort

1

antwortete ich bereits eine ähnliche Frage hier: https://stackoverflow.com/a/26120662/4094678

It seems like I have to parse the file differently if I don't build a parse tree, so I would like documentation or examples of how to do this.

Suchen Sie nach Grammatik Aktionen in antlr Buch - wie gesagt in der verknüpften Antwort, vergessen Zuhörer und Besucher und Aufbau eines Parse-Baumes. Auch wenn dies nicht genug ist, teilen Sie die Datei in eine Anzahl von kleineren und analysieren Sie dann jeden von ihnen.
Und natürlich, wie in den Kommentaren erwähnt erhöhen Java Vm-Speicher.

+0

Natürlich würden Grammatik-Aktionen funktionieren ... aber wenn eine implementierte Lösung mit Parse-Baum-Listenern arbeitet und nur während des Testens festgestellt wird, dass die Lösung mit LARGE-Dateien bricht, ist ein generisches Codierungsmuster zum Aufbrechen der Eingabe wahrscheinlich einfacher implementieren, dass alle Listener-Methoden in Grammatikaktionen umgeschrieben werden. –