使用 Go 實現的數學表達式解析計算引擎,無任何依賴,相對比較完整的完成了數學表達式解析執行,包括詞法分析、語法分析、構建AST、運行。
能夠處理的表達式樣例:
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)DemoMethod 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 = 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 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 onefunc 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.61+2*6/4+(456-8*9.2)-(2+4^5) = -639.6
TrigonometricMode三角函數的參數類型默認為弧度RadianMode,e.g. sin(pi/2) = 1.
你可以通過設置 TrigonometricMode 調整參數類型,可選 弧度RadianMode、角度AngleMode,e.g. :
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.TrigonometricMode = engine.RadianMode engine.ParseAndExec(s) // will return 2, nil}
Documentgodoc.org/github.com/dengsgo/math-engine/engine
Compilego version 1.12
# Compile Demogo testgo build./math-engine
也可以直接下載已編譯好的二進位文件,直接運行:
Github Releases
實現細節請閱讀我的博客文章:用 Go 實現一個完整的數學表達式計算引擎
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 友好的錯誤消息 e.g.input /> 123+89-0.0.9ERROR: strconv.ParseFloat: parsing "0.0.9": invalid syntaxwant '(' or '0-9' but get '0.0.9'--123+89-0.0.9 ^--
待實現