# Mathematical expression parsing and calculation engine library. 数学表达式解析计算引擎库

### Related tags

Compiler go library math engine vendor lib ast expression mathematical

## Math-Engine

`go get -u github.com/dengsgo/math-engine`

• `1+127-21+(3-4)*6/2.5`
• `(88+(1+8)*6)/2+99`
• `123_345_456 * 1.5 - 2 ^ 4`
• `-4 * 6 + 2e2 - 1.6e-3`
• `sin(pi/2)+cos(45-45*1)+tan(pi/4)`
• `99+abs(-1)-ceil(88.8)+floor(88.8)`
• `max(min(2^3, 3^2), 10*1.5-7)`
• `double(6) + 3` , `double`是一个自定义的函数

## Method Support

symbol explanation e.g.
`+` 加，plus 1+2 = 3
`-` 减，sub 8-3.5 = 4.5
`*` 乘，multiply 2*3 = 6
`/` 除，division 5/2 = 2.5
`%` 取余，remainder 5%2 = 1
`^` 整数次方，integer power 2^3 = 8, 3^2 = 9
`e` 科学计数法，E-notation 1.2e3 = 1.2e+3 = 1200，1.2e-2 = 0.012
`()` 括号，brackets (2+3)*4 = 20
`_` 数字分隔符，number separator 123_456_789 = 123456789
`pi` π pi = 3.141592653589793
`sin(x)` 正弦函数，sine sin(pi/2) = 1
`cos(x)` 余弦函数，cosine cos(0) = 1
`tan(x)` 正切函数，tangent tan(pi/4) = 1
`cot(x)` 余切函数，cotangent cot(pi/4) = 1
`sec(x)` 正割函数，secant sec(0) = 1
`csc(x)` 余割函数，cosecant csc(pi/2) = 1
`abs(x)` 绝对值，absolute value abs(-6) = 6
`ceil(x)` 向上取整 ceil(4.2) = 5
`floor(x)` 向下取整 floor(4.8) = 4
`round(x)` 四舍五入取整 round(4.4) = 4, round(4.5) = 5
`sqrt(x)` 平方根，square root sqrt(4) = 2
`cbrt(x)` 立方根，cube root cbrt(27) = 3
`max(x, y)` x, y 中的较大值 max(2, 3) = 3
`min(x, y)` x, y 中的较小值 min(2, 3) = 2
`noerr(x)` 计算 x 出错时返回 0 noerr(1 / 1) = 1, noerr( 1/ 0 ) = 0
`double(x)` 返回 x 的双倍值，这是一个自定义的函数示例，你可以注册任意的自定义函数到引擎中 double(6) = 12

## Usage

`go get -u github.com/dengsgo/math-engine`

`import "github.com/dengsgo/math-engine/engine"`

e.g. 1 常规用法： 直接调用解析执行函数 :

```import "github.com/dengsgo/math-engine/engine"

func main() {
s := "1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)"
// call top level function
r, err := engine.ParseAndExec(s)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s = %v", s, r)
}```

e.g. 2 高级用法： 依次调用函数，手动执行 :

```import "github.com/dengsgo/math-engine/engine"

func main() {
s := "1 + 2 * 6 / 4 + (456 - 8 * 9.2) - (2 + 4 ^ 5)"
exec(s)
}

// call engine
// one by one
func exec(exp string) {
// input text -> []token
toks, err := engine.Parse(exp)
if err != nil {
fmt.Println("ERROR: " + err.Error())
return
}
// []token -> AST Tree
ast := engine.NewAST(toks, exp)
if ast.Err != nil {
fmt.Println("ERROR: " + ast.Err.Error())
return
}
// AST builder
ar := ast.ParseExpression()
if ast.Err != nil {
fmt.Println("ERROR: " + ast.Err.Error())
return
}
fmt.Printf("ExprAST: %+v\n", ar)
// AST traversal -> result
r := engine.ExprASTResult(ar)
fmt.Println("progressing ...\t", r)
fmt.Printf("%s = %v\n", exp, r)
}```

```ExprAST: {Op:- Lhs:{Op:+ Lhs:{Op:+ Lhs:{Val:1} Rhs:{Op:/ Lhs:{Op:* Lhs:{Val:2} Rhs:{Val:6}} Rhs:{Val:4}}} Rhs:{Op:- Lhs:{Val:456} Rhs:{Op:* Lhs:{Val:8} Rhs:{Val:9.2}}}} Rhs:{Op:+ Lhs:{Val:2} Rhs:{Op:^ Lhs:{Val:4} Rhs:{Val:5}}}}
progressing ...  -639.6
1+2*6/4+(456-8*9.2)-(2+4^5) = -639.6```

## TrigonometricMode

```import "github.com/dengsgo/math-engine/engine"

func main() {
s := "1 + sin(90)"
engine.TrigonometricMode = engine.AngleMode
engine.ParseAndExec(s) // will return 2, nil
s = "1 + sin(pi/2)"
engine.ParseAndExec(s) // will return 2, nil
}```

## Register Function

`math-engine` 提供了自定义函数注册到引擎的能力。你可以把常用的函数注册到引擎中，然后就能像内置函数一样在输入的数学表达式中使用。

e.g

```  // RegFunction is Top level function
// the same function name only needs to be registered once.
// double is register function name.
// 1 is a number of parameter signatures.
// func(expr ...engine.ExprAST) float64 is your function.
engine.RegFunction("double", 1, func(expr ...engine.ExprAST) float64 {
// you can use the index value directly according to the number of parameters
// without worrying about crossing the boundary.
// use ExprASTResult to get the result of the ExprAST structure.
return engine.ExprASTResult(expr[0]) * 2
})```

```//exp := "double(6) + 2"
r, err := engine.ParseAndExec("double(6) + 2")
if err != nil {
panic(err)
}
fmt.Printf("double(6) + 2 = %f\n", r) // will print ： double(6) + 2 = 14.000000```

• 注册的函数名只能是英文字母和数字，且必须英文字母开头（区分大小写）;
• 每一个函数名只能且只需注册一次；
• 注册的函数逻辑中如果有 panic ，需要程序自己捕获处理;

## Compile

go version 1.12

```# Compile Demo
go test
go build
./math-engine```

Github Releases

## TODO

### 已实现

• `+`
• `-`
• `*`
• `/`
• 取余 `%`
• 整数次方 `^`
• 科学计数法 e.g. `1.2e7``1.2e-7`
• 括号 `()`
• 混合运算 e.g. `1+2*6/4+(456-8*9.2)-(2+4^5)*2e3+1.2e-2`
• 友好的长数字 e.g. `123_456_789`
• 三角函数 e.g. `sin, cos, tan, cot, sec, csc`
• 常量 pi
• 辅助函数 e.g. `abs, ceil, floor, sqrt, cbrt, max, min, noerr`
• 提供自定义函数注册功能，注册后可以在表达式中使用
• 精确的数据计算
• 友好的错误消息 e.g.
```input /> 123+89-0.0.9
ERROR: strconv.ParseFloat: parsing "0.0.9": invalid syntax
want '(' or '0-9' but get '0.0.9'
------------
123+89-0.0.9
^
------------```
• #### V3.0 update: the top-level function ExprASTResult will have a panic error when a runtime error occurs

V3.0 update: the top-level function `ExprASTResult` will have a panic error when a runtime error occurs .

Most of the time you should use `ParseAndExec`, which automatically handles the errors that occur with `ExprASTResult` . Use recover to catch the panic if you really need to call `ExprASTResult` :

``````defer func() {
if e := recover(); e != nil {
// todo
}
}()
ExprASTResult(expr)
``````
break change
opened by dengsgo 4
• #### Proposal: Please start using Semantic Versioning

I found that this project already supports Go modules. But sadly, the [tags](https://github.com https://github.com/dengsgo/math-engine/tags) doesn't follow Semantic Versioning, which means that all tags of this project will be ignored by Go modules and replaced by pseudo-versions, go get acts weirdly when tags are not in that form. It would be great to have the tagged release be named in the format vX.X.X format so that go mod can read it.

``````	github.com/dengsgo/math-engine v0.0.0-20200627074419-8918d8f8ea02
``````

Else the mod file shows something like `github.com/dengsgo/math-engine v0.0.0-20200627074419-8918d8f8ea02` which is not very readable and difficult to upgrade. It’s hard to verify which version is in use. This is not conducive to version control.

So, I propose this project to follow Semantic Versioning in future versions. For example, `v1.0.1`, `v2.0.0`, `v3.1.0-alpha`, `v3.1.0-beta.2`etc, so that other project can use tag in go.mod.

opened by KateGo520 3
• #### 0.7* 表达式无效

``````package main

import (
"fmt"

"github.com/dengsgo/math-engine/engine"
)

func main() {
s := "0.7*"
// call top level function
r, err := engine.ParseAndExec(s)
if err != nil {
fmt.Println(err)
}

fmt.Println(r)
// 0.7
}
``````

类似 0.7- 、0.7+ 这种表达式也是无效吧。

bug
opened by jimyag 1
• #### 1-- panic

``````input /> 1--
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow

runtime stack:
runtime.throw(0x10d97b0, 0xe)
/usr/local/go/src/runtime/panic.go:617 +0x72
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1041 +0x6f0
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:429 +0x8f

goroutine 1 [running]:
github.com/dengsgo/math-engine/engine.(*AST).parsePrimary(0xc043fffdb0, 0x0, 0x0)
/Users/admin/go/pkg/mod/github.com/dengsgo/[email protected]/engine/ast.go:164 +0x85c fp=0xc0240003e8 sp=0xc0240003e0 pc=0x109ef4c
github.com/dengsgo/math-engine/engine.(*AST).parsePrimary(0xc043fffdb0, 0x0, 0x0)
``````
opened by xuanskyer 1
• #### 增加注册自定义函数的能力

可以把常用的函数注册到引擎中，然后就能像内置函数一样在输入的数学表达式中使用。

e.g

``````  engine.RegFunction("double", 1, func(expr ...engine.ExprAST) float64 {
return engine.ExprASTResult(expr[0]) * 2
})
``````

然后就可以在输入的表达式中使用这个函数 `double`:

``````exp := "double(6) + 2"
r, err := engine.ParseAndExec("double(6) + 2")
if err != nil {
panic(err)
}
fmt.Printf("double(6) + 2 = %f\n", r) // will print ： double(6) + 2 = 14.000000
``````
feature
opened by dengsgo 5

• #### v3.0(Oct 22, 2019)

``````# *Unix
chmod +x math-engine
./math-engine
# Windows
math-engine.exe
``````
• 增加 辅助函数 `noerr`, 该函数中的表达式计算出错时，返回 0
• 支持 常量 `pi`
• 支持 三角函数支持 `sin(), cos(), tan(), cot(), sec(), csc()`
• 支持 三角函数参数调整，可选 弧度`RadianMode`、角度`AngleMode`
• 支持 辅助函数 `abs(), ceil(), floor(), round(), sqrt(). cbrt(), max(), min()`
• 支持 godoc.org 支持
• 支持 顶级函数 `ParseAndExec`
• 支持 单元测试
• 支持 解析错误 e.g. `(((`
Source code(tar.gz)
Source code(zip)
math-engine-darwin(1.72 MB)
math-engine-linux(1.55 MB)
math-engine-windows.exe(1.62 MB)
• #### v2.0(Oct 22, 2019)

###### Deng.Liu
Back-end Engineer
###### Expression evaluation engine for Go: fast, non-Turing complete, dynamic typing, static typing

Expr Expr package provides an engine that can compile and evaluate expressions. An expression is a one-liner that returns a value (mostly, but not lim

3.3k Dec 30, 2022
###### Fast, portable, non-Turing complete expression evaluation with gradual typing (Go)

Common Expression Language The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, safety, and portabil

1.4k Dec 24, 2022
###### Expression evaluation in golang

Gval Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions. Evaluate Gval can evaluate expressio

563 Dec 27, 2022
###### Arbitrary expression evaluation for golang

govaluate Provides support for evaluating arbitrary C-like artithmetic/string expressions. Why can't you just write these expressions in code? Sometim

2.9k Jan 2, 2023
###### Logexp - Logical expression compiler for golang

Logical Expression Compiler Functions: - Compile(exp string) - Match(text string

1 Jan 24, 2022
###### ECMAScript/JavaScript engine in pure Go

goja ECMAScript 5.1(+) implementation in Go. Goja is an implementation of ECMAScript 5.1 in pure Go with emphasis on standard compliance and performan

3.5k Jan 1, 2023
###### Library for interacting with LLVM IR in pure Go.

llvm Library for interacting with LLVM IR in pure Go. Introduction Introductory blog post "LLVM IR and Go" Our Document Installation go get -u github.

995 Dec 24, 2022
###### A parser library for Go

A dead simple parser package for Go V2 Introduction Tutorial Tag syntax Overview Grammar syntax Capturing Capturing boolean value Streaming Lexing Sta

2.8k Dec 30, 2022
###### Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. https://vlang.io

The V Programming Language vlang.io | Docs | Changelog | Speed | Contributing & compiler design Key Features of V Simplicity: the language can be lear

31.1k Jan 4, 2023
###### Promise to the Go compiler that your Reads and Writes are well-behaved

noescape go get lukechampine.com/noescape noescape provides Read and Write functions that do not heap-allocate their argument. Normally, when you pas

39 Dec 22, 2022
###### Go compiler for small places. Microcontrollers, WebAssembly, and command-line tools. Based on LLVM.

TinyGo - Go compiler for small places TinyGo is a Go compiler intended for use in small places such as microcontrollers, WebAssembly (Wasm), and comma

12.1k Jan 4, 2023
###### GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

5.2k Jan 9, 2023
###### A Lua 5.3 VM and compiler written in Go.

DCLua - Go Lua Compiler and VM: This is a Lua 5.3 VM and compiler written in Go. This is intended to allow easy embedding into Go programs, with minim

899 Dec 12, 2022
###### Grumpy is a Python to Go source code transcompiler and runtime.

Grumpy: Go running Python Overview Grumpy is a Python to Go source code transcompiler and runtime that is intended to be a near drop-in replacement fo

10.6k Jan 7, 2023
###### High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

6.9k Dec 30, 2022
###### Runcmd - just golang binary that runs commands from url or local file and logs output

runcmd just golang binary that runs commands from url or local file and logs out

0 Feb 2, 2022
###### Suan - Mathematical expression calculation tool

suan Suan( 算 ) is a CLI tool to calculate given mathematical expression. Current

1 Feb 14, 2022
###### A real-time `VWAP` (volume-weighted average price) calculation engine

VWAP Overview The goal of this project is to create a real-time VWAP (volume-weighted average price) calculation engine. For this was used the coinbas

0 Feb 11, 2022
###### Exp-tree: go library for parsing expression tree

Vinshop expression tree Exp-tree is go library for parsing expression tree Installation go get -u github.com/vinshop/exp-tree Quick start Format Expre

6 May 11, 2022
###### Peg, Parsing Expression Grammar, is an implementation of a Packrat parser generator.

PEG, an Implementation of a Packrat Parsing Expression Grammar in Go A Parsing Expression Grammar ( hence peg) is a way to create grammars similar in

886 Dec 31, 2022