120日目の記事です。2012はまだまだ執筆者を募集中です。scriptで行うという記事があったのを覚えておいででしょうか。scriptで字句解析!と組み合わせて使っていただければいろいろできるかもしれません。いうわけで、実際にやってみましょう。Calendarの2つの記事をまとめた集大成です。15となるような関数s:calcを持つファイルcalc.vimを作ります。足し算より掛け算の方が演算子結合順序が強く、また括弧もあるというものです。トークン列に分解し、その後パースしつつ各ノードを評価してひとつの値に畳み込む、という一般的かつ簡単な方法でやっていくことにしましょう。Lexerまずは字句解析です。ひとかとまりの文字列を、トークンのListに変換します。http://qiita.com/items/a5ead41d4a1d4cbaeb74rbtnnさんが作成したVital.Lexerを用います。vitalを用いるので、まずは開発用に&rtpに入っているvitalをそのままvital#of('vital')を通して利用しましょう。s:L.lexer(s:rule).parse(a:str)endfunctionかなり短くかつ宣言的に記述することができました。]といった辞書のリストが得られます。無事字句解析ができているようです。読者皆様はparse()関数の突然の登場に面食らったのではないでしょうか。この関数は構文解析器とは何の関係もありません。この名前が非常にまぎらわしいとのことで、vitalのissueにチケットを作成しておきました。https://github.com/vim-jp/vital.vim/issues/48Parser続いて構文解析です。http://uwanosora.hatenablog.jp/entry/2013/03/28/000633uwanosoraさんが作成したkp19ppはC++で記述されており、g++とmakeがあればビルドできます。実際に必要なのは生成されるkp19ppコマンドです。自分でインストールしてPATHを通すのが面倒に感じた読者の方もいらっしゃることでしょう。そんなこともあろうかと、Gentoo用にパッケージ化しておきました。kp19ppすると/usr/bin/kp19ppが利用可能になります。kp19ppは独自の言語です。ftpluginをセットにしたプラギンを作っておきました。これを用いることでパーサを簡単に記述できるようになります。https://github.com/ujihisa/ft-kp19pp.vimさあ早速パーサを記述しましょう。Calendarの該当記事からそのままもってきました。scriptを生成しましょう。scriptのparser.vimファイルが生成されました。つづいて各アクションmake_plsなどを記述しましょう。'error!'endfunctionこれで構文解析器と評価器は完成です。結合Vital.Lexerを用いて作成した字句解析器とkp19ppを用いて作成した構文解析器とそれに適用するよう作成した評価機のすべてを組み合わせましょう。calc.vimつづいてメイン処理です。s:p.accepted_valueendif(逐次パーサにトークン列をひとつずつ渡すより前にfilter()で空白文字を削除しています。これは別にforの中で条件分岐しても良いです。)あとは実行すると正しい計算結果が得られるはずです。calc.vimで実行できます。gif動画作ってみました。それなりの長さですので、気を引き締めてお楽しみください。