2015-12-10 64 views
8

我想從這裏編譯ISO-SQL 2003語法 http://www.antlr3.org/grammar/1304304798093/SQL2003_Grammar.zip。它的所有三個版本可以在這裏找到http://www.antlr3.org/grammar/list.html編譯ISO SQL-2003 ANTLR語法

這些是我遵循的步驟,

  1. Java的罐子ANTLR-3.3-complete.jar -Xmx8G -Xwatchconversion sql2003Lexer.g
  2. Java的罐子ANTLR-3.3-complete.jar -Xmx8G -Xwatchconversion sql2003Parser.g
  3. 的javac ANTLRDemo.java

ANTLRDemo.java文件:

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(); 
    } 
} 

前兩步做工精細,然後在編譯我的主類,我得到了很多關於Java的語法像這樣的錯誤:

./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'))) {

請讓我知道如果我做錯事的建立解析器。
如果有人能告訴我如何使用ANTLR來設置這個語法,那將會很有幫助。

編輯:經過多一點弄亂之後,我認爲這些錯誤是由詞法分析器和解析器規則中存在的操作引起的。有沒有一種安全的方法來克服這個問題?

回答

1

你沒有做錯什麼,ANTLR從來沒有能夠從這些語法文件中生成一個可用的Java解析器。

根據崗位由道格拉斯·戈弗雷到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

我不太確定這是完全正確的。同一個人'道格拉斯戈弗雷'先前發佈在同一個線程上,他設法用8GB的堆空間進行編譯[http://www.antlr3.org/pipermail/antlr-interest/2011-October/042850.html]。另外SQL2003在antlr2 [http://www.antlr2.org/]的官方頁面上列出,我也想到了3(感謝同一個人)。感謝您查看此問題:) – noob333

+0

排除與ANTLR不兼容的整個語法不是正確的方式,我認爲:) – noob333

+0

@ noob333如果您不相信Godfrey先生曾經構建SQL的話語法解析器的生活,然後我不知道還有誰能說服你。另一方面,許多偉大的事物都是由不知道這是不可能的人來修復語法的。 – anttix

1

是的,基本上你是對的。語法被打破了。但是在ANTLRDemo.java中也有錯誤,因爲Parser類中沒有eval()方法。您應該使用解析器語法的任何規則的名稱調用方法,例如query_specification()。在語法本身中,有些錯誤看起來像打字錯誤,一些未定義的方法調用,skip()解析器中的調用僅適用於詞法分析器。您會看到this commit中的所有修復程序。我在this GitHub repository發表了我的研究。

我開始修復語法的明顯錯誤,這導致了生成的java代碼中的編譯錯誤。我發佈了與您相同的錯誤。最終,我修復了所有的Java語法錯誤,但遇到了另一個不可能直接修復的錯誤,因爲它起源於JVM的限制,即compilation error: code too large。閱讀ANTLR郵件列表時,有一種提示將大型類的一些靜態成員提取到單獨的接口中,並「實現」它們以實現多重繼承。通過試驗和錯誤,我最終得到了解析器在sql2003Parser.java中的6個「imlemented」接口。

但還是有2個問題:

  • 錯誤的開始規則。道格拉斯戈弗雷寫了一個以sql2003Parser規則開頭的語法。不幸的是,如果你通過這個啓動規則調用解析器,它將不會正確解析,即使最簡單select a from b。所以我通過query_specification規則調用解析器來解析SELECT子句。
  • 語法中的一些其他錯誤。我沒有深入研究語法,但query_specification未能解析一些隨機的複雜SQL。