2 Way SQLパーサとしてのDoma

もともとは「2Way SQLのパーサ *だけ* って無いのかな?」と思って探したら偶然見つけた。なので、本当に欲しかったのは「2Way SQLのパーサ」。案外無いので、clione-sqlとかmirages2jdbcのソース読んで勉強するしかないかなと思ってる。

2012-04-07

Domaも仲間に入れてあげてー。


実はDomaには2 Way SQLパーサ単独で使用された実績があったりするんです。


Domaのパーサには大きく3つの特長があります。

  1. Visitorパターンを使っているのでパース結果を柔軟に扱える。
  2. パースの粒度が細かく、悲観的ロックやページングのSQLへの書き換えに耐えられる。
  3. 他のライブラリに依存していない。


Visitorの実装の詳細は省きますが、こんな感じで使えます。

public class Main {

    public static void main(String[] args) {
        SqlParser parser = new SqlParser(
                "select * from hoge where foo = /* bar */'test'");
        SqlNode node = parser.parse();
        node.accept(new MyVisitor(), null);
    }
}

class MyVisitor implements SqlNodeVisitor<Void, Void>,
        AnonymousNodeVisitor<Void, Void>, BindVariableNodeVisitor<Void, Void>,
        CommentNodeVisitor<Void, Void>, ElseifNodeVisitor<Void, Void>,
        ElseNodeVisitor<Void, Void>, EmbeddedVariableNodeVisitor<Void, Void>,
        EndNodeVisitor<Void, Void>, EolNodeVisitor<Void, Void>,
        ForBlockNodeVisitor<Void, Void>, ForNodeVisitor<Void, Void>,
        ForUpdateClauseNodeVisitor<Void, Void>,
        FragmentNodeVisitor<Void, Void>, FromClauseNodeVisitor<Void, Void>,
        GroupByClauseNodeVisitor<Void, Void>,
        HavingClauseNodeVisitor<Void, Void>, IfBlockNodeVisitor<Void, Void>,
        IfNodeVisitor<Void, Void>, LogicalOperatorNodeVisitor<Void, Void>,
        OrderByClauseNodeVisitor<Void, Void>, OtherNodeVisitor<Void, Void>,
        ParensNodeVisitor<Void, Void>, SelectClauseNodeVisitor<Void, Void>,
        SelectStatementNodeVisitor<Void, Void>,
        WhereClauseNodeVisitor<Void, Void>, WhitespaceNodeVisitor<Void, Void>,
        WordNodeVisitor<Void, Void> {
	
	...

}


関連リソースへのリンクです。


ところで、話は変わりますが、Domaを作った当時は知識がなくて字句解析とか構文解析を自前でがんばったんですが、今やるならparser generator使うだろうなーと思います。F#ではfslex/fsyaccを使ったんですが、Domaと同様の文法を字句/構文解析できましたし、結果的に楽でした。fslex/fsyaccの情報がすくなかったりしてルール書くのに骨が折れましたけど。