ANTLRでOracleのDDLを解析してみる

#contents

*文法ファイル [#e3077a65]
	
文法ファイルは下記のサイトで公開されていました。	
	http://www.antlr.org/grammar/1174072667394/PLSQLGrammar.g

 PLSQLGrammar.g	
で保存	


antlrのjarファイルがあるディレクトリで実行すると、いろいろファイルができそうだったので、	

olacle_ddlというフォルダをつくってそこに保存	

*前回ANTLRを動かした例を参考にコンパイルしてみる [#i95dd298]
前回やってみた例ではこんなかんじ	
 java -jar antlr-3.4-complete-no-antlrv2.jar  T.g	
だからまねて次のようにしてみた。	
 java -jar ../antlr-3.4-complete-no-antlrv2.jar  PLSQLGrammar.g	

**結果 [#r733d84a]
 error(10):  internal error:  : java.lang.Error: Error parsing PLSQLGrammar.g: 'header' not expected 'grammar'
 org.antlr.tool.GrammarSpelunker.match(GrammarSpelunker.java:70)

 java -classpath antlr-2.7.2.jar antlr.Tool T.g
だと、前のバージョンでうごいたから、これをさんこうにして

 java -classpath ../antlr-2.7.2.jar antlr.Tool PLSQLGrammar.g

**結果 [#kee796b6]
なにやら、警告分がたくさんでたが、動いた。

PLSqlLexer.javaやPLSqlParser.javaなど4ファイルが出力されている

さいしょから、このファイルをダウンロードできるようにしておいたほうが、面倒なコンパイルとかしなくていいんじゃない?って
おもうのであった。それは、さておき

**確認用のコード [#p66e8d02]
確認用のコードをつくってみなくては、

前回ためしてみたメインクラスを参考にしてみることにした、えー、前回確認してみたコードは次のコードである

 import java.io.*;
 
 class Main {
   public static void main(String[] args) {
       try {
           L lexer = new L(new DataInputStream(System.in));
           P parser = new P(lexer);
           parser.startRule();
       } catch(Exception e) {
           System.err.println("exception: "+e);
       }
   }
 }

このクラスを、生成されたクラスの名前とかみて、手直しすると次のようになるのではないかとおもう。

 import java.io.*;
 
 class Main {
   public static void main(String[] args) {
       try {
           PLSqlLexer lexer = new PLSqlLexer(new DataInputStream(System.in));
           PLSqlParser parser = new PLSqlParser(lexer);
           parser.start_rule();
       } catch(Exception e) {
           System.err.println("exception: "+e);
       }
   }
 }

start_ruleメソッドを観察すると、どうやらreturnAST変数に格納されることで、満足して、戻り値を返さないという
なんとも、自己満足的なメソッドとなっているようだ。

ここを改造すればよいのだな。でもどういう変数が格納されているのかわからないや。
デバックで止めるために、エクリプスにいれるのも面倒だし。。。

とりあえずコンパイルじゃ。

 javac -classpath ../antlr-2.7.2.jar *.java

**結果 [#v09f39df]


 PLSqlLexer.java:487: エラー: シンボルを見つけられません
                        SoftwareMetrics.adjustMetrics(getText(), getLine());
                        ^
  シンボル:   変数 SoftwareMetrics
  場所: クラス PLSqlLexer


 SoftwareMetricsを//SoftwareMetricsに置換してコメントアウトした。

で、コンパイル

 if (lcnt > 0) //SoftwareMetrics.incBlanks(lcnt - 1);

でこけてたので、コメントアウトしなおし

//if (lcnt > 0) //SoftwareMetrics.incBlanks(lcnt - 1);

こんなふうにした

**結果 [#d230cd35]
 PLSqlParser.java:1075: エラー: シンボルを見つけられません
                                SoftwareMetrics.start(pn.getText(),"Package",pk.
getLine());
                                 ^
  シンボル:   変数 SoftwareMetrics
  場所: クラス PLSqlParser

PLSqlParserにもあるようだ。じゃまなのが、

同様にコメントアウトする

**結果 [#ya550b71]
こんなメッセージがでたが、コンパイルできた
 注意:PLSqlLexer.javaの操作は、未チェックまたは安全ではありません。
 注意:詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください。

**DDLのサンプルを用意する [#se5b8c97]
http://oracle.se-free.com/ddl/A1_cre_tbl.html

DDLを解析といっても、テーブル作成のDDLしか興味がないのだ。
プライマリ付きのテーブル
 create table emp
 (
  emp_id char(3) ,
  emp_name varchar2(10),
  primary key( emp_id )
 )

実行させてみます。

 java -classpath .;../antlr-2.7.2.jar Main

標準入力を受け付けたままになっているはずなので、DDLをペーストしてみます。

**結果 [#v1ee495a]

 create table emp
 line 1:8: unexpected token: table
 (

あれ?tableって単語は、予期してませんでしたって出てる

おいおい、予期してくれよう

かんべんしてよ。。。っておもいながら、しょせんフリーなんてどうさ確認もとれてませんという

ことなんだよねと自分を説得します。

**後述 [#l5598037]

SELECT文だと通った気がする。

*他のSQLパーサの文法ファイルを検討する [#nbc385b2]
ほかに、ないのかとしらべてみると、

 http://www.antlr.org/grammar/list

にOraclleSQLが載っていました。

ためしてみましょう。

tgzでかためられた

えーと、C言語用でした。

**Javaへの変換 [#s698777b]
Perlで書かれたJavaに置き換えるスクリプトも同梱されているもよう。


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS