FParsecを利用して作成したパーサをUnityのスクリプト上で利用する

半年振りのUnity(ゲームエンジン)ネタです。

かつてF# で作成したライブラリをUnityのスクリプト上で利用する - pocketberserkerの爆走な記事を書いたわけですが、じゃあFParsecも動くのでは?という楽観的考えから試してみることにしました。

FParsecの準備

FParsecはHaskellのパーサ・コンビネータライブラリParsecをF#に移植したものです。

さてこのFParsecさん、.NET 4.0対象であればNuGetさんでさくっと導入できるのですが、Unity3.5のMonoさんは未だ.NET 3.5互換です。さくっとは入れられません。

というわけで、下記リポジトリからソースを取得してビルドします。

fparsec / main — Bitbucket

ただ、こいつもそのままビルドすると.NET 4.0系ライブラリになってしまうので、プロジェクトプロパティの設定を変更してからビルドします。

  1. "条件付きコンパイルシンボル"から"CLR4"の記述を削除
  2. "対象のフレームワーク"を.NET Framework 3.5系にする

これでビルドするとFParsecとFParsecCSのdllができあがるはずです。おそらくこれで同じように動作するはずです*1。他のプロジェクトがビルドに失敗しているかもしれませんが、サンプルやテストプロジェクトなのでひとまず無視。

FParsecを利用したF#ライブラリを作る

ではFParsecを早速作ってみましょう!

サンプルとしては、チュートリアルの最初にでてくる"小数一つのパース"でいきましょうか。

#112 FParsec日本語チュートリアル « F# « a wandering wolf

module FloatParser

open FParsec

let test p str = 
  match run p str with
  | Success(result, _, _)   -> "Success: " + string result
  | Failure(errorMsg, _, _) -> "Failure: " + errorMsg

let parse str = test pfloat str

parse関数に文字列を渡すと、解析に成功したか失敗したかを教えてくれます。
サンプルなのでこんなもんでいいでしょう。

このプロジェクトをビルドして(ビルドオプションにフラグ"--standalone"をつけておくのを忘れずに)、dllの出来上がり。

Unity側で使う

出来上がったdllを、Unityプロジェクト下にあるAssetsフォルダのどこかに放り込みましょう。

そしてお試しにテキストを二つ用意します。

using UnityEngine;
using System.Collections;

public class CountViewer : MonoBehaviour
{

    string input = "";
    string parseResult = ""; 

    void OnGUI()
    {

        GUILayout.BeginArea(new Rect(10, 100, 500, 500));
        GUILayout.Label("Please input float number!.");
        input = GUILayout.TextField(input, 25);
        parseResult = GUILayout.TextArea(FloatParser.parse(input), 100);
        GUILayout.EndArea();
    }
}

実にシンプルですね。

あとはこのスクリプトをEmpty Objectにリンクさせれば動くようになります。

実行結果

まず小数を入力した場合

次に小数以外を入力した場合

パースできてますね。

何がうれしいの?

F#でパーサをさくっと作って、スクリプト側で読み込んで使えたりします。
いやまぁ、Unityでそんなもの使わないと言われたらそこまでですが。

*1:細かく確認できていない・・・