jlhonora
jlhonora

Reputation: 10709

Evaluate formula in Go

Using Go (golang) I'd like to take a string with a formula and evaluate it with pre-defined values. Here's a way to do it with python's parser module:

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

Any idea how to do it with Go?

Upvotes: 27

Views: 24778

Answers (10)

Anton Medvedev
Anton Medvedev

Reputation: 3668

This package also a good fit https://github.com/antonmedv/expr

// Allow only admins and moderators to moderate comments.
user.Group in ["admin", "moderator"] || user.Id == comment.UserId


// Ensure all tweets are less than 240 characters.
all(Tweets, .Size <= 240)

Expr is a safe, fast, and intuitive expression evaluator optimized for the Go language. Here are its standout features:

  • Memory-Safe
  • Side-Effect-Free
  • Always Terminating
  • Seamless with Go
  • Static Typing
  • Optimized for Speed

Upvotes: 0

Pramod
Pramod

Reputation: 351

go-exprtk package will probably meet all kinds of your needs to evaluate any kind of mathematical expression dynamically.

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())
}

This package has many capabilities

Upvotes: 7

Nicola Strappazzon
Nicola Strappazzon

Reputation: 129

With this code you can evaluate dynamically any formula and return true or 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())
}

Upvotes: 2

swill
swill

Reputation: 2077

This package will probably work for your needs: 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);

Upvotes: 19

Zan Lynx
Zan Lynx

Reputation: 54355

Googling around I found this: https://github.com/sbinet/go-eval

It appears to be an eval loop for Go.

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

Upvotes: 0

Marc
Marc

Reputation: 1820

I have made my own equation evaluator, using Djikstra's Shunting Yard Algorithm. It supports all operators, nested parenthesis, functions and even user defined variables.

It is written in pure go

https://github.com/marcmak/calc

Upvotes: 4

Paul Hankin
Paul Hankin

Reputation: 58339

For expression or program evaluation, you can build a lexer and parser using lex and yacc, and specify exactly the syntax and semantics of your mini-language. A calculator has always been a standard yacc example, and the go versions of lex and yacc are no different.

Here's a pointer to the calc example: https://github.com/golang-samples/yacc/tree/master/simple

Upvotes: 1

nemo
nemo

Reputation: 57739

You will probably need to resort to a library that interprets math statements or have to write your own parser. Python being a dynamic language can parse and execute python code at runtime. Standard Go cannot do that.

If you want to write a parser on your own, the go package will be of help. Example (On play):

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

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

The resulting AST (Abstract Syntax Tree) can then be traversed and interpreted as you choose (handling '+' tokens as addition for the now stored values, for example).

Upvotes: 16

OneOfOne
OneOfOne

Reputation: 99351

There's nothing built in that could do that (remember, Go is not a dynamic language).

However, you can always use bufio.Scanner and build your own parser.

Upvotes: 1

fuz
fuz

Reputation: 93117

There is no such module in Go. You have to build your own. You could use subpackages of the go package, but they might be overkill for your application.

Upvotes: 1

Related Questions