なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

Tinyexprで文字列上の数値計算をする

久しぶりにC++の記事

以下のような文字列中の数値計算をどうすれば行えるか悩んでいた。

これを

MOV     ECX,512*1024/4

これに変換したい

MOV     ECX,131072

Tinyexpr

それには文字列型の計算式を評価して結果を返すライブラリが必要。とりあえず組み込みやすいやつを入れる。
github.com

Tinyexpr使用例

CppUTestを使ってテストを書いてみた

  • 別にdouble型じゃなくても使える
  • std::isnan 便利っぽい(JavascriptのNaNと同じようなもん)
TEST(tinyexpr_suite, testNask)
{
     int error;

     const double ecx1 = te_interp("512*1024/4", &error);
     CHECK(!std::isnan(ecx1));
     CHECK_EQUAL(131072, ecx1);

     const double ecx2 = te_interp("512/4", &error);
     CHECK(!std::isnan(ecx2));
     CHECK_EQUAL(128, ecx2);

     const double dw = te_interp("8*3-1", &error);
     CHECK(!std::isnan(dw));
     CHECK_EQUAL(23, dw);
}

正規表現で計算式を見つけ出して処理するぞ

     // 正規表現は、
     // (***数字じゃない奴***)(***数字と数学記号***)(***数字じゃない奴***)
     //
     std::regex re("([^0-9]*)([-\\*/+0-9]*)([^0-9]*)");
     std::smatch match;
     if (std::regex_search(subject, match, re) && match.size() > 1) {
          int error;
          const int process = te_interp(match[2].str().c_str(), &error);
          return match[1].str() + std::to_string(process) + match[3].str();
     }