2015-12-10 7 views
8

Ich versuche, die ISO-SQL 2003-Grammatik von hier http://www.antlr3.org/grammar/1304304798093/SQL2003_Grammar.zip zu kompilieren. Alle drei Versionen davon finden Sie hier http://www.antlr3.org/grammar/list.html.Kompilieren von ISO SQL-2003 ANTLR Grammar

Dies sind die Schritte, die ich gefolgt,

  1. java -jar antlr-3.3-complete.jar -Xmx8G -Xwatchconversion sql2003Lexer.g
  2. java -jar antlr-3.3-complete.jar -Xmx8G -Xwatchconversion sql2003Parser.g
  3. javac ANTLRDemo.java

ANTLRDemo.java Datei:

import org.antlr.runtime.*; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 

public class ANTLRDemo { 
    static String readFile(String path) throws IOException 
    { 
     byte[] encoded = Files.readAllBytes(Paths.get(path)); 
     return new String(encoded, "UTF-8"); 
    } 

    public static void main(String[] args) throws Exception { 
     ANTLRStringStream in = new ANTLRStringStream(readFile(args[0])); 
     sql2003Lexer lexer = new sql2003Lexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     sql2003Parser parser = new sql2003Parser(tokens); 
     parser.eval(); 
    } 
} 

ersten beiden Schritte funktionieren, dann während meine Hauptklasse kompilieren ich viele Fehler erhalten im Zusammenhang mit Java-Syntax wie diese:

./sql2003Parser.java:96985: error: not a statement $UnsignedInteger.text == '1' ./sql2003Parser.java:96985: error: ';' expected $UnsignedInteger.text == '1' ./sql2003Parser.java:102659: error: unclosed character literal if (!(((Unsigned_Integer3887!=null?Unsigned_Integer3887.getText():null) == '01'))) {

Bitte lassen Sie mich wissen, ob ich bei der Einrichtung etwas falsch zu machen bin der Parser.
Es wäre hilfreich, wenn mir jemand zeigen könnte, wie man diese Grammatik mit ANTLR genau einrichtet.

Edit: Nach ein wenig mehr fiedeln, denke ich, dass diese Fehler durch die Aktionen in Lexer und Parser-Regeln verursacht werden. Gibt es einen sicheren Weg, dies zu überwinden?

Antwort

1

Sie machen nichts falsch, ANTLR konnte aus diesen Grammatikdateien niemals einen funktionierenden Java-Parser erzeugen.

Nach einem Beitrag von Douglas Godfrey zu antlr-interest in Oct 2011:

I generated a C parser and lexer. they both generate and compile successfully on my machine with 8GB heap allocated to Antlr.

...

I don't believe that it will ever be possible to get a working parser in Java. A C language parser on the other hand is quite possible.

+0

Ich bin nicht wirklich sicher, dass das völlig richtig ist. Die gleiche Person "Douglas Godfrey" hat zuvor auf demselben Thread gepostet, dass er es geschafft hat, es mit 8 GB Heapspace zu kompilieren [http://www.antlr3.org/pipermail/antlr-interest/2011-October/042850.html]. Auch SQL2003 ist auf den offiziellen Seiten von antlr2 [http://www.antlr2.org/] und 3 aufgeführt, denke ich (Danke an die selbe Person). Danke, dass Sie sich diese Frage angeschaut haben :) – noob333

+0

Eine ganze Grammatik als inkompatibel mit ANTLR abzulehnen, ist nicht der richtige Weg zu gehen, denke ich :) – noob333

+0

@noob333 Wenn Sie den Worten von Mr. Godfrey, der SQL baute, nicht glauben Grammatik-Parser zum Leben, dann weiß ich nicht, wer dich sonst noch überzeugen kann. Auf der anderen Seite wurden viele großartige Dinge von Leuten gebaut, die nicht wussten, dass es unmöglich ist, also viel Glück bei der Korrektur dieser Grammatik. – anttix

1

Ja, im Grunde haben Sie recht. Die Grammatik ist gebrochen. Aber es gibt auch einen Fehler in Ihrem ANTLRDemo.java, da es keine eval() Methode in Parser Klasse gibt. Sie sollten die Methode mit dem Namen einer beliebigen Regel der Parsergrammatik aufrufen, z. query_specification(). In der Grammatik selbst gab es einige Fehler, die als Schreibfehler galten, einige undefinierte Java error() Methodenaufrufe, skip() Aufrufe im Parser, die nur im Lexer geeignet sind. Sie sehen alle Korrekturen in this commit. Ich habe meine Forschung in this GitHub repository veröffentlicht.

Ich fing an, offensichtliche Fehler der Grammatik zu beheben, was zu den Kompilierungsfehlern in generiertem Java-Code führte. Ich hatte die gleichen Fehler, die du gepostet hast. Schließlich habe ich alle Java-Syntaxfehler behoben, aber es gab eine andere, die nicht direkt behoben werden konnte, weil sie aus der Beschränkung von JVM, der compilation error: code too large, stammt. Beim Lesen der ANTLR-Mailingliste gab es einen Hinweis, einige statische Mitglieder der riesigen Klassen in separate Schnittstellen zu extrahieren und sie "zu implementieren", um eine Art Mehrfachvererbung zu erhalten. Mit Versuch und Irrtum endete ich mit 6 Schnittstellen, die durch den Parser in sql2003Parser.java "ergänzt" wurden.

Aber immer noch gibt es 2 Probleme:

  • Falsche Startregel. Douglas Godfrey schrieb Grammatik, die mit sql2003Parser Regel beginnt. Leider, wenn Sie Parser mit dieser Startregel aufrufen, wird es nicht einmal select a from b korrekt analysieren. So rufe ich Parser von query_specification Regel nur SELECT Klausel parsen.
  • Einige andere Fehler in der Grammatik. Ich habe nicht zu tief in der Grammatik gegraben, aber kann einige zufällige komplexe SQLs nicht analysieren.