使用 Go 實現的數學表達式微型計算引擎,無任何依賴,相對比較完整的完成了數學表達式解析執行,包括詞法分析、語法分析、構建AST、運行。
TODO
已實現
- 加 +
- 減 -
- 乘 *
- 除 /
- 取余 %
- 整數次方 ^
- 科學計數法 e.g. 1.2e7
- 括號 ()
- 混合運算 e.g. 1+26/4+(456_-_89.2)-(2+4^5)
- 友好的長數字 e.g. 123_456_789
- 友好的錯誤消息 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
^
------------
待實現
- 科學計數法 e.g. 1.2-e7
- 精確的浮點計算
Usage
你可以直接引用該庫嵌入到自己的程序中:
go get -u github.com/dengsgo/math-engine
在代碼中引入:
import "github.com/dengsgo/math-engine/engine"
e.g. :
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
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
Compile
go version 1.12
go test go build ./math-engine
也可以直接下載已編譯好的二進制文件,直接運行:
實現細節
請閱讀我的博客文章:用 Go 實現一個完整的數學表達式計算引擎
