ANTLRでOracleのDDLを解析してみる
文法ファイルは下記のサイトで公開されていました。
http://www.antlr.org/grammar/1174072667394/PLSQLGrammar.g
PLSQLGrammar.g
で保存
antlrのjarファイルがあるディレクトリで実行すると、いろいろファイルができそうだったので、
olacle_ddlというフォルダをつくってそこに保存
前回やってみた例ではこんなかんじ
java -jar antlr-3.4-complete-no-antlrv2.jar T.g
だからまねて次のようにしてみた。
java -jar ../antlr-3.4-complete-no-antlrv2.jar PLSQLGrammar.g
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
なにやら、警告分がたくさんでたが、動いた。
PLSqlLexer?.javaやPLSqlParser?.javaなど4ファイルが出力されている
さいしょから、このファイルをダウンロードできるようにしておいたほうが、面倒なコンパイルとかしなくていいんじゃない?って おもうのであった。それは、さておき
確認用のコードをつくってみなくては、
前回ためしてみたメインクラスを参考にしてみることにした、えー、前回確認してみたコードは次のコードである
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
PLSqlLexer.java:487: エラー: シンボルを見つけられません SoftwareMetrics.adjustMetrics(getText(), getLine()); ^ シンボル: 変数 SoftwareMetrics 場所: クラス PLSqlLexer
SoftwareMetricsを//SoftwareMetricsに置換してコメントアウトした。
で、コンパイル
if (lcnt > 0) //SoftwareMetrics.incBlanks(lcnt - 1);
でこけてたので、コメントアウトしなおし
こんなふうにした
PLSqlParser.java:1075: エラー: シンボルを見つけられません SoftwareMetrics.start(pn.getText(),"Package",pk.
getLine());
^ シンボル: 変数 SoftwareMetrics 場所: クラス PLSqlParser
PLSqlParser?にもあるようだ。じゃまなのが、
同様にコメントアウトする
こんなメッセージがでたが、コンパイルできた
注意:PLSqlLexer.javaの操作は、未チェックまたは安全ではありません。 注意:詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください。
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をペーストしてみます。
create table emp line 1:8: unexpected token: table (
あれ?tableって単語は、予期してませんでしたって出てる
おいおい、予期してくれよう
かんべんしてよ。。。っておもいながら、しょせんフリーなんてどうさ確認もとれてませんという
ことなんだよねと自分を説得します。
SELECT文だと通った気がする。
ほかに、ないのかとしらべてみると、
http://www.antlr.org/grammar/list
にOraclleSQLが載っていました。
ためしてみましょう。
tgzでかためられた
えーと、C言語用でした。
Perlで書かれたJavaに置き換えるスクリプトも同梱されているもよう。