Hatena::ブログ(Diary)

Alone Like a Rhinoceros Horn

2011-02-06

Vimノート - Vim script で構文解析するには、という考察

考察というか、ぼんやりと考えてみました的なもの。

まず、C/C++関数定義、あるいは Javaメソッド定義(コンストラクタ含む)を正規表現マッチによって拾うのはかなり苦しい*1。これらの言語の outline info は結構涙ぐましいものになっていて、「正規表現では括弧の数を数えられない*2」という至言とともに、「構文解析できたらなあ!」と痛感させられる。*3

Vim script正規表現でできるところまでやってやろうとは思うものの、Vim script構文解析という手法が使えるとしたら、どんな方法があるだろうか、と考え(妄想し)ておくことは、悪くないと思う。もしかしたら、ということもある。

まあ、半分ネタですけどw

1、ファイルタイプごとに構文解析器を Vim script で書く

Vim script再帰降下な構文解析器をごりごりと書く。見出しとして拾いたいものだけ認識できればいいので、構文のサブセットを認識できる最小のもの、ということなら、頑張ればなんとか……なる?

問題は、言語ごとに構文解析器をスクラッチするみたいな感じになるので、あまり数はこなせないだろうなあということ。後、Vim script で字句解析やったら絶対ボトルネックになると思われ。

2、構文解析器の生成系を Vim script で書く

個々の言語用に構文解析器を書くのではなく、構文解析器の生成系を Vim script で書き、そいつが生成した構文解析器を使うという大胆不敵な戦術。Vim scriptyacc、すなわち vacc(または vison)を開発する。

問題は、作るのが難しそう*4な点w 後、Vim script での字句解析がボトルネックになるという点は 1、と同じ。

3、言語インターフェースを利用する

PerlPythonRuby、いずれの言語も構文解析器の生成系を持っているので、それらで生成した構文解析器を言語インターフェース経由で呼び出すという方式。1、2、に比べるとかなり現実的。生成系に食わせる文法ファイルを用意すればいいだけだし、そういうのは多分言語の総本山にいけば入手できるだろう。

問題は、ユーザーの Vim にその言語のインターフェースがあるかどうかわからないという点。ないと見出し抽出できませんではやっぱりダメだと思われる。なので、その場合は既存の Vim script正規表現方式に fallback する必要があるだろう。


とまあ、ざっと思いついたのはこんなところ。他にも ! を使って system() を使って外部コマンドを呼び出す方法や libcall() を使う方法なども考えられる。どちらにしても、「Vim script だけで」っていうのは難しい感じ。

また何か思いついたら書く。

*1:目印となる予約語がない、というのが一番大きい。予約語がないと、構文上こうなってるよね、というのを正規表現で書かないといけないのだけど、それがかなり難しい。大体は、ゆるめにマッチさせて、やっぱり違った、というものは Vim script ではじく、みたいな形になる。

*2:文脈自由文法 ⊃ 正規文法

*3:一方、RubyPython みたいな LL系の言語は大抵見出し行に class とか def みたいな予約語があるので楽ちん♪

*4:世の中、難しそうに見えるものが本当に難しいかどうかはわからないもので、こういうのも偏見なのだろうなあとは思います。

トラックバック - http://d.hatena.ne.jp/h1mesuke/20110206/p1