VS2013でFsYacc、FsLexを使う
Visual Studio 2013*1でFsYaccとFsLexを使うには、基本的に
http://stackoverflow.com/questions/19781156/using-fslex-yacc-in-vs2013
の通りにすればいいのですが、2つほどハマったところがあったのでそれを書いておきます。
FsYacc、FsLexが参照するFSharp.Coreのバージョン
VS2013 + F# 3.1.1しかパソコンにインストールしていない場合、FsYaccやFsLexが起動しません。これはそれらのツールがFSarp.Core.dllのバージョン3.0を読みに行こうとしているのが原因です。
そこで、F#のコンパイラ(Fsc.exe)のあるディレクトリ*2にある「○○.exe.config」というファイルを2つぐらい、プロジェクトのfslex.exeやfsyacc.exeがあるディレクトリにコピーして、それぞれ「fslex.exe.config」「fsyacc.exe.config」とリネームします。これでFsYaccやFsLexはFSarp.Core.dllのバージョン3.1.1を読み込んでくれるようになります。
ファイルの更新順序
今回FsYaccの使い方についてfslexとfsyaccを使って字句・構文解析して電卓っぽい計算をしてくれる奴を作成したい - My Life as a Mock Quantを参考にさせてもらったのですが、この記事の例を試す時に
- Lexer.fslを追加して編集
- Parser.fsyを追加して編集
- Parser.fs、Lexer.fsを追加
- .fsprojファイルをいじる
- ビルド
の順番に作業するとうまくいきません。(FsLex、FsYaccが走らない)理由は、Lexer.fsやParser.fsをLexer.fslやParser.fsyより後に作成している(つまり、より新しい)ため、MsBuildが更新の必要がないとしてFsLexなどのタスクをスキップするためです。(結果、Parser.fsなどの中身が作成されない)
これを回避するには、まあ、Parser.fs、Lexer.fsをLexer.fslやParser.fsyよりも先に追加しておくとか、.fslや.fsyに適当なコメントとかを書いて更新時間を遅くする、とか。おそらく初回のビルド以降では問題にはならないでしょう。
なお、これはMsBuildのコンパイルタスク*3を使うときに問題になりますが、Pre-build eventで直接fslex.exeなどをたたく方法の時は関係ありません*4
まとめ
- FsYaccなどが参照するdllを~.exe.configでごまかす
- ファイルの更新時間に気を付ける。.fsyや.fslの方を新しくする