背景
ちょっとわけあってフリーフォーマットで入力された式を解析して計算するという処理が必要となった。
例えば「売上」といったテーブルがあったとする。
CREATE TABLE Sale '売上'
(
product_id INT PRIMARY KEY , '商品ID'
price INT, '価格'
unit INT, '売上数量'
) ;
で、ユーザーが数式として
価格 × 売上数量 で商品の総売上額を算出する、みたいなイメージだ。
この手はパーサーを活用して文を定義したりするのが王道のようだが、なかなか難しい分野でもある。
それでなんかもっと直感的に楽に使えるライブラリとかないかなーと探していたらNCalcがひっかかった。
NCalcとは
一番最初に引っかかったページが以下だ。
http://gottaniprogramming.seesaa.net/article/458949172.html
で、そこからNCalcについて調べてみるとまず以下のサイトがヒットした。
https://archive.codeplex.com/?p=ncalc
なるほど使い方自体はそれほど難しくない。
インスタンス生成時に計算式を与えてEvaluateを実行すればobject型で計算結果を返してくれるようだ。
変数を与えた場合でもパラメータとして定義すれば計算してくれる。これは確かに便利そうだ。
NuGetから取得するか自力でビルドするか
NuGetパッケージで提供されているようなのでNuGetパッケージマネージャーからインストールを試みる。
ncalc自体はすぐに見つかる。他にもいくつかあるようだがこれで大丈夫そう……ん?
公開日が2011年11月で最新のバージョンが1.3.8? やけに古い。嫌な予感がしてプロジェクトURLへジャンプしてみる。
どれも7年前で更新が止まってるやんけ…
ライセンスも確認したいが見当たらない。これは使えないかと諦めつつページを漁っていると
https://github.com/sheetsync/NCalc/issues/5
要はyallieさんという人がこのプロジェクトを引き継いで新しいプロジェクトを作成してくれているみたいだ。
それがこれ↓
https://github.com/ncalc/ncalc
ライセンスも明示されており、更新もそこそこされている。
使いたい場合はこちらを使用する方が確実だろう。
ただしこちらはNuGetパッケージではないので使用したい場合はGitHubからソースをダウンロードする必要がある。
NCalcのその他注意点
使用できる計算記号は↓。大小判定によるtrue/falseの返却もできる。
https://github.com/ncalc/ncalc/wiki/Operators
使用できる関数は↓。関数内にパラメータを使用することももちろん可能。
https://github.com/ncalc/ncalc/wiki/Functions
いろいろ検証してみたが単純な四則演算レベルならまったく問題ない。
注意点としては全角文字が使えないくらいだろうか。
これはNCalcというよりもNCalcが利用しているAntlrのせいだ。そもそもプログラム言語で全角を使おうという魂胆がもう甘えである。
ちなみに日本語は当然のことだが計算記号の全角(+)みたいなのも認識しない。
※Antlrのバージョンを3から4にあげれば対応できるみたいな記事も見かけたが、あまり確証はないし、Antlr 3からAntlr 4 へのマイグレーションはかなり困難をきわめる。文法自体が大きく変わっているのだ。
なので最初の例にあげた価格 × 売上数量みたいな計算はそのままではできないので、UI上は日本語入力させておきながら裏側では日本語名と英語名(price, unit)をマッピングしておけばいいだろう。
あとは項目名と計算記号そのものの解析をどうするかといった仕様は人によって変わるだろうからそこらへんは突っ込まない。
このライブラリは非常に使いやすいので文字列のまま計算したいみたいな需要が発生した時は候補のひとつとしてもいいと思う。