arithmetic

Extensible arithmetic parsing lib for go

Github星跟踪图

Arithmetic parser

Godoc
license

This library parses and solves a mathematical expression.

It uses a Shunting-Yard algorithm (aka Reverse-Polish notation).

Usual mathematic constants and functions are defined in this package (see doc).
Additional can be defined using the functions RegisterVariable and RegisterFunction.

Getting started

	package main

	import(
		"fmt"
		
		"github.com/moxar/arithmetic"
	)

	func main() {
		
		v, err := arithmetic.Parse("2+3")
		if err != nil {
			// ...
		}
		
		fmt.Println(v) // print 5
	}

This snippet is a very simple usage example of the arithmetic package.

Built-in

The following operators, variables and functions are supported by the package. Note that the inputs
of the Parse method are not case sensitive.

Operators

The package supports the following operators:

* +  (sum)
* -  (difference)
* /  (quotient)
* x  (product)
* %  (modulo). Note: modulo requires both operand to be integer
* >  (greater)
* >= (greater or equal)
* == (equal)
* <= (lower or equal)
* <  (lower)
* != (different)
* && (and). Note: "and" is an alias to "&&"
*, (or). Note: "or" is an alias to ", "
* !  (not). Note: "not" is an alias to "!"

Variables

The package supports the following variables from the math package:

* e
* pi
* phi

* sqrt2
* sqrte
* sqrtpi
* sqrtphi

* ln2
* ln2e
* ln10
* log10e

Additionnaly, it supports the boolean true and false.

Functions

The package supports the following functions:

* max(a, b, c...). Note: Max only supports float, but can use any number of arguments.
* min(a, b, c...). Note: Min only supports float, but can use any number of arguments.
* mean(a, b, c...). Note: Mean only supports float, but can use any number of arguments.
* if(condition, success, failure).

Extension

The package can be extended. You can add variable, functions or expression to be automaticaly recognized by the parser. The extension is made possible by the RegisterXXX functions, which works in a similar way than the sql drivers. The functions will panic if there is a conflict between the name of the newly defined variable/function and an existing one.

Variable

A variable is a mapping from a string to a value. In this example, when the parser detects
"dayInYear", it converts it to 365.

	package main
	
	import "github.com/moxar/arithmetic"

	func init() {
		arithmetic.RegisterVariable("dayInYear", 365)
	}
	
	func main() {
		
		v, err := arithmetic.Parse("dayInYear * 2")
		if err != nil {
			// ...
		}
		
		fmt.Println(v) 
		
		// Output: 730
	}

Function

A function is a mapping from a string to a function that returns a value. In this example, when the parser detects "contains", it checks if the second argument is contained within the first one.

	package main
	
	import (
		"fmt"
	
		"github.com/moxar/arithmetic"
	)

	func init() {

		// Register a new function, that increments the value by one.
		arithmetic.RegisterFunction("increment", func(args ...interface{}) (interface{}, error) {
			if len(args) != 1 {
				return nil, fmt.Errorf("increment requires one argument, %d provided", len(args))
			}

			f, ok := arithmetic.ToFloat(args[0])
			if !ok {
				return nil, fmt.Errorf("increment requires integer argument, %v (%T) provided", args[0], args[0])
			}

			return int(f) + 1, nil
		})
	}
	
	func main() {

		v, err := Parse("increment(2)")
		if err != nil {
			// ...
		}

		fmt.Println(v)
		// Output: 3
	}

Expression

An expression is a function that transforms an input to a value. The boolean tells whether the input could be transformed or not. Because the expressions are tested in an undefined order, you have to ensure there is no overlap between them.

	package main
	
	import (
		"fmt"
		"strings"
	
		"github.com/moxar/arithmetic"
	)

	func init() {
		arithmetic.RegisterExpression(foo)
	}
	
	func foo(input string) (interface{}, bool) {
		if len(input) == 0 {
			return nil, false
		}

		if input[0] != 'f' {
			return nil, false
		}
		

		for i, r := range input {
		
			if r != 'o' {
				return nil, false
			}
		}

		return true, true
	})
	
	func main() {

		v, err := arithmetic.Parse("fooOOoOoooOOOooOo && true")
		if err != nil {
			// ...
		}

		fmt.Println(v) 
		// Output: true
	}

Disclaimer

This lib is still at early development stages. The API is most likely susceptible to change.

主要指标

概览
名称与所有者MichaelS11/go-tetris
主编程语言Go
编程语言Go (语言数: 2)
平台
许可证Other
所有者活动
创建于2017-03-27 20:05:22
推送于2021-08-23 09:48:31
最后一次提交2021-08-23 17:48:31
发布数0
用户参与
星数77
关注者数3
派生数6
提交数24
已启用问题?
问题数0
打开的问题数0
拉请求数1
打开的拉请求数0
关闭的拉请求数0
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?