texpr

package module
v1.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2020 License: Apache-2.0 Imports: 9 Imported by: 0

README

TExpr

Build Status Coverage status

Go语言布尔及数值运算表达式解析器

Java语言版本

布尔表达式:

$country in ['cn', 'us', 'jp'] && $length > 100
$host == 'cs.qa.com' && 'Webkit' not in $ua

数值运算表达式:

( 1 ^ 5) + (2 << 3)
4 | 3 + 3

Example

package main

import (
	"fmt"
	"log"

	"github.com/aliyun/texpr"
)

type context map[string]interface{}

func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}

func main() {
	m := context {
		"$value" : 15.0,
	}
	expr := texpr.MustCompile("$value - 10")
	v, err := expr.Eval(m)
	if err != nil {
		log.Fatalf("expression err, %s", err)
	}
	fmt.Println(v) // 5
}

表达式语法

标量变量

类型 范例 说明
字符串 'hello' , "world" 字符串可以用单引号或双引号
整数 1,3,64
浮点数 1.1, 3.14
布尔值 true/false
变量 $name, @meta 变量名必须用$或@作为前缀.
数组 ["hello", "world"] 数组元素的类型可以是上面5种类型中的一种

数值计算

操作符 描述 例子
+ 1+1=2
- 2-1=1
* 2*2=4
/ 2/2=1
% 取余 5/2=1
& 位与 33&44=34
| 位或 33|44=45
^ 异或 33|44=13
<< 左位移 1 << 3 = 8
>> 右位移 16 >> 3 = 2

布尔计算

关系运算符
操作符 描述 例子
== 两值相等 A==B
> 左值大于右值 A>B
< 右值大于左值 A<B
>= 左值大于等于右值 A>=B
<= 右值大于等于左值 A<=B

左值和右值必须为同类型

逻辑运算符
操作符 描述 例子
&& 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 A && B
|| 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 A || B
not 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 not(A && B)
包含表达式
操作符 描述 例子
in 判断左值是否被包含在右值中,右值为数组类型 A in [A, B, C, D]
in 判断左值是否被包含在右值中,左值右值都是字符串或字符串类型变量 A in B

example

$name in ['John', 'Mary', "Jackson"]
'world' in 'hello world'
正则匹配
操作符 描述 例子
=~ 判断左值是匹配右值,右值是正则表达式 'world' =~ /.+orl.+/

正则表达式首尾需要用'/'包含

IS 判断
操作符 描述 例子
is 判断左值是否是右值代表的类型 A is empty
is not 判断左值是否不是右值代表的类型 A is not null

支持的类型如下

名称 描述 例子
string 字符串 A is string
integer 整数 A is integer
float 浮点数 A is float
boolean 布尔值 A is boolean && not A
host 主机名 A is host
ip4 ipv4地址 A is ip4
empty null、空字符、空数组 A is not empty
null null A is not null

范例

$name is string
$nil is null
'192.168.1.1' is ip4

函数运算

表达式函数

当前版本内置了一个函数'eval', 用来解析运算变量中的表达式, 范例:

// $expr = "$left + $right"
type context map[string]interface{}
func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}


m := context {
		"$left" : 2.0,
		"$right" : 3.0,
		"$ex" : "$left + $right"
}

expr, err := t.Compile("eval($ex)")

v, _ := expr.Eval(m)
// v == 5.0
自定义函数

可以在程序中自定义扩展函数, 只需要两个步骤

  1. 定义一个结构体, 实现Function接口
  2. 定义一个结构体变量并注册.

下面是自定义has_prefix函数的范例


type HasPrefixFunc struct {
	Function
}

func (f *HasPrefixFunc) Name() string {
	return "has_prefix"
}

func (f *HasPrefixFunc) Execute(vg ValueGetter, params []interface{}) (interface{}, error) {
	if len(params) != 2 {
		return nil, fmt.Errorf(`HasPrefixFunc() takes exactly 2 argument (" + %d + " given)`, len(params))
	}
	return strings.HasPrefix(params[0].(string), params[1].(string)), nil
}

func main() {
  RegisterFunc(&HasPrefixFunc{})
	...
}

Development

简单表达式计算
import (
	"fmt"
	"log"
	"os"

	t "github.com/aliyun/texpr"
)

func main() {
    input := "99 in "33 > 22 && 22 > 11"
	expr, err := t.Compile(input)

	if err != nil {
		log.Fatalf("expression err, %s", os.Args[1])
	}
	v, err := expr.Eval(nil)
	fmt.Println(v)
}
带有变量的表达式计算

表达式中可以带有变量,表达式中的变量必须以'$'或者'@'开头,如:

// 定义一个类型, 实现Get(string)interface{} 接口
type context map[string]interface{}
func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}

expr, err := t.Compile("($value - 10) / @meta")

m := context {
		"$value" : 15.0,
		"@meta" : 9.0,
}

v, err := expr.Eval(m)
if err != nil {
log.Fatalf("expression err, %s", err)
}

其中 expr.Eval() 的参数m,必须实现下面的interface

type ValueGetter interface {
	Get(name string) interface{}
}

在执行时,解释器会调用参数的Get方法取得表达式中变量的值,详细实现可以参考范例 test/variable/main.go

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ListContainsValue

func ListContainsValue(val interface{}, array []interface{}, typ reflect.Type) bool

func RegisterFunc added in v1.0.8

func RegisterFunc(f Function)

Types

type ArrayExpr

type ArrayExpr struct {
	Array []Expression
	Type  reflect.Type
}

func (*ArrayExpr) Eval

func (e *ArrayExpr) Eval(vg ValueGetter) (interface{}, error)

func (*ArrayExpr) String

func (e *ArrayExpr) String() string

type BiExpr

type BiExpr struct {
	// contains filtered or unexported fields
}

func (*BiExpr) Eval

func (e *BiExpr) Eval(vg ValueGetter) (interface{}, error)

func (*BiExpr) String

func (e *BiExpr) String() string

type EvalFunc added in v1.0.8

type EvalFunc struct {
	Function
}

func (*EvalFunc) Execute added in v1.0.8

func (f *EvalFunc) Execute(vg ValueGetter, params []interface{}) (interface{}, error)

func (*EvalFunc) Name added in v1.0.8

func (f *EvalFunc) Name() string

type Expression

type Expression interface {
	Eval(vg ValueGetter) (interface{}, error)
	String() string
}

func Compile

func Compile(expr string) (Expression, error)

func MustCompile

func MustCompile(expr string) Expression

func NewBiBoolExpr

func NewBiBoolExpr(left, right Expression, op *OP) Expression

func NewBiCalcExpr

func NewBiCalcExpr(left, right Expression, op *OP) Expression

func NewMatchExpr

func NewMatchExpr(left Expression, regex string) (Expression, error)

type FuncExpr added in v1.0.8

type FuncExpr struct {
	// contains filtered or unexported fields
}

func NewFuncExpr added in v1.0.8

func NewFuncExpr(name string, function Function, params []Expression) *FuncExpr

func (*FuncExpr) Eval added in v1.0.8

func (e *FuncExpr) Eval(vg ValueGetter) (interface{}, error)

func (*FuncExpr) String added in v1.0.8

func (e *FuncExpr) String() string

type Function added in v1.0.8

type Function interface {
	Execute(vg ValueGetter, params []interface{}) (interface{}, error)
	Name() string
}

type InExpr

type InExpr struct {
	// contains filtered or unexported fields
}

func (*InExpr) Eval

func (e *InExpr) Eval(vg ValueGetter) (interface{}, error)

func (*InExpr) String

func (e *InExpr) String() string

type IsTypeExpr

type IsTypeExpr struct {
	// contains filtered or unexported fields
}

func (*IsTypeExpr) Eval

func (e *IsTypeExpr) Eval(vg ValueGetter) (interface{}, error)

func (*IsTypeExpr) String

func (e *IsTypeExpr) String() string

type MatchExpr

type MatchExpr struct {
	// contains filtered or unexported fields
}

func (*MatchExpr) Eval

func (e *MatchExpr) Eval(vg ValueGetter) (interface{}, error)

func (*MatchExpr) String

func (e *MatchExpr) String() string

type NotExpr

type NotExpr struct {
	// contains filtered or unexported fields
}

func (*NotExpr) Eval

func (e *NotExpr) Eval(vg ValueGetter) (interface{}, error)

func (*NotExpr) String

func (e *NotExpr) String() string

type OP

type OP struct {
	Symbol string
	Func   opFunc
}

func NewOP

func NewOP(symbol string, fun opFunc) *OP

func (*OP) Eval

func (op *OP) Eval(left, right interface{}) (interface{}, error)

type TExprParserVisitor added in v1.0.8

type TExprParserVisitor struct {
	ast.TExprParserVisitor
}

func (*TExprParserVisitor) VisitArray added in v1.0.8

func (v *TExprParserVisitor) VisitArray(ctx *ast.ArrayContext) interface{}

func (*TExprParserVisitor) VisitAtom added in v1.0.8

func (v *TExprParserVisitor) VisitAtom(ctx *ast.AtomContext) interface{}

func (*TExprParserVisitor) VisitBinary added in v1.0.8

func (v *TExprParserVisitor) VisitBinary(ctx *ast.BinaryContext) interface{}

func (*TExprParserVisitor) VisitBinaryExpression added in v1.0.8

func (v *TExprParserVisitor) VisitBinaryExpression(ctx *ast.BinaryExpressionContext) interface{}

func (*TExprParserVisitor) VisitBit added in v1.0.8

func (v *TExprParserVisitor) VisitBit(ctx *ast.BitContext) interface{}

func (*TExprParserVisitor) VisitBoolean added in v1.0.8

func (v *TExprParserVisitor) VisitBoolean(ctx *ast.BooleanContext) interface{}

func (*TExprParserVisitor) VisitBooleans added in v1.0.8

func (v *TExprParserVisitor) VisitBooleans(ctx *ast.BooleansContext) interface{}

func (*TExprParserVisitor) VisitCalc added in v1.0.8

func (v *TExprParserVisitor) VisitCalc(ctx *ast.CalcContext) interface{}

func (*TExprParserVisitor) VisitCalcExpression added in v1.0.8

func (v *TExprParserVisitor) VisitCalcExpression(ctx *ast.CalcExpressionContext) interface{}

func (*TExprParserVisitor) VisitComparator added in v1.0.8

func (v *TExprParserVisitor) VisitComparator(ctx *ast.ComparatorContext) interface{}

func (*TExprParserVisitor) VisitComparatorExpression added in v1.0.8

func (v *TExprParserVisitor) VisitComparatorExpression(ctx *ast.ComparatorExpressionContext) interface{}

func (*TExprParserVisitor) VisitContainer added in v1.0.8

func (v *TExprParserVisitor) VisitContainer(ctx *ast.ContainerContext) interface{}

func (*TExprParserVisitor) VisitFloats added in v1.0.8

func (v *TExprParserVisitor) VisitFloats(ctx *ast.FloatsContext) interface{}

func (*TExprParserVisitor) VisitFuncname added in v1.0.8

func (v *TExprParserVisitor) VisitFuncname(ctx *ast.FuncnameContext) interface{}

func (*TExprParserVisitor) VisitFunction added in v1.0.8

func (v *TExprParserVisitor) VisitFunction(ctx *ast.FunctionContext) interface{}

func (*TExprParserVisitor) VisitInExpression added in v1.0.8

func (v *TExprParserVisitor) VisitInExpression(ctx *ast.InExpressionContext) interface{}

func (*TExprParserVisitor) VisitIntegers added in v1.0.8

func (v *TExprParserVisitor) VisitIntegers(ctx *ast.IntegersContext) interface{}

func (*TExprParserVisitor) VisitIsNotTypeExpression added in v1.0.8

func (v *TExprParserVisitor) VisitIsNotTypeExpression(ctx *ast.IsNotTypeExpressionContext) interface{}

func (*TExprParserVisitor) VisitIsTypeExpression added in v1.0.8

func (v *TExprParserVisitor) VisitIsTypeExpression(ctx *ast.IsTypeExpressionContext) interface{}

func (*TExprParserVisitor) VisitKind added in v1.0.8

func (v *TExprParserVisitor) VisitKind(ctx *ast.KindContext) interface{}

func (*TExprParserVisitor) VisitLiteral added in v1.0.8

func (v *TExprParserVisitor) VisitLiteral(ctx *ast.LiteralContext) interface{}

func (*TExprParserVisitor) VisitMatchExpression added in v1.0.8

func (v *TExprParserVisitor) VisitMatchExpression(ctx *ast.MatchExpressionContext) interface{}

func (*TExprParserVisitor) VisitMultiplying added in v1.0.8

func (v *TExprParserVisitor) VisitMultiplying(ctx *ast.MultiplyingContext) interface{}

func (*TExprParserVisitor) VisitNotExpression added in v1.0.8

func (v *TExprParserVisitor) VisitNotExpression(ctx *ast.NotExpressionContext) interface{}

func (*TExprParserVisitor) VisitNotInExpression added in v1.0.8

func (v *TExprParserVisitor) VisitNotInExpression(ctx *ast.NotInExpressionContext) interface{}

func (*TExprParserVisitor) VisitNumber added in v1.0.8

func (v *TExprParserVisitor) VisitNumber(ctx *ast.NumberContext) interface{}

func (*TExprParserVisitor) VisitParameters added in v1.0.8

func (v *TExprParserVisitor) VisitParameters(ctx *ast.ParametersContext) interface{}

func (*TExprParserVisitor) VisitParenExpression added in v1.0.8

func (v *TExprParserVisitor) VisitParenExpression(ctx *ast.ParenExpressionContext) interface{}

func (*TExprParserVisitor) VisitParse added in v1.0.8

func (v *TExprParserVisitor) VisitParse(ctx *ast.ParseContext) interface{}

func (*TExprParserVisitor) VisitPlus added in v1.0.8

func (v *TExprParserVisitor) VisitPlus(ctx *ast.PlusContext) interface{}

func (*TExprParserVisitor) VisitRegex added in v1.0.8

func (v *TExprParserVisitor) VisitRegex(ctx *ast.RegexContext) interface{}

func (*TExprParserVisitor) VisitScientific added in v1.0.8

func (v *TExprParserVisitor) VisitScientific(ctx *ast.ScientificContext) interface{}

func (*TExprParserVisitor) VisitShift added in v1.0.8

func (v *TExprParserVisitor) VisitShift(ctx *ast.ShiftContext) interface{}

func (*TExprParserVisitor) VisitStrings added in v1.0.8

func (v *TExprParserVisitor) VisitStrings(ctx *ast.StringsContext) interface{}

func (*TExprParserVisitor) VisitVariable added in v1.0.8

func (v *TExprParserVisitor) VisitVariable(ctx *ast.VariableContext) interface{}

func (*TExprParserVisitor) VisitVariableExpression added in v1.0.8

func (v *TExprParserVisitor) VisitVariableExpression(ctx *ast.VariableExpressionContext) interface{}

type ValueExpression

type ValueExpression struct {
	// contains filtered or unexported fields
}

func NewValueExpression

func NewValueExpression(value interface{}) *ValueExpression

func (*ValueExpression) Eval

func (e *ValueExpression) Eval(vg ValueGetter) (interface{}, error)

func (*ValueExpression) String

func (e *ValueExpression) String() string

type ValueGetter

type ValueGetter interface {
	Get(name string) interface{}
}

type VariableExpr

type VariableExpr struct {
	// contains filtered or unexported fields
}

func (*VariableExpr) Eval

func (e *VariableExpr) Eval(vg ValueGetter) (interface{}, error)

func (*VariableExpr) String

func (e *VariableExpr) String() string

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL