Subscribed unsubscribe Subscribe Subscribe

Islands in the byte stream

Technical notes by a software engineer

AndroidライブラリでANTLR4によるパーサを生成&使用する

三行まとめ

  • ANTLR4で生成したパーサはAndroidからも利用可能
  • ANTRL4によるパーサはJavaCCによるパーサと比べてずっと遅く、実機では10ms単位で時間を使うので注意
  • ANTLR4を組み込むにあたってのビルドスクリプトAndroid-Orma/migration/build.gradleを参照のこと

詳細

Orma の自動マイグレーションモジュール(orma-migration)ではSQLite DDLから ALTER TABLE などの差分を生成してます。

この orma-migration ではDDL構文解析JavaCCベースのJSqlParserを使っていたのですが、SQLiteの拡張構文(たとえばカラム定義における UNIQUE ON CONFLICT REPLACE など)に対応していないため、すでに拡張構文を多用しているアプリケーションでOrmaを導入できないという問題がありました。

そこで、ANTLR4によるSQLiteの構文定義があったのでこれを利用してパーサを生成し、Ormaに組み込んでみました。

まずは使い物になるかどうかを検証するために、Gradleで標準的とみられる組み込みのantlrプラグインを利用して実装しました。

built-in SQLite parser by gfx · Pull Request #84 · gfx/Android-Orma · GitHub

実機でも動作することが確認できたので、最終的にAndroid libraryであるorma-migrationモジュールにマージしました。 これはリリースに際して余計なモジュールを増やしたくなかったからです。

Gralde組み込みのantlrプラグインJava project前提なのでantlrの呼び出しを自分で行わなければいけませんが、それほど難しくないので特にantlrプラグインにこだわることもないでしょう。

Merge sqliteparser/ to migration/ by gfx · Pull Request #87 · gfx/Android-Orma · GitHub

SQLiteに特化しつつ外部のパーサライブラリに依存しなくなったので、機能拡張はずいぶん楽になりました。ANTLR4のランタイムAPIは素直なのでANTLR4の事前知識がなくても難しくはありません。とはいえここまでANTLR4に置き換えるまでに丸2日くらいかかりましたが。

なおPR#84 にパフォーマンスの測定もしています。残念ながらJSqlParserと比較して10倍以上遅く、1回のパースで10ms以上かかっています。この測定はNexus 9 (Android 6.0.1) で行ったので、普通の端末だと更に時間がかかるでしょう。マイグレーションはそれほど頻繁に行うタスクではないものの、テーブルの定義が多いとパースの時間だけでかなり時間がかかることになります。