#ifndef __FORMULA_EVAL_HPP__ #define __FORMULA_EVAL_HPP__ // 「公式映射」的表达式编译与求值(信号样式区的 `Y = …` 输入框)。 // // 语法(刻意保持极小,避免引入脚本引擎与额外的体积): // expr := term (('+' | '-') term)* // term := unary (('*' | '/') unary)* // unary := ('+' | '-') unary | power // power := primary ('^' unary)? —— 右结合:2^3^2 = 2^(3^2) // primary := number | '(' expr ')' | variable | constant // number := 十进制小数(支持 e/E 指数) // constant:= `e`(自然常数)| `pi`(圆周率)—— 大小写均接受,保存前统一为小写 // variable:= `X` / `x` / `f(t)` —— 都表示"当前采样点的值"(**不支持单独的 `f`**) // // ⚠️ 求值走 `thread_local` 的单条缓存(按 `std::wstring` 的 data 指针 + 内容判定): // 绘制循环里同一条信号的样式对象是稳定的,因此每个信号只需编译一次; // **绝不能**每个采样点都重新解析(千万级采样会慢到不可用)。 #include namespace jdi { /** * @brief 校验公式文本是否可以解析。 * * 空文本是合法输入(表示"不做映射")。 * * @param [IN] text 公式文本(不含 `Y =` 前缀)。 * @param [OUT] error 解析失败时的原因(成功时清空),允许为空。 * @return 语法合法返回 true。 */ bool ValidateFormula(const std::wstring& text, std::wstring* error); /** * @brief 计算公式在给定采样值处的取值。 * * 文本为空或无法解析时**原样返回** `x`(保证绘制不会因为非法公式而消失)。 * 计算结果非有限(如 1/0)时返回 NaN(保持断线语义)。 * * @param [IN] text 公式文本。 * @param [IN] x 采样值(公式中的 `f(t)` / `X`)。 * @return 映射后的值。 */ double EvaluateFormula(const std::wstring& text, double x); /** * @brief 把用户输入里的自变量写法统一成 `f(t)`、常量统一为小写(保存前调用)。 * * 规则: * * 把独立的 `X` / `x` / `f(t)`(含 `F(T)`)记号改写为 `f(t)`; * * 把 `E` / `Pi` / `PI` 等写法改写为小写 `e` / `pi`; * * **单独的 `f` 不改写**(它不是合法写法,留给校验报错)。 * * 只做记号级替换(不会动标识符中间或数字里的字符,如 `1e5` 保持不变)。 * * @param [IN] text 用户输入的公式。 * @return 归一化后的文本。 */ std::wstring NormalizeFormulaText(const std::wstring& text); } // namespace jdi #endif // __FORMULA_EVAL_HPP__