在Go中评估公式

时间:2014-05-28 23:18:26

标签: go

使用Go(golang)我想带一个带有公式的字符串并使用预定义的值进行评估。以下是使用python' parser模块的方法:

x = 8
code = parser.expr("(x + 2) / 10").compile()
print eval(code)
# prints 1

知道怎么用Go做这件事吗?

9 个答案:

答案 0 :(得分:10)

您可能需要求助于解释数学语句的库或者必须编写自己的解析器。 Python是一种动态语言,可以在运行时解析和执行python代码。标准围棋不能那样做。

如果您想自己编写解析器,那么go包将会有所帮助。示例(On play):

import (
    "go/ast"
    "go/parser"
    "go/token"
)

func main() {
    fs := token.NewFileSet()
    tr, _ := parser.ParseExpr("(3-1) * 5")
    ast.Print(fs, tr)
}

然后可以根据您的选择遍历和解释生成的AST(抽象语法树)(例如,处理'+'标记作为现在存储的值的添加)。

答案 1 :(得分:4)

我使用Djikstra's Shunting Yard Algorithm制作了自己的等式评估器。 它支持所有运算符,嵌套括号,函数甚至用户定义的变量。

它是用纯go

编写的

https://github.com/marcmak/calc

答案 2 :(得分:4)

此套餐可能会满足您的需求:https://github.com/Knetic/govaluate

expression, err := govaluate.NewEvaluableExpression("(x + 2) / 10");

parameters := make(map[string]interface{}, 8)
parameters["x"] = 8;

result, err := expression.Evaluate(parameters);

答案 3 :(得分:1)

Go中没有这样的模块。你必须建立自己的。您可以使用go包的子包,但它们对您的应用程序可能过度。

答案 4 :(得分:1)

对于表达式或程序评估,您可以使用lex和yacc构建词法分析器和解析器,并准确指定迷你语言的语法和语义。计算器一直是标准的yacc示例,而lex和yacc的go版本也没有区别。

这是一个指向计算示例的指针:https://github.com/golang-samples/yacc/tree/master/simple

答案 5 :(得分:0)

没有任何内置可以做到这一点(记住,Go不是动态语言)。

但是,您始终可以使用bufio.Scanner并构建自己的解析器。

答案 6 :(得分:0)

在谷歌上搜索我发现:https://github.com/sbinet/go-eval

它似乎是Go的一个eval循环。

go get github.com/sbinet/go-eval/cmd/go-eval
go install github.com/sbinet/go-eval/cmd/go-eval
go-eval

答案 7 :(得分:0)

使用此 code,您可以动态评估任何公式并返回 true 或 false:

package main

import (
    "go/token"
    "go/types"
)

func main() {
    fs := token.NewFileSet()
    tv, err := types.Eval(fs, nil, token.NoPos, "(1 + 4) >= 5")
    if err != nil {
        panic(err)
    }
    println(tv.Value.String())
}

答案 8 :(得分:0)

go-exprtk 包可能会满足您动态评估任何类型数学表达式的各种需求。

package main

import (
    "fmt"

    "github.com/Pramod-Devireddy/go-exprtk"
)

func main() {
    exprtkObj := exprtk.NewExprtk()

    exprtkObj.SetExpression("(x + 2) / 10")

    exprtkObj.AddDoubleVariable("x")

    exprtkObj.CompileExpression()
    
    exprtkObj.SetDoubleVariableValue("x", 8)

    fmt.Println(exprtkObj.GetEvaluatedValue())
}

这个包有很多capabilities