77. 数式パーサー¶
文字列で表現された数式をパースし、計算結果を取得する方法を学びます。
77.1 数式のパース¶
- 数式をパースし、計算結果を取得する次のような関数があります
| コード | 説明 | 
|---|---|
| double Eval(数式) | 数式をパースし、計算結果を double型で返す。数式が不正な場合は NaNを返す | 
| Optional<double> EvalOpt(数式) | 数式をパースし、計算結果を double型で返す。数式が不正な場合は noneを返す | 
- 数式内では次のような演算子や関数を使用できます:- +,- -,- *,- /,- %,- ^
- log2,- log10,- log,- ln,- exp,- sqrt,- sign,- abs,- min,- max,- sin,- cos,- tan,- asin,- acos,- atan,- sinh,- cosh,- tanh,- asinh,- acosh,- atanh
 
# include <Siv3D.hpp>
void Main()
{
	{
		const String expression = U"100 + 10 * 2 + sqrt(9) + 10 * 0.2 ^2";
		Print << Eval(expression);
		Print << EvalOpt(expression);
	}
	{
		// 不正な数式
		const String expression = U"100 +";
		Print << Eval(expression);
		Print << EvalOpt(expression);
	}
	while (System::Update())
	{
	}
}
77.2 定数の追加¶
- 独自の定数など、新しい要素を数式内で使えるようにしたい場合は MathParserクラスを使用します
# include <Siv3D.hpp>
void Main()
{
	MathParser parser;
    // 定数の追加
	parser.setConstant(U"pi", Math::Pi);
	parser.setConstant(U"x", 100);
    // 数式の設定
	parser.setExpression(U"x * pi");
	Print << parser.eval();
	Print << parser.evalOpt();
	while (System::Update())
	{
	}
}
77.3 変数の追加¶
- MathParserに- double型の変数のアドレスを登録することで、数式内で変数を使用できます
# include <Siv3D.hpp>
void Main()
{
	double x = 0.0;
	MathParser parser;
	parser.setVariable(U"x", &x);
	parser.setExpression(U"100 + x");
	for (int32 i = 0; i < 10; ++i)
	{
		x = (i * 0.1);
		Print << parser.eval();
	}
	while (System::Update())
	{
	}
}
77.4 関数の追加¶
- MathParserに独自の関数を登録できます
# include <Siv3D.hpp>
double CircleArea(double r)
{
	return (Math::Pi * r * r);
}
double TriangleArea(double a, double b, double c)
{
	double s = ((a + b + c) / 2.0);
	return std::sqrt(s * (s - a) * (s - b) * (s - c));
}
void Main()
{
	MathParser parser;
	parser.setFunction(U"circleArea", CircleArea);
	parser.setFunction(U"triangleArea", TriangleArea);
	parser.setExpression(U"circleArea(10)");
	Print << parser.eval();
	parser.setExpression(U"triangleArea(3, 4, 5)");
	Print << parser.eval();
	while (System::Update())
	{
	}
}