Skip to content

ydog01/cxx_eval

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 

Repository files navigation

主要功能

1. 基本算术运算
2. 自定义函数
3. 变量系统
4. 运算符优先级
5. 前缀/中缀/后缀运算符
6. 常量定义
7. 复数运算

功能特性

  • 核心特性
    • 支持自定义类型:运行自己编写规则
    • 支持实数类型:float/double/long double
    • 复数运算支持:std::complex<T>
    • 动态符号管理:前缀树存储变量、函数和运算符
    • 运算符优先级自动处理
  • 扩展能力
    • 自定义函数、运算符和变量
    • 自由变量与托管变量分离管理
    • 支持多参数函数(如atan2, log)

快速开始

实数计算示例

#include "eval_init.hpp"
int main() 
{
  auto calc = eval_init::create_real_eval<double>();
  auto expr = calc.parse("64 + sqrt(16) * sin(pi/2)");
  double result = calc.evaluate(expr); // 结果:64 + 4*1 = 68
}

复数计算示例

#include "eval_init_complex.hpp"
int main() 
{
  auto c_calc = eval_init::create_complex_eval<double>();
  c_calc.vars->insert("z", std::complex<double>(1, 2));
  auto expr = c_calc.parse("z * e^(i*pi) + conj(3+4i)");
  auto result = c_calc.evaluate(expr); // 结果:(-1-2i) + (3-4i) = 2-6i
}

核心类说明

类名功能关键成员
sstree<C,T>前缀树符号表insert(), search(), erase()
evaluator<C,T>表达式解析器parse(), evaluate()
epre<T>表达式中间表示funcs, vars, index

表达式语法

类别语法示例说明
基本运算3 + 5 * (2 - x)支持嵌套括号
函数调用sin(pi/2)必须使用括号
复数运算(2+3i) * 4i虚数单位用i后缀

自定义扩展

1. 添加自定义函数

eval::func<double> custom_op
{
  2,              // 参数个数
  eval::size_max, // 最高优先级
  [](const double* args) { return args[0] + std::exp(args[1]); }
};
calc.funcs->insert("custom", custom_op);

2. 注册变量

// 托管变量(值存储)
calc.vars->insert("PI", 3.1415926);

// 自由变量(指针绑定) double x = 2.0; calc.vars->insert("x", &x);

错误处理

  • 语法错误:未闭合括号时抛出size_t指明错误下标
  • 符号未定义:未注册变量返回nullptr
  • 运算错误:抛出std::runtime_error指明错误原因
try 
{ 
  auto expr = calc.parse("2 + * 3");
} 
catch (const std::runtime_error& e) 
{ 
  std::cerr << "解析错误: " << e.what(); 
}

性能优化建议

  • 表达式重用:多次计算时保留epre对象
// 预编译表达式
auto expr = calc.parse("x^2 + y^2"); 
for (int i=0; i<1000; i++) 
{ 
  x = i; 
  y = i+1; 
  double result = calc.evaluate(expr); // 避免重复解析 
}

关键注意事项

  • 本项目仅需要标准的cxx_11标准并包含头即可使用
  • 函数参数分隔符必须使用英文逗号

高级特性示例

自定义运算符优先级

eval::func<double> mod_op{
  2, 4, 
  [](auto args) { return f(args[0], args[1]); }
};
calc.infix_ops->insert("&", mod_op); // 设置运算优先级为4的中缀运算符

About

基于逆波兰序的拓展版表达式求值

Topics

Resources

Stars

Watchers

Forks

Languages