├── .gitignore ├── README.MD ├── base ├── Arg.go ├── Args.go ├── ArgsHolder.go ├── Assignment.go ├── AtNameHolder.go ├── Constant.go ├── ConstantHolder.go ├── ElseStmt.go ├── Evaluator.go ├── Expression.go ├── ExpressionAtom.go ├── ExpressionAtomHolder.go ├── ExpressionHolder.go ├── FunctionCall.go ├── FunctionCallHolder.go ├── IfStmt.go ├── Initializer.go ├── IntegerHolder.go ├── KnowledgeContext.go ├── MathExpression.go ├── MathExpressionHolder.go ├── MethodCall.go ├── MethodCallHolder.go ├── RuleContent.go ├── RuleEntity.go ├── Statement.go ├── Statements.go ├── StatementsHolder.go ├── StringHolder.go └── VariableHolder.go ├── builder └── RuleBuilder.go ├── context └── DataContext.go ├── core ├── errors │ └── errors.go ├── execute.go └── math.go ├── define └── strconv.go ├── engine └── Gengine.go ├── iantlr ├── alr │ ├── gengine.interp │ ├── gengine.tokens │ ├── gengineLexer.interp │ ├── gengineLexer.tokens │ ├── gengine_base_listener.go │ ├── gengine_base_visitor.go │ ├── gengine_lexer.go │ ├── gengine_listener.go │ ├── gengine_parser.go │ └── gengine_visitor.go └── gengine.g4 ├── iparser ├── GengineErrorListener.go ├── GengineParserListener.go └── GenginePaserVistior.go └── test ├── AtName_test.go ├── Gengine_base_test.go ├── Gengine_salience_test.go ├── Grammar_test.go ├── MutliRules_test.go ├── complex ├── extends_test.go ├── father.go └── man.go ├── concurrent └── concurrent_test.go ├── rule.gengine └── struct_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Gengine [中文说明](#基于golang的规则引擎) 2 | 3 | ## the rule engine based on golang 4 | - this is a rule engine named **Gengine** based on golang and AST, it can help you to load your code(rules) to run while you did not need to restart your application. 5 | - Gengine's code structure is Modular design, logic is easy to understand, and it passed the necessary testing! 6 | - it is also a high performance engine 7 | 8 | ## Grammar support by Gengine 9 | - support the priority of the rules list and the priority scope is -int64 to int64 10 | - support rule's description 11 | - support define a local variable in a rule, and it invisible between rules 12 | - support 'if..else' and it's Nested structure 13 | - support complex logic operation 14 | - support complex Arithmetic (+ - * /) 15 | - support method of golang's structure 16 | - support single line comment(//) 17 | - support elegant check error, if there is an error in one rule, gengine will not load the rules to run to forbidden the harm to data 18 | - to make it easy to use,Gengine just supports one return value function's or method's Assignment and support return struct, but support call multi return value function 19 | - support directly inject function to run, and rename function 20 | - support switch to help user to decide when a rule execute error in the list whether continue to execute the last rules 21 | - support use '@name' to get rule's name in rule content 22 | 23 | ## Gengine not support grammar 24 | - not support 'else if', beacase the creator hates 'else if' 25 | - not support Multi-level call such as 'user.ip.ipRisk()',because it not meet the "Dimit rule", and multi-level call make it hard to understand, so it just support this call type: 'ip.ipRisk()' 26 | - not support multi line comment (/* comment */) 27 | - not support multi return value, if you want, you can use return struct 28 | - not support nil 29 | 30 | ## something need your attention 31 | - if you not declare the rules' priority, the rules will be execute in unknown sort 32 | - every rule's name should be different from each other 33 | 34 | 35 | ## support data type 36 | - string 37 | - bool 38 | - int, int8, int16, int32, int64 39 | - float32, float64 40 | 41 | ## support logic operation 42 | - && 43 | - || 44 | - ! 45 | 46 | ## support compared operation 47 | - == 48 | - != 49 | - \> 50 | - < 51 | - \>= 52 | - <= 53 | 54 | ## support math operation 55 | - \+ 56 | - \- 57 | - \* 58 | - / 59 | - support string and string's plus 60 | 61 | ## attention and in action 62 | - if you want get high performance, please do as the test case do: separate the rule build process and the rule execute process 63 | - when you rules contains Very time-consuming operation, such as operate database, you should use engine.ExecuteConcurrent(...), if not ,you should still use engine.Execute(...) 64 | 65 | ## Gengine rule example 66 | ```go 67 | //rule 68 | rule "测试" "测试描述" salience 0 69 | begin 70 | // rename function test; @name represent the rule name "测试" 71 | Sout(@name) 72 | // common function test 73 | Hello() 74 | //struct's method test 75 | User.Say() 76 | // if 77 | if !(7 == User.GetNum(7)) || !(7 > 8) { 78 | //define variable and string's plus; @name is just a string 79 | variable = "hello" + (" world" + "zeze")+"@name" 80 | // inner function 81 | User.Name = "hhh" + strconv.FormatBool(true) 82 | //struct's field 83 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 84 | //bool set test 85 | User.Male = false 86 | //use inner variable test 87 | User.Print(variable) 88 | //float test 89 | f = 9.56 90 | PrintReal(f) 91 | //if-else test 92 | if false { 93 | Sout("sout true") 94 | }else{ 95 | Sout("sout false") 96 | } 97 | }else{ //else 98 | //struct field set value test 99 | User.Name = "yyyy" 100 | } 101 | end 102 | ``` 103 | 104 | ## Gengine complete test 105 | - you can find all code in test package 106 | ```go 107 | 108 | import ( 109 | "fmt" 110 | "gengine/base" 111 | "gengine/builder" 112 | "gengine/context" 113 | "gengine/engine" 114 | "github.com/sirupsen/logrus" 115 | "testing" 116 | "time" 117 | ) 118 | 119 | type User struct { 120 | Name string 121 | Age int 122 | Male bool 123 | } 124 | 125 | func (u *User)GetNum(i int64) int64 { 126 | return i 127 | } 128 | 129 | func (u *User)Print(s string){ 130 | fmt.Println(s) 131 | } 132 | 133 | func (u *User)Say(){ 134 | fmt.Println("hello world") 135 | } 136 | 137 | const ( 138 | rule2 = ` 139 | rule "测试" "测试描述" salience 0 140 | begin 141 | // 重命名函数 测试 142 | Sout(@name) 143 | // 普通函数 测试 144 | Hello() 145 | //结构提方法 测试 146 | User.Say() 147 | // if 148 | if 7 == User.GetNum(7){ 149 | //自定义变量 和 加法 测试 150 | variable = "hello" + " world" 151 | // 加法 与 内建函数 测试 152 | User.Name = "hhh" + strconv.FormatBool(true) 153 | //结构体属性、方法调用 和 除法 测试 154 | User.Age = User.GetNum(89767999999) / 10000000 155 | //布尔值设置 测试 156 | User.Male = false 157 | //规则内自定义变量调用 测试 158 | User.Print(variable) 159 | //float测试 也支持科学计数法 160 | f = 9.56 161 | PrintReal(f) 162 | //嵌套if-else测试 163 | if false { 164 | Sout("嵌套if测试") 165 | }else{ 166 | Sout("嵌套else测试") 167 | } 168 | }else{ //else 169 | //字符串设置 测试 170 | User.Name = "yyyy" 171 | } 172 | end`) 173 | 174 | func Hello() { 175 | fmt.Println("hello") 176 | } 177 | 178 | func PrintReal(real float64){ 179 | fmt.Println(real) 180 | } 181 | 182 | func exe(user *User){ 183 | /** 184 | 不要注入除函数和结构体指针以外的其他类型(如变量) 185 | */ 186 | dataContext := context.NewDataContext() 187 | //注入结构体指针 188 | dataContext.Add("User", user) 189 | //重命名函数,并注入 190 | dataContext.Add("Sout",fmt.Println) 191 | //直接注入函数 192 | dataContext.Add("Hello",Hello) 193 | dataContext.Add("PrintReal",PrintReal) 194 | 195 | //初始化规则引擎 196 | knowledgeContext := base.NewKnowledgeContext() 197 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 198 | 199 | //读取规则 200 | err := ruleBuilder.BuildRuleFromString(rule2) 201 | if err != nil{ 202 | logrus.Errorf("err:%s ", err) 203 | }else{ 204 | eng := engine.NewGengine() 205 | 206 | start := time.Now().UnixNano() 207 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 208 | err := eng.Execute(ruleBuilder, true) 209 | end := time.Now().UnixNano() 210 | if err != nil{ 211 | logrus.Errorf("execute rule error: %v", err) 212 | } 213 | logrus.Infof("execute rule cost %d ns",end-start) 214 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 215 | } 216 | } 217 | 218 | func Test_Base(t *testing.T){ 219 | user := &User{ 220 | Name: "Calo", 221 | Age: 0, 222 | Male: true, 223 | } 224 | exe(user) 225 | } 226 | 227 | ``` 228 | 229 | ## Connection 230 | - renyunyi@bilibili.com 231 | 232 | ## Licence 233 | - MIT 234 | 235 | 236 | 237 | ## 基于golang的规则引擎 238 | - **Gengine**是一款基于AST(Abstract Syntax Tree)和golang语言实现的规则引擎。能够让你在golang这种静态语言上,在不停服务的情况下实现动态加载与配置规则。 239 | - **代码结构松散,逻辑极其简单,但经过了必要且详尽的测试** 240 | - Gengine所支持的规则,就是一门**DSL**(领域专用语言) 241 | 242 | ## Gengine支持的规则语法 243 | - 支持规则优先级和规则执行条件,优先级高的先执行,优先级低的后执行; 244 | - 支持的优先级范围 -int64 ~ int64 245 | - 支持中文规则名与中文规则描述 246 | - 支持规则内定义变量,但规则内定义的变量在规则与规则之间的不可见 247 | - 支持 if../if..else.. 代码块和其代码块嵌套 248 | - 支持复杂逻辑运算 249 | - 支持复杂数学四则运算(+ - * /) 250 | - 支持结构体方法调用 251 | - 支持单行注释(//) 252 | - 支持优雅的规则检错机制(是的,你没看错,就是检错,不是检测!):如果待加载的一批规则中有一个规则有语法错误,那么规则引擎就不会加载这批规则去执行,防止对数据造成不可预知的危害 253 | - 支持仅有一个返回值的函数赋值,且返回值为基础类型或结构体; 支持多返回值函数的调用,但无法处理其返回值 254 | - 支持直接注入函数并执行,并允许函数重命名 255 | - 支持规则链中有规则执行失败时,是否继续执行后续规则开关 256 | - 支持一些内置函数 257 | - 支持使用@name 在规则体内获得当前规则的名称 258 | 259 | 260 | ## Gengine不支持的规则语法 261 | - 不支持else if, 因为作者讨厌使用else if 262 | - 不支持形如user.ip.ipRisk()这种多级调用,因为它不符合"迪米特法则",并且会使代码变得难以理解;只支持ip.ipRisk()这种单级调用 263 | - 不支持函数多个返回值,当需要返回多个值时,请使用返回结构体 264 | - 不支持多行注释,因为不想支持 265 | - 不支持nil 266 | 267 | ## 书写规则需要注意的事情 268 | - 如果规则的优先级不指定,多个规则将以未知次序执行 269 | - 同一批待加载的规则中不能有重名规则 270 | 271 | ## 支持的基本数据类型 272 | - string 273 | - bool 274 | - int, int8, int16, int32, int64 275 | - float32, float64 276 | 277 | ## 支持的逻辑运算符 278 | - && 且 279 | - || 或 280 | - ! 非 281 | 282 | ## 支持的比较运算符 283 | - == 等于 284 | - != 不等于 285 | - \> 大于 286 | - < 小于 287 | - \>= 大于等于 288 | - <= 小于等于 289 | 290 | ## 支持的算术运算符 291 | - \+ 加 292 | - \- 减 293 | - \* 乘 294 | - / 除 295 | - 支持int,uint,float任意两者之间的加减乘除, 以及string与string之间的加法 296 | 297 | ## 支持的括号 298 | - 圆括号 299 | 300 | ## 运算优先级 301 | - 单目运算符非(!) > 算术运算符 > 比较运算符 > 逻辑运算符 302 | 303 | ## Gengine规则示例 304 | ```go 305 | //规则 306 | rule "测试" "测试描述" salience 0 307 | begin 308 | // 重命名函数 测试 309 | Sout("XXXXXXXXXX") 310 | // 普通函数 测试 311 | Hello() 312 | //结构提方法 测试 313 | User.Say() 314 | // if 315 | if !(7 == User.GetNum(7)) || !(7 > 8) { 316 | //自定义变量 和 加法 测试 317 | variable = "hello" + (" world" + "zeze") 318 | // 加法 与 内建函数 测试 319 | User.Name = "hhh" + strconv.FormatBool(true) 320 | //结构体属性、方法调用 和 除法 测试 321 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 322 | //布尔值设置 测试 323 | User.Male = false 324 | //规则内自定义变量调用 测试 325 | User.Print(variable) 326 | //float测试 也支持科学计数法 327 | f = 9.56 328 | PrintReal(f) 329 | //嵌套if-else测试 330 | if false { 331 | Sout("嵌套if测试") 332 | }else{ 333 | Sout("嵌套else测试") 334 | } 335 | }else{ //else 336 | //字符串设置 测试 337 | User.Name = "yyyy" 338 | } 339 | end 340 | ``` 341 | 342 | ## Gengine完整的规则加载并执行的代码示例 343 | - 所有代码,在test测试包可见 344 | ```go 345 | 346 | import ( 347 | "fmt" 348 | "gengine/base" 349 | "gengine/builder" 350 | "gengine/context" 351 | "gengine/engine" 352 | "github.com/sirupsen/logrus" 353 | "testing" 354 | "time" 355 | ) 356 | 357 | type User struct { 358 | Name string 359 | Age int 360 | Male bool 361 | } 362 | 363 | func (u *User)GetNum(i int64) int64 { 364 | return i 365 | } 366 | 367 | func (u *User)Print(s string){ 368 | fmt.Println(s) 369 | } 370 | 371 | func (u *User)Say(){ 372 | fmt.Println("hello world") 373 | } 374 | 375 | const ( 376 | rule2 = ` 377 | rule "测试" "测试描述" salience 0 378 | begin 379 | // 重命名函数 测试 380 | Sout("XXXXXXXXXX") 381 | // 普通函数 测试 382 | Hello() 383 | //结构提方法 测试 384 | User.Say() 385 | // if 386 | if 7 == User.GetNum(7){ 387 | //自定义变量 和 加法 测试 388 | variable = "hello" + " world" 389 | // 加法 与 内建函数 测试 390 | User.Name = "hhh" + strconv.FormatBool(true) 391 | //结构体属性、方法调用 和 除法 测试 392 | User.Age = User.GetNum(89767999999) / 10000000 393 | //布尔值设置 测试 394 | User.Male = false 395 | //规则内自定义变量调用 测试 396 | User.Print(variable) 397 | //float测试 也支持科学计数法 398 | f = 9.56 399 | PrintReal(f) 400 | //嵌套if-else测试 401 | if false { 402 | Sout("嵌套if测试") 403 | }else{ 404 | Sout("嵌套else测试") 405 | } 406 | }else{ //else 407 | //字符串设置 测试 408 | User.Name = "yyyy" 409 | } 410 | end`) 411 | 412 | func Hello() { 413 | fmt.Println("hello") 414 | } 415 | 416 | func PrintReal(real float64){ 417 | fmt.Println(real) 418 | } 419 | 420 | func exe(user *User){ 421 | /** 422 | 不要注入除函数和结构体指针以外的其他类型(如变量) 423 | */ 424 | dataContext := context.NewDataContext() 425 | //注入结构体指针 426 | dataContext.Add("User", user) 427 | //重命名函数,并注入 428 | dataContext.Add("Sout",fmt.Println) 429 | //直接注入函数 430 | dataContext.Add("Hello",Hello) 431 | dataContext.Add("PrintReal",PrintReal) 432 | 433 | //初始化规则引擎 434 | knowledgeContext := base.NewKnowledgeContext() 435 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 436 | 437 | //读取规则 438 | err := ruleBuilder.BuildRuleFromString(rule2) 439 | if err != nil{ 440 | logrus.Errorf("err:%s ", err) 441 | }else{ 442 | eng := engine.NewGengine() 443 | 444 | start := time.Now().UnixNano() 445 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 446 | err := eng.Execute(ruleBuilder, true) 447 | end := time.Now().UnixNano() 448 | if err != nil{ 449 | logrus.Errorf("execute rule error: %v", err) 450 | } 451 | logrus.Infof("execute rule cost %d ns",end-start) 452 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 453 | } 454 | } 455 | 456 | func Test_Base(t *testing.T){ 457 | user := &User{ 458 | Name: "Calo", 459 | Age: 0, 460 | Male: true, 461 | } 462 | exe(user) 463 | } 464 | 465 | ``` 466 | 467 | ## 注意 和最佳实践 468 | - 如果你想获得高执行效率,请将 规则的构建过程和规则的执行过程相分离 469 | - 如果你的规则中包含耗时,比如操作数据库,那么建议你用engine.ExecuteConcurrent(...) ,如果没有,建议你仍然用engine.Execute(...) 470 | 471 | ## 联系 472 | - renyunyi@bilibili.com -------------------------------------------------------------------------------- /base/Arg.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "fmt" 5 | "gengine/context" 6 | ) 7 | 8 | type Arg struct { 9 | Constant *Constant 10 | Variable string 11 | FunctionCall *FunctionCall 12 | MethodCall *MethodCall 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | } 16 | 17 | func (a *Arg) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 18 | 19 | a.knowledgeContext = kc 20 | a.dataCtx = dc 21 | 22 | if a.Constant != nil { 23 | a.Constant.Initialize(kc, dc) 24 | } 25 | if a.FunctionCall != nil { 26 | a.FunctionCall.Initialize(kc, dc) 27 | } 28 | if a.MethodCall != nil { 29 | a.MethodCall.Initialize(kc, dc) 30 | } 31 | 32 | } 33 | 34 | func (a *Arg) Evaluate(Vars map[string]interface{}) (interface{}, error) { 35 | if len(a.Variable) > 0 { 36 | //单值 37 | return a.dataCtx.GetValue(Vars, a.Variable) 38 | } 39 | 40 | if a.Constant != nil { 41 | //单值 42 | return a.Constant.Evaluate(Vars) 43 | } 44 | 45 | if a.FunctionCall != nil { 46 | //单值 47 | return a.FunctionCall.Evaluate(Vars) 48 | } 49 | 50 | if a.MethodCall != nil { 51 | //单值 52 | return a.MethodCall.Evaluate(Vars) 53 | } 54 | 55 | return nil, fmt.Errorf("argHolder holder has more values than want!") 56 | } 57 | -------------------------------------------------------------------------------- /base/Args.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | ) 6 | 7 | type Args struct { 8 | ArgList []*Arg 9 | knowledgeContext *KnowledgeContext 10 | dataCtx *context.DataContext 11 | } 12 | 13 | func (as *Args) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 14 | as.knowledgeContext = kc 15 | as.dataCtx = dc 16 | 17 | if as.ArgList != nil { 18 | for _, val := range as.ArgList { 19 | val.Initialize(kc, dc) 20 | } 21 | } 22 | } 23 | 24 | func (as *Args) AcceptFunctionCall(funcCall *FunctionCall) error { 25 | holder := &Arg{ 26 | FunctionCall: funcCall, 27 | } 28 | as.ArgList = append(as.ArgList, holder) 29 | return nil 30 | } 31 | 32 | func (as *Args) AcceptMethodCall(methodCall *MethodCall) error { 33 | holder := &Arg{ 34 | MethodCall: methodCall, 35 | } 36 | as.ArgList = append(as.ArgList, holder) 37 | return nil 38 | } 39 | 40 | func (as *Args) AcceptVariable(name string) error { 41 | holder := &Arg{ 42 | Variable: name, 43 | } 44 | as.ArgList = append(as.ArgList, holder) 45 | return nil 46 | } 47 | 48 | func (as *Args) AcceptConstant(cons *Constant) error { 49 | holder := &Arg{ 50 | Constant: cons, 51 | } 52 | as.ArgList = append(as.ArgList, holder) 53 | return nil 54 | } 55 | 56 | func (as *Args) Evaluate(Vars map[string]interface{}) ([]interface{}, error) { 57 | if as.ArgList == nil || len(as.ArgList) == 0 { 58 | return make([]interface{}, 0), nil 59 | } 60 | retVal := make([]interface{}, len(as.ArgList)) 61 | for i, v := range as.ArgList { 62 | rv, err := v.Evaluate(Vars) 63 | if err != nil { 64 | return retVal, err 65 | } 66 | retVal[i] = rv 67 | } 68 | return retVal, nil 69 | } 70 | 71 | -------------------------------------------------------------------------------- /base/ArgsHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type ArgsHolder interface { 4 | AcceptArgs(funcArg *Args) error 5 | } 6 | -------------------------------------------------------------------------------- /base/Assignment.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | "reflect" 7 | ) 8 | 9 | // := or = 10 | type Assignment struct { 11 | Variable string 12 | MathExpression *MathExpression 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | } 16 | 17 | func (a *Assignment) Evaluate(Vars map[string]interface{}) (reflect.Value, error) { 18 | v, err := a.MathExpression.Evaluate(Vars) 19 | if err != nil { 20 | return reflect.ValueOf(nil), err 21 | } 22 | err = a.dataCtx.SetValue(Vars, a.Variable, v) 23 | if err != nil { 24 | return reflect.ValueOf(nil), err 25 | } 26 | return reflect.ValueOf(nil), nil 27 | } 28 | 29 | func (a *Assignment) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 30 | a.knowledgeContext = kc 31 | a.dataCtx = dc 32 | 33 | if a.MathExpression != nil{ 34 | a.MathExpression.Initialize(kc, dc) 35 | } 36 | } 37 | 38 | func (a *Assignment)AcceptMathExpression(me *MathExpression) error{ 39 | if a.MathExpression == nil { 40 | a.MathExpression = me 41 | return nil 42 | } 43 | return errors.Errorf("%s","MathExpression already set twice") 44 | } 45 | 46 | func (a *Assignment)AcceptVariable(name string) error{ 47 | if len(a.Variable) == 0 { 48 | a.Variable = name 49 | return nil 50 | } 51 | return errors.Errorf("Variable already set twice") 52 | } -------------------------------------------------------------------------------- /base/AtNameHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | 4 | 5 | type AtNameHolder interface { 6 | AcceptName(val string) error 7 | } -------------------------------------------------------------------------------- /base/Constant.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | ) 6 | 7 | type Constant struct { 8 | ConstantValue interface{} 9 | knowledgeContext *KnowledgeContext 10 | dataCtx *context.DataContext 11 | } 12 | 13 | func (cons *Constant) AcceptString(str string) error { 14 | cons.ConstantValue = str 15 | return nil 16 | } 17 | 18 | func (cons *Constant) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 19 | cons.knowledgeContext = kc 20 | cons.dataCtx = dc 21 | } 22 | 23 | func (cons *Constant) Evaluate(Vars map[string]interface{}) (interface{}, error) { 24 | return cons.ConstantValue, nil 25 | } 26 | 27 | func (cons *Constant) AcceptInteger(i64 int64) error { 28 | cons.ConstantValue = i64 29 | return nil 30 | } 31 | 32 | //receive rule's name 33 | func (cons *Constant)AcceptName(name string) error{ 34 | cons.ConstantValue = name 35 | return nil 36 | } -------------------------------------------------------------------------------- /base/ConstantHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type ConstantHolder interface { 4 | AcceptConstant(cons *Constant) error 5 | } -------------------------------------------------------------------------------- /base/ElseStmt.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | "reflect" 7 | ) 8 | 9 | type ElseStmt struct { 10 | StatementList *Statements 11 | knowledgeContext *KnowledgeContext 12 | dataCtx *context.DataContext 13 | } 14 | 15 | func (e *ElseStmt) Evaluate(Vars map[string]interface{}) (reflect.Value, error) { 16 | value, err:= e.StatementList.Evaluate(Vars) 17 | if err != nil { 18 | return reflect.ValueOf(nil),err 19 | } 20 | return value,nil 21 | } 22 | 23 | func (e *ElseStmt) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 24 | e.knowledgeContext = kc 25 | e.dataCtx = dc 26 | if e.StatementList != nil { 27 | e.StatementList.Initialize(kc, dc) 28 | } 29 | } 30 | 31 | func (e *ElseStmt)AcceptStatements(stmts *Statements ) error { 32 | if e.StatementList == nil { 33 | e.StatementList = stmts 34 | return nil 35 | } 36 | return errors.Errorf("ElseStmt set twice") 37 | } 38 | -------------------------------------------------------------------------------- /base/Evaluator.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import "reflect" 4 | 5 | type Evaluator interface { 6 | Evaluate(Vars map[string]interface{}) (reflect.Value, error) 7 | } -------------------------------------------------------------------------------- /base/Expression.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | "reflect" 7 | ) 8 | 9 | var TypeMap = map[string]string{ 10 | "int" : "int", 11 | "int8" : "int8" , 12 | "int16" : "int16" , 13 | "int32" : "int32" , 14 | "int64" : "int64" , 15 | "uint" : "uint" , 16 | "uint8" : "uint8", 17 | "uint16" : "uint16", 18 | "uint32" : "uint32", 19 | "uint64" : "uint64", 20 | "float32" :"float32", 21 | "float64" :"float64", 22 | } 23 | 24 | type Expression struct { 25 | ExpressionLeft *Expression 26 | ExpressionRight *Expression 27 | ExpressionAtom *ExpressionAtom 28 | MathExpression *MathExpression 29 | LogicalOperator string 30 | ComparisonOperator string 31 | NotOperator string 32 | knowledgeContext *KnowledgeContext 33 | dataCtx *context.DataContext 34 | } 35 | 36 | func (e *Expression) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 37 | e.knowledgeContext = kc 38 | e.dataCtx = dc 39 | 40 | if e.ExpressionLeft != nil { 41 | e.ExpressionLeft.Initialize(kc, dc) 42 | } 43 | if e.ExpressionRight != nil { 44 | e.ExpressionRight.Initialize(kc, dc) 45 | } 46 | 47 | if e.ExpressionAtom != nil { 48 | e.ExpressionAtom.Initialize(kc, dc) 49 | } 50 | 51 | if e.MathExpression != nil { 52 | e.MathExpression.Initialize(kc, dc) 53 | } 54 | } 55 | 56 | func (e *Expression) AcceptExpressionAtom(atom *ExpressionAtom) error{ 57 | if e.ExpressionAtom == nil { 58 | e.ExpressionAtom = atom 59 | return nil 60 | } 61 | return errors.Errorf("%s","ExpressionAtom already set twice!") 62 | } 63 | 64 | func (e *Expression) AcceptMathExpression(atom *MathExpression) error { 65 | if e.MathExpression == nil { 66 | e.MathExpression = atom 67 | return nil 68 | } 69 | return errors.Errorf("%s", " Expression's MathExpression set twice") 70 | } 71 | 72 | func(e *Expression)AcceptExpression(expression *Expression) error{ 73 | if e.ExpressionLeft == nil { 74 | e.ExpressionLeft = expression 75 | return nil 76 | } 77 | 78 | if e.ExpressionRight == nil { 79 | e.ExpressionRight = expression 80 | return nil 81 | } 82 | return errors.Errorf("%s","Expression already set twice! ") 83 | } 84 | 85 | func (e *Expression) Evaluate(Vars map[string]interface{}) (interface{}, error) { 86 | 87 | //priority to calculate single value 88 | var math interface{} 89 | if e.MathExpression != nil { 90 | evl, err := e.MathExpression.Evaluate(Vars) 91 | if err != nil { 92 | return nil, err 93 | } 94 | math = evl 95 | } 96 | 97 | var atom interface{} 98 | if e.ExpressionAtom != nil { 99 | evl, err := e.ExpressionAtom.Evaluate(Vars) 100 | if err != nil { 101 | return nil,err 102 | } 103 | atom = evl 104 | } 105 | 106 | 107 | var b interface{} 108 | if e.ExpressionRight == nil { 109 | if e.ExpressionLeft != nil { 110 | left, err := e.ExpressionLeft.Evaluate(Vars) 111 | if err != nil { 112 | return nil,err 113 | } 114 | b = left 115 | } 116 | } 117 | 118 | // && || just only to be used between boolean 119 | if e.LogicalOperator != "" { 120 | 121 | lv, err := e.ExpressionLeft.Evaluate(Vars) 122 | if err != nil { 123 | return nil, err 124 | } 125 | 126 | rv, err := e.ExpressionRight.Evaluate(Vars) 127 | if err != nil { 128 | return nil, err 129 | } 130 | 131 | // 132 | flv := reflect.ValueOf(lv) 133 | frv := reflect.ValueOf(rv) 134 | 135 | if reflect.TypeOf(lv).String() == "bool" && reflect.TypeOf(rv).String() == "bool" { 136 | if e.LogicalOperator == "&&" { 137 | b = flv.Bool() && frv.Bool() 138 | } 139 | if e.LogicalOperator == "||" { 140 | b = flv.Bool() || frv.Bool() 141 | } 142 | }else { 143 | return nil, errors.Errorf(" || or && can't be used between %s and %s",flv.Kind().String(), frv.Kind().String()) 144 | } 145 | } 146 | 147 | // == > < != >= <= just only to be used between number and number, string and string 148 | if e.ComparisonOperator != ""{ 149 | 150 | lv, err := e.ExpressionLeft.Evaluate(Vars) 151 | if err != nil { 152 | return nil, err 153 | } 154 | 155 | rv, err := e.ExpressionRight.Evaluate(Vars) 156 | if err != nil { 157 | return nil, err 158 | } 159 | 160 | // 161 | flv := reflect.ValueOf(lv) 162 | frv := reflect.ValueOf(rv) 163 | 164 | //string compare 165 | tlv := reflect.TypeOf(lv).String() 166 | trv := reflect.TypeOf(rv).String() 167 | if tlv == "string" && trv == "string" { 168 | switch e.ComparisonOperator { 169 | case "==": 170 | b = flv.String() == frv.String() 171 | break 172 | case "!=": 173 | b = flv.String() != frv.String() 174 | break 175 | case ">": 176 | b = flv.String() > frv.String() 177 | break 178 | case "<": 179 | b = flv.String() < frv.String() 180 | break 181 | case ">=": 182 | b = flv.String() >= frv.String() 183 | break 184 | case "<=": 185 | b = flv.String() <= frv.String() 186 | break 187 | default: 188 | return nil,errors.Errorf("Can't be recognized ComparisonOperator: %s", e.ComparisonOperator) 189 | } 190 | goto LAST 191 | } 192 | 193 | //data compare 194 | if l, ok1 := TypeMap[tlv]; ok1{ 195 | if r, ok2 := TypeMap[trv]; ok2{ 196 | var ll float64 197 | switch l { 198 | case "int", "int8","int16","int32","int64": 199 | ll = float64(flv.Int()) 200 | break 201 | case "uint", "uint8", "uint16", "uint32", "uint64": 202 | ll = float64(flv.Uint()) 203 | break 204 | case "float32", "float64": 205 | ll = flv.Float() 206 | break 207 | } 208 | 209 | var rr float64 210 | switch r { 211 | case "int", "int8","int16","int32","int64": 212 | rr = float64(frv.Int()) 213 | break 214 | case "uint", "uint8", "uint16", "uint32", "uint64": 215 | rr = float64(frv.Uint()) 216 | break 217 | case "float32", "float64": 218 | rr = frv.Float() 219 | break 220 | } 221 | 222 | switch e.ComparisonOperator { 223 | case "==": 224 | b = ll == rr 225 | break 226 | case "!=": 227 | b = ll != rr 228 | break 229 | case ">": 230 | b = ll > rr 231 | break 232 | case "<": 233 | b = ll < rr 234 | break 235 | case ">=": 236 | b = ll >= rr 237 | break 238 | case "<=": 239 | b = ll <= rr 240 | break 241 | default: 242 | return nil,errors.Errorf("Can't be recognized ComparisonOperator: %s", e.ComparisonOperator) 243 | } 244 | } 245 | } 246 | } 247 | 248 | LAST: 249 | if e.NotOperator == "!" { 250 | 251 | if math != nil { 252 | return !reflect.ValueOf(math).Bool(),nil 253 | } 254 | 255 | if atom != nil { 256 | return !reflect.ValueOf(atom).Bool(), nil 257 | } 258 | 259 | if b != nil { 260 | return !reflect.ValueOf(b).Bool(), nil 261 | } 262 | } else { 263 | if math != nil { 264 | return math, nil 265 | } 266 | 267 | if atom != nil { 268 | return atom, nil 269 | } 270 | 271 | if b != nil { 272 | return b, nil 273 | } 274 | } 275 | return nil,errors.Errorf("%s", "Can't evaluate Expression err!") 276 | } 277 | 278 | -------------------------------------------------------------------------------- /base/ExpressionAtom.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | ) 7 | 8 | type ExpressionAtom struct { 9 | Variable string 10 | Constant *Constant 11 | FunctionCall *FunctionCall 12 | MethodCall *MethodCall 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | } 16 | 17 | 18 | func (e *ExpressionAtom) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 19 | e.knowledgeContext = kc 20 | e.dataCtx = dc 21 | 22 | if e.Constant != nil { 23 | e.Constant.Initialize(kc, dc) 24 | } 25 | 26 | if e.FunctionCall != nil { 27 | e.FunctionCall.Initialize(kc, dc) 28 | } 29 | 30 | if e.MethodCall != nil { 31 | e.MethodCall.Initialize(kc, dc) 32 | } 33 | } 34 | 35 | func (e *ExpressionAtom)AcceptVariable(name string) error { 36 | if len(e.Variable) == 0 { 37 | e.Variable = name 38 | return nil 39 | } 40 | return errors.Errorf("Variable already defined") 41 | } 42 | 43 | func (e *ExpressionAtom)AcceptConstant(cons *Constant) error { 44 | if e.Constant == nil{ 45 | e.Constant = cons 46 | return nil 47 | } 48 | return errors.Errorf("Constant already defined") 49 | } 50 | 51 | func (e *ExpressionAtom)AcceptFunctionCall(funcCall *FunctionCall) error { 52 | if e.FunctionCall == nil { 53 | e.FunctionCall = funcCall 54 | return nil 55 | } 56 | return errors.Errorf("FunctionCall already defined") 57 | } 58 | 59 | func (e *ExpressionAtom)AcceptMethodCall(methodCall *MethodCall) error{ 60 | if e.MethodCall == nil { 61 | e.MethodCall = methodCall 62 | return nil 63 | } 64 | return errors.Errorf("MethodCall already defined") 65 | } 66 | 67 | 68 | func (e *ExpressionAtom) Evaluate(Vars map[string]interface{}) (interface{}, error) { 69 | if len(e.Variable) > 0 { 70 | return e.dataCtx.GetValue(Vars, e.Variable) 71 | } else if e.Constant != nil { 72 | return e.Constant.Evaluate(Vars) 73 | } else if e.FunctionCall != nil { 74 | return e.FunctionCall.Evaluate(Vars) 75 | } else if e.MethodCall != nil { 76 | return e.MethodCall.Evaluate(Vars) 77 | } 78 | //todo 79 | return nil, errors.Errorf("%v", "ExpressionAtom Evaluate error") 80 | } 81 | 82 | -------------------------------------------------------------------------------- /base/ExpressionAtomHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type ExpressionAtomHolder interface { 4 | AcceptExpressionAtom(atom *ExpressionAtom) error 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /base/ExpressionHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type ExpressionHolder interface { 4 | AcceptExpression(expression *Expression) error 5 | } 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /base/FunctionCall.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | ) 6 | 7 | type FunctionCall struct { 8 | FunctionName string 9 | FunctionArgs *Args 10 | knowledgeContext *KnowledgeContext 11 | dataCtx *context.DataContext 12 | } 13 | 14 | func (fc *FunctionCall) AcceptArgs(funcArg *Args) error { 15 | fc.FunctionArgs = funcArg 16 | return nil 17 | } 18 | 19 | func (fc *FunctionCall) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 20 | fc.knowledgeContext = kc 21 | fc.dataCtx = dc 22 | 23 | if fc.FunctionArgs != nil { 24 | fc.FunctionArgs.Initialize(kc, dc) 25 | } 26 | } 27 | 28 | func (fc *FunctionCall) Evaluate(Vars map[string]interface{}) (interface{}, error) { 29 | var argumentValues []interface{} 30 | if fc.FunctionArgs == nil { 31 | argumentValues = nil 32 | } else { 33 | av, err := fc.FunctionArgs.Evaluate(Vars) 34 | if err != nil { 35 | return nil, err 36 | } 37 | argumentValues = av 38 | } 39 | 40 | return fc.dataCtx.ExecFunc(fc.FunctionName, argumentValues) 41 | } 42 | -------------------------------------------------------------------------------- /base/FunctionCallHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type FunctionCallHolder interface { 4 | AcceptFunctionCall(funcCall *FunctionCall) error 5 | } -------------------------------------------------------------------------------- /base/IfStmt.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | "reflect" 7 | ) 8 | 9 | type IfStmt struct { 10 | Expression *Expression 11 | StatementList *Statements 12 | ElseStmt *ElseStmt 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | } 16 | 17 | func (i *IfStmt) Evaluate(Vars map[string]interface{}) (reflect.Value, error) { 18 | 19 | it ,err := i.Expression.Evaluate(Vars) 20 | if err != nil { 21 | return reflect.ValueOf(nil), err 22 | } 23 | 24 | if reflect.ValueOf(it).Bool() { 25 | return i.StatementList.Evaluate(Vars) 26 | }else { 27 | if i.ElseStmt != nil{ 28 | return i.ElseStmt.Evaluate(Vars) 29 | }else { 30 | return reflect.ValueOf(nil),nil 31 | } 32 | } 33 | } 34 | 35 | func (i *IfStmt) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 36 | i.knowledgeContext = kc 37 | i.dataCtx = dc 38 | 39 | if i.Expression != nil { 40 | i.Expression.Initialize(kc, dc) 41 | } 42 | if i.StatementList != nil { 43 | i.StatementList.Initialize(kc, dc) 44 | } 45 | 46 | if i.ElseStmt != nil { 47 | i.ElseStmt.Initialize(kc, dc) 48 | } 49 | } 50 | 51 | func (i *IfStmt)AcceptExpression(expr *Expression) error{ 52 | if i.Expression == nil { 53 | i.Expression = expr 54 | return nil 55 | } 56 | return errors.Errorf("IfStmt Expression set twice!") 57 | } 58 | 59 | func (i *IfStmt)AcceptStatements(stmts *Statements)error{ 60 | if i.StatementList == nil { 61 | i.StatementList = stmts 62 | return nil 63 | } 64 | return errors.Errorf("ifStmt's statements set twice") 65 | } -------------------------------------------------------------------------------- /base/Initializer.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import "gengine/context" 4 | 5 | type Initializer interface { 6 | Initialize(kc *KnowledgeContext, dc *context.DataContext) 7 | } -------------------------------------------------------------------------------- /base/IntegerHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type IntegerHolder interface { 4 | AcceptInteger(val int64) error 5 | } -------------------------------------------------------------------------------- /base/KnowledgeContext.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type KnowledgeContext struct { 4 | // ruleName - RuleEntity 5 | RuleEntities map[string]*RuleEntity 6 | SortRules []*RuleEntity 7 | } 8 | 9 | func NewKnowledgeContext() *KnowledgeContext{ 10 | return &KnowledgeContext{ 11 | RuleEntities: make(map[string]*RuleEntity), 12 | } 13 | } 14 | 15 | func (k * KnowledgeContext)ClearRules(){ 16 | k.RuleEntities = make(map[string]*RuleEntity) 17 | k.SortRules = make([]*RuleEntity, 0) 18 | } -------------------------------------------------------------------------------- /base/MathExpression.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core" 6 | "gengine/core/errors" 7 | ) 8 | 9 | type MathExpression struct { 10 | MathExpressionLeft *MathExpression 11 | MathPmOperator string 12 | MathMdOperator string 13 | MathExpressionRight *MathExpression 14 | ExpressionAtom *ExpressionAtom 15 | knowledgeContext *KnowledgeContext 16 | dataCtx *context.DataContext 17 | } 18 | 19 | func (e *MathExpression) AcceptMathExpression(atom *MathExpression) error { 20 | if e.MathExpressionLeft == nil { 21 | e.MathExpressionLeft = atom 22 | return nil 23 | } 24 | if e.MathExpressionRight == nil{ 25 | e.MathExpressionRight = atom 26 | return nil 27 | } 28 | return errors.Errorf("%v","expressionAtom set twice") 29 | } 30 | 31 | 32 | func (e *MathExpression) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 33 | e.knowledgeContext = kc 34 | e.dataCtx = dc 35 | 36 | if e.MathExpressionLeft != nil { 37 | e.MathExpressionLeft.Initialize(kc, dc) 38 | } 39 | 40 | if e.MathExpressionRight != nil { 41 | e.MathExpressionRight.Initialize(kc, dc) 42 | } 43 | 44 | if e.ExpressionAtom != nil { 45 | e.ExpressionAtom.Initialize(kc, dc) 46 | } 47 | } 48 | 49 | func (e *MathExpression) AcceptExpressionAtom(atom *ExpressionAtom) error{ 50 | if e.ExpressionAtom == nil { 51 | e.ExpressionAtom = atom 52 | return nil 53 | } 54 | return errors.Errorf("%s","ExpressionAtom already set twice!") 55 | } 56 | 57 | 58 | func (e *MathExpression) Evaluate(Vars map[string]interface{}) (interface{}, error) { 59 | 60 | //priority to calculate single value 61 | if e.ExpressionAtom != nil { 62 | return e.ExpressionAtom.Evaluate(Vars) 63 | } 64 | 65 | // check the right whether is nil 66 | if e.MathExpressionRight == nil { 67 | return e.MathExpressionLeft.Evaluate(Vars) 68 | } 69 | 70 | lv, err := e.MathExpressionLeft.Evaluate(Vars) 71 | if err != nil { 72 | return nil, err 73 | } 74 | rv, err := e.MathExpressionRight.Evaluate(Vars) 75 | if err != nil { 76 | return nil, err 77 | } 78 | 79 | if e.MathPmOperator == "+" { 80 | return core.Add(lv, rv) 81 | } 82 | 83 | if e.MathPmOperator == "-" { 84 | return core.Sub(lv, rv) 85 | } 86 | 87 | if e.MathMdOperator == "*" { 88 | return core.Mul(lv, rv) 89 | } 90 | 91 | if e.MathMdOperator == "/" { 92 | return core.Div(lv, rv) 93 | } 94 | return nil, errors.Errorf("MathExpression calculate evaluate error: %s, %s", e.MathPmOperator, e.MathPmOperator) 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /base/MathExpressionHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type MathExpressionHolder interface { 4 | AcceptMathExpression(mh *MathExpression) error 5 | } -------------------------------------------------------------------------------- /base/MethodCall.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | "reflect" 7 | ) 8 | 9 | type MethodCall struct { 10 | MethodName string 11 | MethodArgs *Args 12 | knowledgeContext *KnowledgeContext 13 | dataCtx *context.DataContext 14 | } 15 | 16 | func (mc *MethodCall) Initialize(ctx *KnowledgeContext, dataCtx *context.DataContext) { 17 | mc.knowledgeContext = ctx 18 | mc.dataCtx = dataCtx 19 | 20 | if mc.MethodArgs != nil { 21 | mc.MethodArgs.Initialize(ctx, dataCtx) 22 | } 23 | } 24 | 25 | func (mc *MethodCall) AcceptArgs(funcArg *Args) error { 26 | if mc.MethodArgs == nil{ 27 | mc.MethodArgs = funcArg 28 | return nil 29 | } 30 | return errors.Errorf("methodArgs set twice") 31 | } 32 | 33 | func (mc *MethodCall) Evaluate(Vars map[string]interface{}) (interface{}, error) { 34 | var argumentValues []interface{} 35 | if mc.MethodArgs == nil { 36 | argumentValues = make([]interface{}, 0) 37 | } else { 38 | av, err := mc.MethodArgs.Evaluate(Vars) 39 | if err != nil { 40 | return reflect.ValueOf(nil), err 41 | } 42 | argumentValues = av 43 | } 44 | 45 | return mc.dataCtx.ExecMethod(mc.MethodName, argumentValues) 46 | } -------------------------------------------------------------------------------- /base/MethodCallHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type MethodCallHolder interface { 4 | AcceptMethodCall(methodCall *MethodCall) error 5 | } 6 | -------------------------------------------------------------------------------- /base/RuleContent.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | ) 7 | 8 | type RuleContent struct { 9 | Statements *Statements 10 | knowledgeContext *KnowledgeContext 11 | dataCtx *context.DataContext 12 | } 13 | 14 | func (t *RuleContent) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 15 | t.knowledgeContext = kc 16 | t.dataCtx = dc 17 | if t.Statements!=nil { 18 | t.Statements.Initialize(kc, dc) 19 | } 20 | } 21 | 22 | func (t *RuleContent) Execute(Vars map[string]interface{}) error { 23 | _, err := t.Statements.Evaluate(Vars) 24 | if err != nil { 25 | return err 26 | } 27 | return nil 28 | } 29 | 30 | func (t *RuleContent)AcceptStatements(stmts *Statements)error { 31 | if t.Statements == nil{ 32 | t.Statements = stmts 33 | return nil 34 | } 35 | return errors.Errorf("RuleContent's statements set twice.") 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /base/RuleEntity.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | ) 7 | 8 | type RuleEntity struct { 9 | RuleName string 10 | Salience int64 11 | RuleDescription string 12 | RuleContent *RuleContent 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | Vars map[string]interface{} //belongs to current rule,rule execute finish, it will be clear 16 | } 17 | 18 | func (r *RuleEntity) AcceptString(s string) error { 19 | if r.RuleName == "" { 20 | r.RuleName = s 21 | return nil 22 | } 23 | 24 | if r.RuleDescription == "" { 25 | r.RuleDescription = s 26 | return nil 27 | } 28 | return errors.Errorf("value = %s set twice!",s) 29 | } 30 | 31 | func (r *RuleEntity) AcceptInteger(val int64) error { 32 | r.Salience = val 33 | return nil 34 | } 35 | 36 | func (r *RuleEntity) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 37 | r.knowledgeContext = kc 38 | r.dataCtx = dc 39 | 40 | if r.RuleContent != nil { 41 | r.RuleContent.Initialize(kc, dc) 42 | } 43 | } 44 | 45 | func (r *RuleEntity) Execute() error { 46 | r.Vars = make(map[string]interface{}) 47 | defer r.clearMap() 48 | return r.RuleContent.Execute(r.Vars) 49 | } 50 | 51 | func (r *RuleEntity)clearMap() { 52 | r.Vars = make(map[string]interface{}) 53 | } -------------------------------------------------------------------------------- /base/Statement.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "gengine/core/errors" 6 | ) 7 | 8 | type Statement struct { 9 | IfStmt *IfStmt 10 | MethodCall *MethodCall 11 | FunctionCall *FunctionCall 12 | Assignment *Assignment 13 | knowledgeContext *KnowledgeContext 14 | dataCtx *context.DataContext 15 | } 16 | 17 | func (s *Statement) Evaluate(Vars map[string]interface{}) (interface{}, error) { 18 | 19 | if s.IfStmt != nil { 20 | return s.IfStmt.Evaluate(Vars) 21 | } 22 | 23 | if s.MethodCall != nil { 24 | return s.MethodCall.Evaluate(Vars) 25 | } 26 | 27 | if s.FunctionCall != nil { 28 | return s.FunctionCall.Evaluate(Vars) 29 | } 30 | 31 | if s.Assignment != nil { 32 | return s.Assignment.Evaluate(Vars) 33 | } 34 | 35 | return nil,errors.Errorf("Statement evaluate error") 36 | } 37 | 38 | func (s *Statement) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 39 | s.knowledgeContext = kc 40 | s.dataCtx = dc 41 | 42 | if s.IfStmt != nil { 43 | s.IfStmt.Initialize(kc, dc) 44 | } 45 | 46 | if s.FunctionCall != nil { 47 | s.FunctionCall.Initialize(kc, dc) 48 | } 49 | 50 | if s.MethodCall != nil { 51 | s.MethodCall.Initialize(kc, dc) 52 | } 53 | 54 | if s.Assignment != nil { 55 | s.Assignment.Initialize(kc, dc) 56 | } 57 | 58 | } 59 | 60 | func (s *Statement)AcceptFunctionCall(funcCall *FunctionCall) error { 61 | if s.FunctionCall == nil { 62 | s.FunctionCall = funcCall 63 | return nil 64 | } 65 | return errors.Errorf("FunctionCall already defined") 66 | } 67 | 68 | 69 | func (s *Statement)AcceptMethodCall(methodCall *MethodCall) error{ 70 | if s.MethodCall == nil { 71 | s.MethodCall = methodCall 72 | return nil 73 | } 74 | return errors.Errorf("MethodCall already defined") 75 | } 76 | 77 | -------------------------------------------------------------------------------- /base/Statements.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "gengine/context" 5 | "reflect" 6 | ) 7 | 8 | type Statements struct { 9 | StatementList []*Statement 10 | knowledgeContext *KnowledgeContext 11 | dataCtx *context.DataContext 12 | } 13 | 14 | func (s *Statements) Evaluate(Vars map[string]interface{}) (reflect.Value, error) { 15 | for _, val := range s.StatementList{ 16 | _, err := val.Evaluate(Vars) 17 | if err != nil { 18 | return reflect.ValueOf(nil), err 19 | } 20 | } 21 | return reflect.ValueOf(nil), nil 22 | } 23 | 24 | func (s *Statements) Initialize(kc *KnowledgeContext, dc *context.DataContext) { 25 | s.knowledgeContext = kc 26 | s.dataCtx = dc 27 | 28 | if s.StatementList != nil { 29 | for _, val := range s.StatementList{ 30 | val.Initialize(kc, dc) 31 | } 32 | } 33 | } 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /base/StatementsHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type StatementsHolder interface { 4 | AcceptStatements(statement *Statements) error 5 | } 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /base/StringHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | type StringHolder interface { 4 | AcceptString(str string) error 5 | } 6 | -------------------------------------------------------------------------------- /base/VariableHolder.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | 4 | type VariableHolder interface { 5 | AcceptVariable(name string) error 6 | } 7 | -------------------------------------------------------------------------------- /builder/RuleBuilder.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | import ( 4 | "gengine/base" 5 | "gengine/context" 6 | "gengine/core/errors" 7 | parser "gengine/iantlr/alr" 8 | "gengine/iparser" 9 | "github.com/antlr/antlr4/runtime/Go/antlr" 10 | "sort" 11 | ) 12 | 13 | 14 | type RuleBuilder struct { 15 | Kc *base.KnowledgeContext 16 | Dc *context.DataContext 17 | } 18 | 19 | func NewRuleBuilder(kc *base.KnowledgeContext,dc *context.DataContext)*RuleBuilder{ 20 | return &RuleBuilder{ 21 | Kc: kc, 22 | Dc: dc, 23 | } 24 | } 25 | 26 | func (builder *RuleBuilder) BuildRuleFromString(ruleString string) error{ 27 | //forbidden old rules in context 28 | builder.Kc.ClearRules() 29 | 30 | in := antlr.NewInputStream(ruleString) 31 | lexer := parser.NewgengineLexer(in) 32 | stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) 33 | listener := iparser.NewGengineParserListener(builder.Kc) 34 | 35 | psr := parser.NewgengineParser(stream) 36 | psr.BuildParseTrees = true 37 | //语法错误监听器 38 | errListener := iparser.NewGengineErrorListener() 39 | psr.AddErrorListener(errListener) 40 | antlr.ParseTreeWalkerDefault.Walk(listener, psr.Primary()) 41 | 42 | if len(errListener.GrammarErrors) > 0 { 43 | builder.Kc.ClearRules() 44 | return errors.Errorf("%v", errListener.GrammarErrors) 45 | } 46 | 47 | if len(listener.ParseErrors) > 0 { 48 | builder.Kc.ClearRules() 49 | return errors.Errorf("%v", listener.ParseErrors) 50 | } 51 | 52 | //initial 53 | for _,v := range builder.Kc.RuleEntities { 54 | v.Initialize(builder.Kc, builder.Dc) 55 | } 56 | 57 | //sort 58 | for _,v := range builder.Kc.RuleEntities { 59 | builder.Kc.SortRules = append(builder.Kc.SortRules, v) 60 | } 61 | if len(builder.Kc.SortRules) > 1 { 62 | sort.SliceStable(builder.Kc.SortRules, func(i, j int) bool { 63 | return builder.Kc.SortRules[i].Salience > builder.Kc.SortRules[j].Salience 64 | }) 65 | } 66 | return nil 67 | } -------------------------------------------------------------------------------- /context/DataContext.go: -------------------------------------------------------------------------------- 1 | package context 2 | 3 | import ( 4 | "gengine/core" 5 | "gengine/core/errors" 6 | "gengine/define" 7 | "reflect" 8 | "strings" 9 | "sync" 10 | ) 11 | 12 | type DataContext struct { 13 | base sync.Map 14 | } 15 | 16 | func NewDataContext() *DataContext { 17 | dc := &DataContext{ 18 | base: sync.Map{}, 19 | } 20 | dc.loadInnerUDF() 21 | return dc 22 | } 23 | 24 | func (dc *DataContext)loadInnerUDF(){ 25 | strconv := &define.StrconvWrapper{} 26 | dc.Add("strconv", strconv) 27 | } 28 | 29 | func (dc *DataContext)Add(key string, obj interface{}) { 30 | dc.base.Store(key, obj) 31 | } 32 | 33 | /** 34 | execute the injected functions 35 | function execute supply multi return values, but simplify ,just return one value 36 | */ 37 | func(dc *DataContext)ExecFunc(funcName string, parameters []interface{}) (interface{}, error) { 38 | if f, ok := dc.base.Load(funcName);ok{ 39 | f, params := core.TypeChange(f, parameters) 40 | if f == nil { 41 | return nil, errors.Errorf("Can't find %s in DataContext[when use it, please set it before]!") 42 | } 43 | fun := reflect.ValueOf(f) 44 | args := make([]reflect.Value, 0) 45 | for _, param :=range params { 46 | args = append(args, reflect.ValueOf(param)) 47 | } 48 | res := fun.Call(args) 49 | raw, e := core.GetRawTypeValue(res) 50 | if e != nil { 51 | return nil,e 52 | } 53 | return raw, nil 54 | }else { 55 | return nil, errors.Errorf("no such data found in DataContext!") 56 | } 57 | } 58 | 59 | /** 60 | execute the struct's functions 61 | function execute supply multi return values, but simplify ,just return one value 62 | */ 63 | func (dc *DataContext)ExecMethod(methodName string, args []interface{} ) (interface{}, error) { 64 | structAndMethod := strings.Split(methodName, ".") 65 | //Dimit rule 66 | if len(structAndMethod) != 2 { 67 | return nil,errors.Errorf("Not supported call, just support struct.method call, now length is %d", len(structAndMethod)) 68 | } 69 | 70 | if struc, ok := dc.base.Load(structAndMethod[0]); ok { 71 | res, err := core.InvokeFunction(struc, structAndMethod[1], args) 72 | if err != nil { 73 | return nil, err 74 | } 75 | return res, nil 76 | } 77 | return nil, errors.Errorf("Not found method: %s",methodName) 78 | } 79 | 80 | /** 81 | get the value user set 82 | */ 83 | func (dc *DataContext)GetValue(Vars map[string]interface{}, variable string)(interface{}, error){ 84 | if strings.Contains(variable, ".") { 85 | //in dataContext 86 | structAndField := strings.Split(variable, ".") 87 | //Dimit rule 88 | if len(structAndField) != 2 { 89 | return nil,errors.Errorf("Not supported Field, just support struct.field , now length is %d", len(structAndField)) 90 | } 91 | 92 | if obj,ok := dc.base.Load(structAndField[0]); ok{ 93 | return core.GetStructAttributeValue(obj, structAndField[1]) 94 | } 95 | 96 | //for return struct or struct ptr 97 | if obj,ok := Vars[structAndField[0]];ok{ 98 | return core.GetStructAttributeValue(obj, structAndField[1]) 99 | } 100 | }else { 101 | //in RuleEntity 102 | return Vars[variable], nil 103 | } 104 | return nil, errors.Errorf("Did not found variable : %s ",variable) 105 | } 106 | 107 | func (dc *DataContext) SetValue(Vars map[string]interface{} ,variable string, newValue interface{}) error { 108 | if strings.Contains(variable, ".") { 109 | structAndField := strings.Split(variable, ".") 110 | //Dimit rule 111 | if len(structAndField) != 2 { 112 | return errors.Errorf("Not supported Field, just support struct.field , now length is %d", len(structAndField)) 113 | } 114 | 115 | if obj, ok := dc.base.Load(structAndField[0]);ok { 116 | return core.SetAttributeValue(obj, structAndField[1], newValue) 117 | } 118 | }else { 119 | //in RuleEntity 120 | Vars[variable] = newValue 121 | return nil 122 | } 123 | return errors.New("setValue not found error.") 124 | } -------------------------------------------------------------------------------- /core/errors/errors.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func New(text string) error{ 9 | return errors.New(text) 10 | } 11 | 12 | func Errorf(format string, i... interface{}) error { 13 | return errors.New(fmt.Sprintf(format, i)) 14 | } 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /core/execute.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "gengine/core/errors" 5 | "reflect" 6 | ) 7 | 8 | func InvokeFunction(obj interface{}, methodName string, parameters []interface{}) (interface{}, error) { 9 | objVal := reflect.ValueOf(obj) 10 | fun := objVal.MethodByName(methodName).Interface() 11 | //change type for base type params 12 | funcVal, params := TypeChange(fun, parameters) 13 | args := make([]reflect.Value, 0) 14 | for _, param :=range params { 15 | args = append(args, reflect.ValueOf(param)) 16 | } 17 | rs := reflect.ValueOf(funcVal).Call(args) 18 | raw, e := GetRawTypeValue(rs) 19 | if e != nil { 20 | return nil,e 21 | } 22 | return raw,nil 23 | } 24 | 25 | /** 26 | if want to support multi return ,change this method implements 27 | */ 28 | func GetRawTypeValue(rs []reflect.Value) (interface{},error){ 29 | if len(rs) == 0 { 30 | return nil, nil 31 | }else { 32 | switch rs[0].Kind().String(){ 33 | case "string": 34 | return rs[0].String(),nil 35 | case "bool": 36 | return rs[0].Bool(), nil 37 | case "int": 38 | return int(rs[0].Int()),nil 39 | case "int8": 40 | return int8(rs[0].Int()),nil 41 | case "int16": 42 | return int16(rs[0].Int()),nil 43 | case "int32": 44 | return int32(rs[0].Int()),nil 45 | case "int64": 46 | return int64(rs[0].Int()),nil 47 | case "uint": 48 | return uint(rs[0].Uint()),nil 49 | case "uint8": 50 | return uint8(rs[0].Uint()),nil 51 | case "uint16": 52 | return uint16(rs[0].Uint()),nil 53 | case "uint32": 54 | return uint32(rs[0].Uint()),nil 55 | case "uint64": 56 | return rs[0].Uint(),nil 57 | case "float32": 58 | return float32(rs[0].Float()),nil 59 | case "float64": 60 | return rs[0].Float(),nil 61 | case "struct": 62 | return rs[0].Interface(),nil 63 | case "ptr": 64 | newPtr := reflect.New(rs[0].Elem().Type()) 65 | newPtr.Elem().Set(rs[0].Elem()) 66 | return newPtr.Interface(), nil 67 | default: 68 | return nil, errors.Errorf("Can't be handled type: %s", rs[0].Kind().String()) 69 | } 70 | } 71 | } 72 | 73 | func ValueToInterface(v reflect.Value) interface{} { 74 | switch v.Type().Kind() { 75 | case reflect.String: 76 | return v.String() 77 | case reflect.Bool: 78 | return v.Bool() 79 | case reflect.Int: 80 | return int(v.Int()) 81 | case reflect.Int8: 82 | return int8(v.Int()) 83 | case reflect.Int16: 84 | return int16(v.Int()) 85 | case reflect.Int32: 86 | return int32(v.Int()) 87 | case reflect.Int64: 88 | return v.Int() 89 | case reflect.Uint: 90 | return uint(v.Uint()) 91 | case reflect.Uint8: 92 | return uint8(v.Uint()) 93 | case reflect.Uint16: 94 | return uint16(v.Uint()) 95 | case reflect.Uint32: 96 | return uint32(v.Uint()) 97 | case reflect.Uint64: 98 | return v.Uint() 99 | case reflect.Float32: 100 | return float32(v.Float()) 101 | case reflect.Float64: 102 | return v.Float() 103 | case reflect.Ptr: 104 | newPtr := reflect.New(v.Elem().Type()) 105 | newPtr.Elem().Set(v.Elem()) 106 | return newPtr.Interface() 107 | case reflect.Struct: 108 | if v.CanInterface() { 109 | return v.Interface() 110 | } 111 | return nil 112 | default: 113 | return nil 114 | } 115 | } 116 | 117 | func GetStructAttributeValue(obj interface{}, fieldName string) (interface{}, error) { 118 | stru := reflect.ValueOf(obj) 119 | var attrVal reflect.Value 120 | if stru.Kind() == reflect.Ptr { 121 | attrVal = stru.Elem().FieldByName(fieldName) 122 | } else { 123 | attrVal = stru.FieldByName(fieldName) 124 | } 125 | return ValueToInterface(attrVal), nil 126 | } 127 | 128 | /** 129 | 设置属性值 130 | */ 131 | func SetAttributeValue(obj interface{}, fieldName string, value interface{}) error { 132 | var field = reflect.ValueOf(nil) 133 | objType := reflect.TypeOf(obj) 134 | objVal := reflect.ValueOf(obj) 135 | if objType.Kind() == reflect.Ptr { 136 | //it points to struct 137 | if objType.Elem().Kind() == reflect.Struct { 138 | field = objVal.Elem().FieldByName(fieldName) 139 | } 140 | } else { 141 | //not a pointer. 142 | if objType.Kind() == reflect.Struct { 143 | field = objVal.FieldByName(fieldName) 144 | } 145 | } 146 | 147 | if field == reflect.ValueOf(nil) { 148 | return errors.Errorf("struct has no this field: %s", fieldName) 149 | } 150 | 151 | if field.CanSet() { 152 | switch field.Type().Kind() { 153 | case reflect.String: 154 | field.SetString(reflect.ValueOf(value).String()) 155 | break 156 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 157 | field.SetInt(int64(reflect.ValueOf(value).Float())) 158 | break 159 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 160 | field.SetUint(uint64(reflect.ValueOf(value).Float())) 161 | break 162 | case reflect.Float32, reflect.Float64: 163 | field.SetFloat(reflect.ValueOf(value).Float()) 164 | break 165 | case reflect.Bool: 166 | field.SetBool(reflect.ValueOf(value).Bool()) 167 | break 168 | default: 169 | return errors.Errorf("%s:%s", "Not support type", field.Type().Kind().String()) 170 | } 171 | } else { 172 | return errors.Errorf("%s:%s","can not set field type", field.Type().Kind().String()) 173 | } 174 | return nil 175 | } 176 | 177 | /* 178 | number type exchange 179 | */ 180 | func TypeChange(f interface{}, params []interface{})(interface{}, []interface{}){ 181 | tf := reflect.TypeOf(f) 182 | if tf.Kind().String() == "ptr"{ 183 | tf = tf.Elem() 184 | } 185 | plen := tf.NumIn() 186 | for i := 0; i < plen; i ++ { 187 | switch tf.In(i).Kind().String(){ 188 | case "int": 189 | params[i] = int(reflect.ValueOf(params[i]).Int()) 190 | break 191 | case "int8": 192 | params[i] = int8(reflect.ValueOf(params[i]).Int()) 193 | break 194 | case "int16": 195 | params[i] = int16(reflect.ValueOf(params[i]).Int()) 196 | break 197 | case "int32": 198 | params[i] = int32(reflect.ValueOf(params[i]).Int()) 199 | break 200 | case "int64": 201 | params[i] = reflect.ValueOf(params[i]).Int() 202 | break 203 | case "uint": 204 | params[i] = uint(reflect.ValueOf(params[i]).Uint()) 205 | break 206 | case "uint8": 207 | params[i] = uint8(reflect.ValueOf(params[i]).Uint()) 208 | break 209 | case "uint16": 210 | params[i] = uint16(reflect.ValueOf(params[i]).Uint()) 211 | break 212 | case "uint32": 213 | params[i] = uint32(reflect.ValueOf(params[i]).Uint()) 214 | break 215 | case "uint64": 216 | params[i] = reflect.ValueOf(params[i]).Uint() 217 | break 218 | case "float32": 219 | params[i] = float32(reflect.ValueOf(params[i]).Float()) 220 | break 221 | case "float64": 222 | params[i] = reflect.ValueOf(params[i]).Float() 223 | break 224 | default: 225 | continue 226 | } 227 | } 228 | return f,params 229 | } 230 | -------------------------------------------------------------------------------- /core/math.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "fmt" 5 | "gengine/core/errors" 6 | "reflect" 7 | "strings" 8 | ) 9 | 10 | func Add(ax, bx interface{}) (interface{}, error){ 11 | a := reflect.ValueOf(ax) 12 | akind := a.Kind().String() 13 | b := reflect.ValueOf(bx) 14 | bkind := b.Kind().String() 15 | 16 | if !(strings.HasPrefix(akind,"int")|| (strings.HasPrefix(akind,"uint")) || (strings.HasPrefix(akind,"float")) || akind == "string") && !(strings.HasPrefix(akind, "int") || (strings.HasPrefix(akind, "uint")) || (strings.HasPrefix(akind, "float")) || bkind == "sting") { 17 | return nil, errors.Errorf("ADD(+) can't be used between %s and %s", akind, bkind) 18 | } 19 | if akind == "string" && bkind == "string" { 20 | //字符串相加 21 | return fmt.Sprintf("%s%s", a.String(), b.String()), nil 22 | } 23 | if akind == "string" && bkind !="string" { 24 | return nil, errors.Errorf("ADD(+) can't be used between %s and %s", akind, bkind) 25 | } 26 | 27 | if akind != "string" && bkind == "string" { 28 | return nil, errors.Errorf("ADD(+) can't be used between %s and %s", akind, bkind) 29 | } 30 | 31 | var afloat float64 32 | if strings.HasPrefix(akind, "int") { 33 | afloat = float64(a.Int()) 34 | } 35 | if strings.HasPrefix(akind, "uint") { 36 | afloat = float64(a.Uint()) 37 | } 38 | if strings.HasPrefix(akind, "float") { 39 | afloat = a.Float() 40 | } 41 | 42 | var bfloat float64 43 | if strings.HasPrefix(bkind, "int") { 44 | bfloat = float64(b.Int()) 45 | } 46 | if strings.HasPrefix(bkind, "uint") { 47 | bfloat = float64(b.Uint()) 48 | } 49 | if strings.HasPrefix(bkind, "float") { 50 | bfloat = b.Float() 51 | } 52 | return afloat + bfloat, nil 53 | } 54 | 55 | func Sub(ax, bx interface{}) (interface{}, error){ 56 | a := reflect.ValueOf(ax) 57 | b := reflect.ValueOf(bx) 58 | akind := a.Kind().String() 59 | bkind := b.Kind().String() 60 | 61 | if !(strings.HasPrefix(akind,"int")|| (strings.HasPrefix(akind,"uint")) || (strings.HasPrefix(akind,"float"))) && !(strings.HasPrefix(akind, "int") || (strings.HasPrefix(akind, "uint")) || (strings.HasPrefix(akind, "float"))) { 62 | return nil, errors.Errorf("SUB(-) can't be used between %s and %s", akind, bkind) 63 | } 64 | 65 | var afloat float64 66 | if strings.HasPrefix(akind, "int") { 67 | afloat = float64(a.Int()) 68 | } 69 | if strings.HasPrefix(akind, "uint") { 70 | afloat = float64(a.Uint()) 71 | } 72 | if strings.HasPrefix(akind, "float") { 73 | afloat = a.Float() 74 | } 75 | 76 | var bfloat float64 77 | if strings.HasPrefix(bkind, "int") { 78 | bfloat = float64(b.Int()) 79 | } 80 | if strings.HasPrefix(bkind, "uint") { 81 | bfloat = float64(b.Uint()) 82 | } 83 | if strings.HasPrefix(bkind, "float") { 84 | bfloat = b.Float() 85 | } 86 | 87 | return afloat - bfloat, nil 88 | } 89 | 90 | func Mul(ax, bx interface{}) (interface{}, error){ 91 | a := reflect.ValueOf(ax) 92 | b := reflect.ValueOf(bx) 93 | akind := a.Kind().String() 94 | bkind := b.Kind().String() 95 | 96 | if !(strings.HasPrefix(akind,"int")|| (strings.HasPrefix(akind,"uint")) || (strings.HasPrefix(akind,"float"))) && !(strings.HasPrefix(akind, "int") || (strings.HasPrefix(akind, "uint")) || (strings.HasPrefix(akind, "float"))) { 97 | return nil, errors.Errorf("Mul(*) can't be used between %s and %s", akind, bkind) 98 | } 99 | 100 | var afloat float64 101 | if strings.HasPrefix(akind, "int") { 102 | afloat = float64(a.Int()) 103 | } 104 | if strings.HasPrefix(akind, "uint") { 105 | afloat = float64(a.Uint()) 106 | } 107 | if strings.HasPrefix(akind, "float") { 108 | afloat = a.Float() 109 | } 110 | 111 | var bfloat float64 112 | if strings.HasPrefix(bkind, "int") { 113 | bfloat = float64(b.Int()) 114 | } 115 | if strings.HasPrefix(bkind, "uint") { 116 | bfloat = float64(b.Uint()) 117 | } 118 | if strings.HasPrefix(bkind, "float") { 119 | bfloat = b.Float() 120 | } 121 | return afloat * bfloat, nil 122 | } 123 | 124 | 125 | func Div(ax, bx interface{}) (interface{}, error) { 126 | a := reflect.ValueOf(ax) 127 | b := reflect.ValueOf(bx) 128 | akind := a.Kind().String() 129 | bkind := b.Kind().String() 130 | 131 | if !(strings.HasPrefix(akind,"int")|| (strings.HasPrefix(akind,"uint")) || (strings.HasPrefix(akind,"float"))) && !(strings.HasPrefix(akind, "int") || (strings.HasPrefix(akind, "uint")) || (strings.HasPrefix(akind, "float"))) { 132 | return nil, errors.Errorf("DIV(/) can't be used between %s and %s", akind, bkind) 133 | } 134 | 135 | var afloat float64 136 | if strings.HasPrefix(akind, "int") { 137 | afloat = float64(a.Int()) 138 | } 139 | if strings.HasPrefix(akind, "uint") { 140 | afloat = float64(a.Uint()) 141 | } 142 | if strings.HasPrefix(akind, "float") { 143 | afloat = a.Float() 144 | } 145 | 146 | var bfloat float64 147 | if strings.HasPrefix(bkind, "int") { 148 | bfloat = float64(b.Int()) 149 | } 150 | if strings.HasPrefix(bkind, "uint") { 151 | bfloat = float64(b.Uint()) 152 | } 153 | if strings.HasPrefix(bkind, "float") { 154 | bfloat = b.Float() 155 | } 156 | 157 | if bfloat == 0 { 158 | return nil, errors.Errorf("DIV(/) can't be used to Div ZERO(0)!") 159 | } 160 | return afloat / bfloat, nil 161 | } -------------------------------------------------------------------------------- /define/strconv.go: -------------------------------------------------------------------------------- 1 | package define 2 | 3 | import "strconv" 4 | 5 | type StrconvWrapper struct {} 6 | 7 | func (s *StrconvWrapper)FormatInt(i int64, base int) string { 8 | return strconv.FormatInt(i, base) 9 | } 10 | 11 | func (s *StrconvWrapper)FormatBool(b bool) string { 12 | return strconv.FormatBool(b) 13 | } 14 | 15 | func (s *StrconvWrapper)FormatFloat(f float64, fmt byte, prec, bitSize int) string{ 16 | return strconv.FormatFloat(f, fmt, prec, bitSize) 17 | } 18 | 19 | func (s *StrconvWrapper)FormatUint(i uint64, base int) string { 20 | return strconv.FormatUint(i, base) 21 | } -------------------------------------------------------------------------------- /engine/Gengine.go: -------------------------------------------------------------------------------- 1 | package engine 2 | 3 | import ( 4 | "gengine/builder" 5 | "gengine/core/errors" 6 | "github.com/sirupsen/logrus" 7 | "sync" 8 | ) 9 | 10 | type Gengine struct { 11 | } 12 | 13 | func NewGengine() *Gengine { 14 | return &Gengine{} 15 | } 16 | 17 | /** 18 | when b is true it means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 19 | */ 20 | func (g *Gengine) Execute(rb *builder.RuleBuilder, b bool) error { 21 | if len(rb.Kc.RuleEntities) == 0 { 22 | return nil 23 | } 24 | 25 | for _,r := range rb.Kc.SortRules{ 26 | err := r.Execute() 27 | if err != nil { 28 | if b { 29 | logrus.Errorf("rule: %s executed, error: %+v ",r.RuleName, err) 30 | } else { 31 | return errors.Errorf("rule: %s executed, error: %v ",r.RuleName, err) 32 | } 33 | } 34 | } 35 | return nil 36 | } 37 | 38 | /* 39 | concurrent execute rules 40 | in this mode, it will not consider the salience and err control 41 | */ 42 | func (g *Gengine) ExecuteConcurrent(rb * builder.RuleBuilder){ 43 | var wg sync.WaitGroup 44 | wg.Add(len(rb.Kc.RuleEntities)) 45 | for _,r := range rb.Kc.RuleEntities { 46 | rr := r 47 | go func() { 48 | e := rr.Execute() 49 | if e != nil { 50 | logrus.Errorf("in rule:%s execute rule err: %+v", r.RuleName, e) 51 | } 52 | wg.Done() 53 | }() 54 | } 55 | wg.Wait() 56 | } -------------------------------------------------------------------------------- /iantlr/alr/gengine.interp: -------------------------------------------------------------------------------- 1 | token literal names: 2 | null 3 | 'if' 4 | 'else' 5 | ',' 6 | '@name' 7 | null 8 | null 9 | '&&' 10 | '||' 11 | null 12 | null 13 | null 14 | null 15 | null 16 | null 17 | null 18 | null 19 | '+' 20 | '-' 21 | '/' 22 | '*' 23 | '==' 24 | '>' 25 | '<' 26 | '>=' 27 | '<=' 28 | '!=' 29 | '!' 30 | ':=' 31 | '=' 32 | ';' 33 | '{' 34 | '}' 35 | '(' 36 | ')' 37 | '.' 38 | null 39 | null 40 | null 41 | null 42 | null 43 | 44 | token symbolic names: 45 | null 46 | null 47 | null 48 | null 49 | null 50 | NIL 51 | RULE 52 | AND 53 | OR 54 | TRUE 55 | FALSE 56 | NULL_LITERAL 57 | SALIENCE 58 | BEGIN 59 | END 60 | SIMPLENAME 61 | INT 62 | PLUS 63 | MINUS 64 | DIV 65 | MUL 66 | EQUALS 67 | GT 68 | LT 69 | GTE 70 | LTE 71 | NOTEQUALS 72 | NOT 73 | ASSIGN 74 | SET 75 | SEMICOLON 76 | LR_BRACE 77 | RR_BRACE 78 | LR_BRACKET 79 | RR_BRACKET 80 | DOT 81 | DQUOTA_STRING 82 | DOTTEDNAME 83 | REAL_LITERAL 84 | SL_COMMENT 85 | WS 86 | 87 | rule names: 88 | primary 89 | ruleEntity 90 | ruleName 91 | ruleDescription 92 | salience 93 | ruleContent 94 | statements 95 | statement 96 | expression 97 | mathExpression 98 | expressionAtom 99 | assignment 100 | ifStmt 101 | elseStmt 102 | constant 103 | functionArgs 104 | integer 105 | realLiteral 106 | stringLiteral 107 | booleanLiteral 108 | functionCall 109 | methodCall 110 | variable 111 | mathPmOperator 112 | mathMdOperator 113 | comparisonOperator 114 | logicalOperator 115 | assignOperator 116 | setOperator 117 | notOperator 118 | atName 119 | 120 | 121 | atn: 122 | [3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 42, 248, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 3, 2, 6, 2, 66, 10, 2, 13, 2, 14, 2, 67, 3, 3, 3, 3, 3, 3, 5, 3, 73, 10, 3, 3, 3, 5, 3, 76, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 6, 8, 92, 10, 8, 13, 8, 14, 8, 93, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 100, 10, 9, 3, 10, 3, 10, 3, 10, 5, 10, 105, 10, 10, 3, 10, 3, 10, 5, 10, 109, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 115, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 125, 10, 10, 12, 10, 14, 10, 128, 11, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 136, 10, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 7, 11, 146, 10, 11, 12, 11, 14, 11, 149, 11, 11, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 155, 10, 12, 3, 13, 3, 13, 3, 13, 5, 13, 160, 10, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 5, 14, 170, 10, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 182, 10, 16, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 188, 10, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 195, 10, 17, 7, 17, 197, 10, 17, 12, 17, 14, 17, 200, 11, 17, 3, 18, 5, 18, 203, 10, 18, 3, 18, 3, 18, 3, 19, 5, 19, 208, 10, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 5, 22, 219, 10, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 5, 23, 226, 10, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 2, 4, 18, 20, 33, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 2, 8, 3, 2, 11, 12, 4, 2, 17, 17, 39, 39, 3, 2, 19, 20, 3, 2, 21, 22, 3, 2, 23, 28, 3, 2, 9, 10, 2, 252, 2, 65, 3, 2, 2, 2, 4, 69, 3, 2, 2, 2, 6, 81, 3, 2, 2, 2, 8, 83, 3, 2, 2, 2, 10, 85, 3, 2, 2, 2, 12, 88, 3, 2, 2, 2, 14, 91, 3, 2, 2, 2, 16, 99, 3, 2, 2, 2, 18, 114, 3, 2, 2, 2, 20, 135, 3, 2, 2, 2, 22, 154, 3, 2, 2, 2, 24, 156, 3, 2, 2, 2, 26, 163, 3, 2, 2, 2, 28, 171, 3, 2, 2, 2, 30, 181, 3, 2, 2, 2, 32, 187, 3, 2, 2, 2, 34, 202, 3, 2, 2, 2, 36, 207, 3, 2, 2, 2, 38, 211, 3, 2, 2, 2, 40, 213, 3, 2, 2, 2, 42, 215, 3, 2, 2, 2, 44, 222, 3, 2, 2, 2, 46, 229, 3, 2, 2, 2, 48, 231, 3, 2, 2, 2, 50, 233, 3, 2, 2, 2, 52, 235, 3, 2, 2, 2, 54, 237, 3, 2, 2, 2, 56, 239, 3, 2, 2, 2, 58, 241, 3, 2, 2, 2, 60, 243, 3, 2, 2, 2, 62, 245, 3, 2, 2, 2, 64, 66, 5, 4, 3, 2, 65, 64, 3, 2, 2, 2, 66, 67, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 3, 3, 2, 2, 2, 69, 70, 7, 8, 2, 2, 70, 72, 5, 6, 4, 2, 71, 73, 5, 8, 5, 2, 72, 71, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 75, 3, 2, 2, 2, 74, 76, 5, 10, 6, 2, 75, 74, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 78, 7, 15, 2, 2, 78, 79, 5, 12, 7, 2, 79, 80, 7, 16, 2, 2, 80, 5, 3, 2, 2, 2, 81, 82, 5, 38, 20, 2, 82, 7, 3, 2, 2, 2, 83, 84, 5, 38, 20, 2, 84, 9, 3, 2, 2, 2, 85, 86, 7, 14, 2, 2, 86, 87, 5, 34, 18, 2, 87, 11, 3, 2, 2, 2, 88, 89, 5, 14, 8, 2, 89, 13, 3, 2, 2, 2, 90, 92, 5, 16, 9, 2, 91, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 15, 3, 2, 2, 2, 95, 100, 5, 26, 14, 2, 96, 100, 5, 44, 23, 2, 97, 100, 5, 42, 22, 2, 98, 100, 5, 24, 13, 2, 99, 95, 3, 2, 2, 2, 99, 96, 3, 2, 2, 2, 99, 97, 3, 2, 2, 2, 99, 98, 3, 2, 2, 2, 100, 17, 3, 2, 2, 2, 101, 102, 8, 10, 1, 2, 102, 115, 5, 20, 11, 2, 103, 105, 5, 60, 31, 2, 104, 103, 3, 2, 2, 2, 104, 105, 3, 2, 2, 2, 105, 106, 3, 2, 2, 2, 106, 115, 5, 22, 12, 2, 107, 109, 5, 60, 31, 2, 108, 107, 3, 2, 2, 2, 108, 109, 3, 2, 2, 2, 109, 110, 3, 2, 2, 2, 110, 111, 7, 35, 2, 2, 111, 112, 5, 18, 10, 2, 112, 113, 7, 36, 2, 2, 113, 115, 3, 2, 2, 2, 114, 101, 3, 2, 2, 2, 114, 104, 3, 2, 2, 2, 114, 108, 3, 2, 2, 2, 115, 126, 3, 2, 2, 2, 116, 117, 12, 6, 2, 2, 117, 118, 5, 52, 27, 2, 118, 119, 5, 18, 10, 7, 119, 125, 3, 2, 2, 2, 120, 121, 12, 5, 2, 2, 121, 122, 5, 54, 28, 2, 122, 123, 5, 18, 10, 6, 123, 125, 3, 2, 2, 2, 124, 116, 3, 2, 2, 2, 124, 120, 3, 2, 2, 2, 125, 128, 3, 2, 2, 2, 126, 124, 3, 2, 2, 2, 126, 127, 3, 2, 2, 2, 127, 19, 3, 2, 2, 2, 128, 126, 3, 2, 2, 2, 129, 130, 8, 11, 1, 2, 130, 136, 5, 22, 12, 2, 131, 132, 7, 35, 2, 2, 132, 133, 5, 20, 11, 2, 133, 134, 7, 36, 2, 2, 134, 136, 3, 2, 2, 2, 135, 129, 3, 2, 2, 2, 135, 131, 3, 2, 2, 2, 136, 147, 3, 2, 2, 2, 137, 138, 12, 6, 2, 2, 138, 139, 5, 50, 26, 2, 139, 140, 5, 20, 11, 7, 140, 146, 3, 2, 2, 2, 141, 142, 12, 5, 2, 2, 142, 143, 5, 48, 25, 2, 143, 144, 5, 20, 11, 6, 144, 146, 3, 2, 2, 2, 145, 137, 3, 2, 2, 2, 145, 141, 3, 2, 2, 2, 146, 149, 3, 2, 2, 2, 147, 145, 3, 2, 2, 2, 147, 148, 3, 2, 2, 2, 148, 21, 3, 2, 2, 2, 149, 147, 3, 2, 2, 2, 150, 155, 5, 44, 23, 2, 151, 155, 5, 42, 22, 2, 152, 155, 5, 30, 16, 2, 153, 155, 5, 46, 24, 2, 154, 150, 3, 2, 2, 2, 154, 151, 3, 2, 2, 2, 154, 152, 3, 2, 2, 2, 154, 153, 3, 2, 2, 2, 155, 23, 3, 2, 2, 2, 156, 159, 5, 46, 24, 2, 157, 160, 5, 56, 29, 2, 158, 160, 5, 58, 30, 2, 159, 157, 3, 2, 2, 2, 159, 158, 3, 2, 2, 2, 160, 161, 3, 2, 2, 2, 161, 162, 5, 20, 11, 2, 162, 25, 3, 2, 2, 2, 163, 164, 7, 3, 2, 2, 164, 165, 5, 18, 10, 2, 165, 166, 7, 33, 2, 2, 166, 167, 5, 14, 8, 2, 167, 169, 7, 34, 2, 2, 168, 170, 5, 28, 15, 2, 169, 168, 3, 2, 2, 2, 169, 170, 3, 2, 2, 2, 170, 27, 3, 2, 2, 2, 171, 172, 7, 4, 2, 2, 172, 173, 7, 33, 2, 2, 173, 174, 5, 14, 8, 2, 174, 175, 7, 34, 2, 2, 175, 29, 3, 2, 2, 2, 176, 182, 5, 40, 21, 2, 177, 182, 5, 34, 18, 2, 178, 182, 5, 36, 19, 2, 179, 182, 5, 38, 20, 2, 180, 182, 5, 62, 32, 2, 181, 176, 3, 2, 2, 2, 181, 177, 3, 2, 2, 2, 181, 178, 3, 2, 2, 2, 181, 179, 3, 2, 2, 2, 181, 180, 3, 2, 2, 2, 182, 31, 3, 2, 2, 2, 183, 188, 5, 30, 16, 2, 184, 188, 5, 46, 24, 2, 185, 188, 5, 42, 22, 2, 186, 188, 5, 44, 23, 2, 187, 183, 3, 2, 2, 2, 187, 184, 3, 2, 2, 2, 187, 185, 3, 2, 2, 2, 187, 186, 3, 2, 2, 2, 188, 198, 3, 2, 2, 2, 189, 194, 7, 5, 2, 2, 190, 195, 5, 30, 16, 2, 191, 195, 5, 46, 24, 2, 192, 195, 5, 42, 22, 2, 193, 195, 5, 44, 23, 2, 194, 190, 3, 2, 2, 2, 194, 191, 3, 2, 2, 2, 194, 192, 3, 2, 2, 2, 194, 193, 3, 2, 2, 2, 195, 197, 3, 2, 2, 2, 196, 189, 3, 2, 2, 2, 197, 200, 3, 2, 2, 2, 198, 196, 3, 2, 2, 2, 198, 199, 3, 2, 2, 2, 199, 33, 3, 2, 2, 2, 200, 198, 3, 2, 2, 2, 201, 203, 7, 20, 2, 2, 202, 201, 3, 2, 2, 2, 202, 203, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 205, 7, 18, 2, 2, 205, 35, 3, 2, 2, 2, 206, 208, 7, 20, 2, 2, 207, 206, 3, 2, 2, 2, 207, 208, 3, 2, 2, 2, 208, 209, 3, 2, 2, 2, 209, 210, 7, 40, 2, 2, 210, 37, 3, 2, 2, 2, 211, 212, 7, 38, 2, 2, 212, 39, 3, 2, 2, 2, 213, 214, 9, 2, 2, 2, 214, 41, 3, 2, 2, 2, 215, 216, 7, 17, 2, 2, 216, 218, 7, 35, 2, 2, 217, 219, 5, 32, 17, 2, 218, 217, 3, 2, 2, 2, 218, 219, 3, 2, 2, 2, 219, 220, 3, 2, 2, 2, 220, 221, 7, 36, 2, 2, 221, 43, 3, 2, 2, 2, 222, 223, 7, 39, 2, 2, 223, 225, 7, 35, 2, 2, 224, 226, 5, 32, 17, 2, 225, 224, 3, 2, 2, 2, 225, 226, 3, 2, 2, 2, 226, 227, 3, 2, 2, 2, 227, 228, 7, 36, 2, 2, 228, 45, 3, 2, 2, 2, 229, 230, 9, 3, 2, 2, 230, 47, 3, 2, 2, 2, 231, 232, 9, 4, 2, 2, 232, 49, 3, 2, 2, 2, 233, 234, 9, 5, 2, 2, 234, 51, 3, 2, 2, 2, 235, 236, 9, 6, 2, 2, 236, 53, 3, 2, 2, 2, 237, 238, 9, 7, 2, 2, 238, 55, 3, 2, 2, 2, 239, 240, 7, 30, 2, 2, 240, 57, 3, 2, 2, 2, 241, 242, 7, 31, 2, 2, 242, 59, 3, 2, 2, 2, 243, 244, 7, 29, 2, 2, 244, 61, 3, 2, 2, 2, 245, 246, 7, 6, 2, 2, 246, 63, 3, 2, 2, 2, 26, 67, 72, 75, 93, 99, 104, 108, 114, 124, 126, 135, 145, 147, 154, 159, 169, 181, 187, 194, 198, 202, 207, 218, 225] -------------------------------------------------------------------------------- /iantlr/alr/gengine.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | NIL=5 6 | RULE=6 7 | AND=7 8 | OR=8 9 | TRUE=9 10 | FALSE=10 11 | NULL_LITERAL=11 12 | SALIENCE=12 13 | BEGIN=13 14 | END=14 15 | SIMPLENAME=15 16 | INT=16 17 | PLUS=17 18 | MINUS=18 19 | DIV=19 20 | MUL=20 21 | EQUALS=21 22 | GT=22 23 | LT=23 24 | GTE=24 25 | LTE=25 26 | NOTEQUALS=26 27 | NOT=27 28 | ASSIGN=28 29 | SET=29 30 | SEMICOLON=30 31 | LR_BRACE=31 32 | RR_BRACE=32 33 | LR_BRACKET=33 34 | RR_BRACKET=34 35 | DOT=35 36 | DQUOTA_STRING=36 37 | DOTTEDNAME=37 38 | REAL_LITERAL=38 39 | SL_COMMENT=39 40 | WS=40 41 | 'if'=1 42 | 'else'=2 43 | ','=3 44 | '@name'=4 45 | '&&'=7 46 | '||'=8 47 | '+'=17 48 | '-'=18 49 | '/'=19 50 | '*'=20 51 | '=='=21 52 | '>'=22 53 | '<'=23 54 | '>='=24 55 | '<='=25 56 | '!='=26 57 | '!'=27 58 | ':='=28 59 | '='=29 60 | ';'=30 61 | '{'=31 62 | '}'=32 63 | '('=33 64 | ')'=34 65 | '.'=35 66 | -------------------------------------------------------------------------------- /iantlr/alr/gengineLexer.interp: -------------------------------------------------------------------------------- 1 | token literal names: 2 | null 3 | 'if' 4 | 'else' 5 | ',' 6 | '@name' 7 | null 8 | null 9 | '&&' 10 | '||' 11 | null 12 | null 13 | null 14 | null 15 | null 16 | null 17 | null 18 | null 19 | '+' 20 | '-' 21 | '/' 22 | '*' 23 | '==' 24 | '>' 25 | '<' 26 | '>=' 27 | '<=' 28 | '!=' 29 | '!' 30 | ':=' 31 | '=' 32 | ';' 33 | '{' 34 | '}' 35 | '(' 36 | ')' 37 | '.' 38 | null 39 | null 40 | null 41 | null 42 | null 43 | 44 | token symbolic names: 45 | null 46 | null 47 | null 48 | null 49 | null 50 | NIL 51 | RULE 52 | AND 53 | OR 54 | TRUE 55 | FALSE 56 | NULL_LITERAL 57 | SALIENCE 58 | BEGIN 59 | END 60 | SIMPLENAME 61 | INT 62 | PLUS 63 | MINUS 64 | DIV 65 | MUL 66 | EQUALS 67 | GT 68 | LT 69 | GTE 70 | LTE 71 | NOTEQUALS 72 | NOT 73 | ASSIGN 74 | SET 75 | SEMICOLON 76 | LR_BRACE 77 | RR_BRACE 78 | LR_BRACKET 79 | RR_BRACKET 80 | DOT 81 | DQUOTA_STRING 82 | DOTTEDNAME 83 | REAL_LITERAL 84 | SL_COMMENT 85 | WS 86 | 87 | rule names: 88 | T__0 89 | T__1 90 | T__2 91 | T__3 92 | DEC_DIGIT 93 | A 94 | B 95 | C 96 | D 97 | E 98 | F 99 | G 100 | H 101 | I 102 | J 103 | K 104 | L 105 | M 106 | N 107 | O 108 | P 109 | Q 110 | R 111 | S 112 | T 113 | U 114 | V 115 | W 116 | X 117 | Y 118 | Z 119 | EXPONENT_NUM_PART 120 | NIL 121 | RULE 122 | AND 123 | OR 124 | TRUE 125 | FALSE 126 | NULL_LITERAL 127 | SALIENCE 128 | BEGIN 129 | END 130 | SIMPLENAME 131 | INT 132 | PLUS 133 | MINUS 134 | DIV 135 | MUL 136 | EQUALS 137 | GT 138 | LT 139 | GTE 140 | LTE 141 | NOTEQUALS 142 | NOT 143 | ASSIGN 144 | SET 145 | SEMICOLON 146 | LR_BRACE 147 | RR_BRACE 148 | LR_BRACKET 149 | RR_BRACKET 150 | DOT 151 | DQUOTA_STRING 152 | DOTTEDNAME 153 | REAL_LITERAL 154 | SL_COMMENT 155 | WS 156 | 157 | channel names: 158 | DEFAULT_TOKEN_CHANNEL 159 | HIDDEN 160 | 161 | mode names: 162 | DEFAULT_MODE 163 | 164 | atn: 165 | [3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 42, 403, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 212, 10, 33, 3, 33, 6, 33, 215, 10, 33, 13, 33, 14, 33, 216, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 6, 44, 270, 10, 44, 13, 44, 14, 44, 271, 3, 45, 6, 45, 275, 10, 45, 13, 45, 14, 45, 276, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 7, 65, 328, 10, 65, 12, 65, 14, 65, 331, 11, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 6, 67, 340, 10, 67, 13, 67, 14, 67, 341, 5, 67, 344, 10, 67, 3, 67, 3, 67, 6, 67, 348, 10, 67, 13, 67, 14, 67, 349, 3, 67, 6, 67, 353, 10, 67, 13, 67, 14, 67, 354, 3, 67, 3, 67, 3, 67, 3, 67, 6, 67, 361, 10, 67, 13, 67, 14, 67, 362, 5, 67, 365, 10, 67, 3, 67, 3, 67, 6, 67, 369, 10, 67, 13, 67, 14, 67, 370, 3, 67, 3, 67, 3, 67, 6, 67, 376, 10, 67, 13, 67, 14, 67, 377, 3, 67, 3, 67, 5, 67, 382, 10, 67, 3, 68, 3, 68, 3, 68, 3, 68, 7, 68, 388, 10, 68, 12, 68, 14, 68, 391, 11, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 6, 69, 398, 10, 69, 13, 69, 14, 69, 399, 3, 69, 3, 69, 3, 389, 2, 70, 3, 3, 5, 4, 7, 5, 9, 6, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 2, 59, 2, 61, 2, 63, 2, 65, 2, 67, 7, 69, 8, 71, 9, 73, 10, 75, 11, 77, 12, 79, 13, 81, 14, 83, 15, 85, 16, 87, 17, 89, 18, 91, 19, 93, 20, 95, 21, 97, 22, 99, 23, 101, 24, 103, 25, 105, 26, 107, 27, 109, 28, 111, 29, 113, 30, 115, 31, 117, 32, 119, 33, 121, 34, 123, 35, 125, 36, 127, 37, 129, 38, 131, 39, 133, 40, 135, 41, 137, 42, 3, 2, 32, 3, 2, 50, 59, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 4, 2, 67, 92, 99, 124, 4, 2, 36, 36, 94, 94, 5, 2, 11, 12, 15, 15, 34, 34, 2, 394, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 3, 139, 3, 2, 2, 2, 5, 142, 3, 2, 2, 2, 7, 147, 3, 2, 2, 2, 9, 149, 3, 2, 2, 2, 11, 155, 3, 2, 2, 2, 13, 157, 3, 2, 2, 2, 15, 159, 3, 2, 2, 2, 17, 161, 3, 2, 2, 2, 19, 163, 3, 2, 2, 2, 21, 165, 3, 2, 2, 2, 23, 167, 3, 2, 2, 2, 25, 169, 3, 2, 2, 2, 27, 171, 3, 2, 2, 2, 29, 173, 3, 2, 2, 2, 31, 175, 3, 2, 2, 2, 33, 177, 3, 2, 2, 2, 35, 179, 3, 2, 2, 2, 37, 181, 3, 2, 2, 2, 39, 183, 3, 2, 2, 2, 41, 185, 3, 2, 2, 2, 43, 187, 3, 2, 2, 2, 45, 189, 3, 2, 2, 2, 47, 191, 3, 2, 2, 2, 49, 193, 3, 2, 2, 2, 51, 195, 3, 2, 2, 2, 53, 197, 3, 2, 2, 2, 55, 199, 3, 2, 2, 2, 57, 201, 3, 2, 2, 2, 59, 203, 3, 2, 2, 2, 61, 205, 3, 2, 2, 2, 63, 207, 3, 2, 2, 2, 65, 209, 3, 2, 2, 2, 67, 218, 3, 2, 2, 2, 69, 222, 3, 2, 2, 2, 71, 227, 3, 2, 2, 2, 73, 230, 3, 2, 2, 2, 75, 233, 3, 2, 2, 2, 77, 238, 3, 2, 2, 2, 79, 244, 3, 2, 2, 2, 81, 249, 3, 2, 2, 2, 83, 258, 3, 2, 2, 2, 85, 264, 3, 2, 2, 2, 87, 269, 3, 2, 2, 2, 89, 274, 3, 2, 2, 2, 91, 278, 3, 2, 2, 2, 93, 280, 3, 2, 2, 2, 95, 282, 3, 2, 2, 2, 97, 284, 3, 2, 2, 2, 99, 286, 3, 2, 2, 2, 101, 289, 3, 2, 2, 2, 103, 291, 3, 2, 2, 2, 105, 293, 3, 2, 2, 2, 107, 296, 3, 2, 2, 2, 109, 299, 3, 2, 2, 2, 111, 302, 3, 2, 2, 2, 113, 304, 3, 2, 2, 2, 115, 307, 3, 2, 2, 2, 117, 309, 3, 2, 2, 2, 119, 311, 3, 2, 2, 2, 121, 313, 3, 2, 2, 2, 123, 315, 3, 2, 2, 2, 125, 317, 3, 2, 2, 2, 127, 319, 3, 2, 2, 2, 129, 321, 3, 2, 2, 2, 131, 334, 3, 2, 2, 2, 133, 381, 3, 2, 2, 2, 135, 383, 3, 2, 2, 2, 137, 397, 3, 2, 2, 2, 139, 140, 7, 107, 2, 2, 140, 141, 7, 104, 2, 2, 141, 4, 3, 2, 2, 2, 142, 143, 7, 103, 2, 2, 143, 144, 7, 110, 2, 2, 144, 145, 7, 117, 2, 2, 145, 146, 7, 103, 2, 2, 146, 6, 3, 2, 2, 2, 147, 148, 7, 46, 2, 2, 148, 8, 3, 2, 2, 2, 149, 150, 7, 66, 2, 2, 150, 151, 7, 112, 2, 2, 151, 152, 7, 99, 2, 2, 152, 153, 7, 111, 2, 2, 153, 154, 7, 103, 2, 2, 154, 10, 3, 2, 2, 2, 155, 156, 9, 2, 2, 2, 156, 12, 3, 2, 2, 2, 157, 158, 9, 3, 2, 2, 158, 14, 3, 2, 2, 2, 159, 160, 9, 4, 2, 2, 160, 16, 3, 2, 2, 2, 161, 162, 9, 5, 2, 2, 162, 18, 3, 2, 2, 2, 163, 164, 9, 6, 2, 2, 164, 20, 3, 2, 2, 2, 165, 166, 9, 7, 2, 2, 166, 22, 3, 2, 2, 2, 167, 168, 9, 8, 2, 2, 168, 24, 3, 2, 2, 2, 169, 170, 9, 9, 2, 2, 170, 26, 3, 2, 2, 2, 171, 172, 9, 10, 2, 2, 172, 28, 3, 2, 2, 2, 173, 174, 9, 11, 2, 2, 174, 30, 3, 2, 2, 2, 175, 176, 9, 12, 2, 2, 176, 32, 3, 2, 2, 2, 177, 178, 9, 13, 2, 2, 178, 34, 3, 2, 2, 2, 179, 180, 9, 14, 2, 2, 180, 36, 3, 2, 2, 2, 181, 182, 9, 15, 2, 2, 182, 38, 3, 2, 2, 2, 183, 184, 9, 16, 2, 2, 184, 40, 3, 2, 2, 2, 185, 186, 9, 17, 2, 2, 186, 42, 3, 2, 2, 2, 187, 188, 9, 18, 2, 2, 188, 44, 3, 2, 2, 2, 189, 190, 9, 19, 2, 2, 190, 46, 3, 2, 2, 2, 191, 192, 9, 20, 2, 2, 192, 48, 3, 2, 2, 2, 193, 194, 9, 21, 2, 2, 194, 50, 3, 2, 2, 2, 195, 196, 9, 22, 2, 2, 196, 52, 3, 2, 2, 2, 197, 198, 9, 23, 2, 2, 198, 54, 3, 2, 2, 2, 199, 200, 9, 24, 2, 2, 200, 56, 3, 2, 2, 2, 201, 202, 9, 25, 2, 2, 202, 58, 3, 2, 2, 2, 203, 204, 9, 26, 2, 2, 204, 60, 3, 2, 2, 2, 205, 206, 9, 27, 2, 2, 206, 62, 3, 2, 2, 2, 207, 208, 9, 28, 2, 2, 208, 64, 3, 2, 2, 2, 209, 211, 7, 71, 2, 2, 210, 212, 7, 47, 2, 2, 211, 210, 3, 2, 2, 2, 211, 212, 3, 2, 2, 2, 212, 214, 3, 2, 2, 2, 213, 215, 5, 11, 6, 2, 214, 213, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 214, 3, 2, 2, 2, 216, 217, 3, 2, 2, 2, 217, 66, 3, 2, 2, 2, 218, 219, 5, 39, 20, 2, 219, 220, 5, 29, 15, 2, 220, 221, 5, 35, 18, 2, 221, 68, 3, 2, 2, 2, 222, 223, 5, 47, 24, 2, 223, 224, 5, 53, 27, 2, 224, 225, 5, 35, 18, 2, 225, 226, 5, 21, 11, 2, 226, 70, 3, 2, 2, 2, 227, 228, 7, 40, 2, 2, 228, 229, 7, 40, 2, 2, 229, 72, 3, 2, 2, 2, 230, 231, 7, 126, 2, 2, 231, 232, 7, 126, 2, 2, 232, 74, 3, 2, 2, 2, 233, 234, 5, 51, 26, 2, 234, 235, 5, 47, 24, 2, 235, 236, 5, 53, 27, 2, 236, 237, 5, 21, 11, 2, 237, 76, 3, 2, 2, 2, 238, 239, 5, 23, 12, 2, 239, 240, 5, 13, 7, 2, 240, 241, 5, 35, 18, 2, 241, 242, 5, 49, 25, 2, 242, 243, 5, 21, 11, 2, 243, 78, 3, 2, 2, 2, 244, 245, 5, 39, 20, 2, 245, 246, 5, 53, 27, 2, 246, 247, 5, 35, 18, 2, 247, 248, 5, 35, 18, 2, 248, 80, 3, 2, 2, 2, 249, 250, 5, 49, 25, 2, 250, 251, 5, 13, 7, 2, 251, 252, 5, 35, 18, 2, 252, 253, 5, 29, 15, 2, 253, 254, 5, 21, 11, 2, 254, 255, 5, 39, 20, 2, 255, 256, 5, 17, 9, 2, 256, 257, 5, 21, 11, 2, 257, 82, 3, 2, 2, 2, 258, 259, 5, 15, 8, 2, 259, 260, 5, 21, 11, 2, 260, 261, 5, 25, 13, 2, 261, 262, 5, 29, 15, 2, 262, 263, 5, 39, 20, 2, 263, 84, 3, 2, 2, 2, 264, 265, 5, 21, 11, 2, 265, 266, 5, 39, 20, 2, 266, 267, 5, 19, 10, 2, 267, 86, 3, 2, 2, 2, 268, 270, 9, 29, 2, 2, 269, 268, 3, 2, 2, 2, 270, 271, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 88, 3, 2, 2, 2, 273, 275, 4, 50, 59, 2, 274, 273, 3, 2, 2, 2, 275, 276, 3, 2, 2, 2, 276, 274, 3, 2, 2, 2, 276, 277, 3, 2, 2, 2, 277, 90, 3, 2, 2, 2, 278, 279, 7, 45, 2, 2, 279, 92, 3, 2, 2, 2, 280, 281, 7, 47, 2, 2, 281, 94, 3, 2, 2, 2, 282, 283, 7, 49, 2, 2, 283, 96, 3, 2, 2, 2, 284, 285, 7, 44, 2, 2, 285, 98, 3, 2, 2, 2, 286, 287, 7, 63, 2, 2, 287, 288, 7, 63, 2, 2, 288, 100, 3, 2, 2, 2, 289, 290, 7, 64, 2, 2, 290, 102, 3, 2, 2, 2, 291, 292, 7, 62, 2, 2, 292, 104, 3, 2, 2, 2, 293, 294, 7, 64, 2, 2, 294, 295, 7, 63, 2, 2, 295, 106, 3, 2, 2, 2, 296, 297, 7, 62, 2, 2, 297, 298, 7, 63, 2, 2, 298, 108, 3, 2, 2, 2, 299, 300, 7, 35, 2, 2, 300, 301, 7, 63, 2, 2, 301, 110, 3, 2, 2, 2, 302, 303, 7, 35, 2, 2, 303, 112, 3, 2, 2, 2, 304, 305, 7, 60, 2, 2, 305, 306, 7, 63, 2, 2, 306, 114, 3, 2, 2, 2, 307, 308, 7, 63, 2, 2, 308, 116, 3, 2, 2, 2, 309, 310, 7, 61, 2, 2, 310, 118, 3, 2, 2, 2, 311, 312, 7, 125, 2, 2, 312, 120, 3, 2, 2, 2, 313, 314, 7, 127, 2, 2, 314, 122, 3, 2, 2, 2, 315, 316, 7, 42, 2, 2, 316, 124, 3, 2, 2, 2, 317, 318, 7, 43, 2, 2, 318, 126, 3, 2, 2, 2, 319, 320, 7, 48, 2, 2, 320, 128, 3, 2, 2, 2, 321, 329, 7, 36, 2, 2, 322, 323, 7, 94, 2, 2, 323, 328, 11, 2, 2, 2, 324, 325, 7, 36, 2, 2, 325, 328, 7, 36, 2, 2, 326, 328, 10, 30, 2, 2, 327, 322, 3, 2, 2, 2, 327, 324, 3, 2, 2, 2, 327, 326, 3, 2, 2, 2, 328, 331, 3, 2, 2, 2, 329, 327, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 332, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 332, 333, 7, 36, 2, 2, 333, 130, 3, 2, 2, 2, 334, 335, 5, 87, 44, 2, 335, 336, 5, 127, 64, 2, 336, 337, 5, 87, 44, 2, 337, 132, 3, 2, 2, 2, 338, 340, 5, 11, 6, 2, 339, 338, 3, 2, 2, 2, 340, 341, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 341, 342, 3, 2, 2, 2, 342, 344, 3, 2, 2, 2, 343, 339, 3, 2, 2, 2, 343, 344, 3, 2, 2, 2, 344, 345, 3, 2, 2, 2, 345, 347, 7, 48, 2, 2, 346, 348, 5, 11, 6, 2, 347, 346, 3, 2, 2, 2, 348, 349, 3, 2, 2, 2, 349, 347, 3, 2, 2, 2, 349, 350, 3, 2, 2, 2, 350, 382, 3, 2, 2, 2, 351, 353, 5, 11, 6, 2, 352, 351, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 354, 355, 3, 2, 2, 2, 355, 356, 3, 2, 2, 2, 356, 357, 7, 48, 2, 2, 357, 358, 5, 65, 33, 2, 358, 382, 3, 2, 2, 2, 359, 361, 5, 11, 6, 2, 360, 359, 3, 2, 2, 2, 361, 362, 3, 2, 2, 2, 362, 360, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 365, 3, 2, 2, 2, 364, 360, 3, 2, 2, 2, 364, 365, 3, 2, 2, 2, 365, 366, 3, 2, 2, 2, 366, 368, 7, 48, 2, 2, 367, 369, 5, 11, 6, 2, 368, 367, 3, 2, 2, 2, 369, 370, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 370, 371, 3, 2, 2, 2, 371, 372, 3, 2, 2, 2, 372, 373, 5, 65, 33, 2, 373, 382, 3, 2, 2, 2, 374, 376, 5, 11, 6, 2, 375, 374, 3, 2, 2, 2, 376, 377, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 380, 5, 65, 33, 2, 380, 382, 3, 2, 2, 2, 381, 343, 3, 2, 2, 2, 381, 352, 3, 2, 2, 2, 381, 364, 3, 2, 2, 2, 381, 375, 3, 2, 2, 2, 382, 134, 3, 2, 2, 2, 383, 384, 7, 49, 2, 2, 384, 385, 7, 49, 2, 2, 385, 389, 3, 2, 2, 2, 386, 388, 11, 2, 2, 2, 387, 386, 3, 2, 2, 2, 388, 391, 3, 2, 2, 2, 389, 390, 3, 2, 2, 2, 389, 387, 3, 2, 2, 2, 390, 392, 3, 2, 2, 2, 391, 389, 3, 2, 2, 2, 392, 393, 7, 12, 2, 2, 393, 394, 3, 2, 2, 2, 394, 395, 8, 68, 2, 2, 395, 136, 3, 2, 2, 2, 396, 398, 9, 31, 2, 2, 397, 396, 3, 2, 2, 2, 398, 399, 3, 2, 2, 2, 399, 397, 3, 2, 2, 2, 399, 400, 3, 2, 2, 2, 400, 401, 3, 2, 2, 2, 401, 402, 8, 69, 2, 2, 402, 138, 3, 2, 2, 2, 20, 2, 211, 216, 271, 276, 327, 329, 341, 343, 349, 354, 362, 364, 370, 377, 381, 389, 399, 3, 8, 2, 2] -------------------------------------------------------------------------------- /iantlr/alr/gengineLexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | NIL=5 6 | RULE=6 7 | AND=7 8 | OR=8 9 | TRUE=9 10 | FALSE=10 11 | NULL_LITERAL=11 12 | SALIENCE=12 13 | BEGIN=13 14 | END=14 15 | SIMPLENAME=15 16 | INT=16 17 | PLUS=17 18 | MINUS=18 19 | DIV=19 20 | MUL=20 21 | EQUALS=21 22 | GT=22 23 | LT=23 24 | GTE=24 25 | LTE=25 26 | NOTEQUALS=26 27 | NOT=27 28 | ASSIGN=28 29 | SET=29 30 | SEMICOLON=30 31 | LR_BRACE=31 32 | RR_BRACE=32 33 | LR_BRACKET=33 34 | RR_BRACKET=34 35 | DOT=35 36 | DQUOTA_STRING=36 37 | DOTTEDNAME=37 38 | REAL_LITERAL=38 39 | SL_COMMENT=39 40 | WS=40 41 | 'if'=1 42 | 'else'=2 43 | ','=3 44 | '@name'=4 45 | '&&'=7 46 | '||'=8 47 | '+'=17 48 | '-'=18 49 | '/'=19 50 | '*'=20 51 | '=='=21 52 | '>'=22 53 | '<'=23 54 | '>='=24 55 | '<='=25 56 | '!='=26 57 | '!'=27 58 | ':='=28 59 | '='=29 60 | ';'=30 61 | '{'=31 62 | '}'=32 63 | '('=33 64 | ')'=34 65 | '.'=35 66 | -------------------------------------------------------------------------------- /iantlr/alr/gengine_base_listener.go: -------------------------------------------------------------------------------- 1 | // Code generated from /Users/renyunyi/go/src/gengine/iantlr/gengine.g4 by ANTLR 4.7.2. DO NOT EDIT. 2 | 3 | package parser // gengine 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | 7 | // BasegengineListener is a complete listener for a parse tree produced by gengineParser. 8 | type BasegengineListener struct{} 9 | 10 | var _ gengineListener = &BasegengineListener{} 11 | 12 | // VisitTerminal is called when a terminal node is visited. 13 | func (s *BasegengineListener) VisitTerminal(node antlr.TerminalNode) {} 14 | 15 | // VisitErrorNode is called when an error node is visited. 16 | func (s *BasegengineListener) VisitErrorNode(node antlr.ErrorNode) {} 17 | 18 | // EnterEveryRule is called when any rule is entered. 19 | func (s *BasegengineListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} 20 | 21 | // ExitEveryRule is called when any rule is exited. 22 | func (s *BasegengineListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} 23 | 24 | // EnterPrimary is called when production primary is entered. 25 | func (s *BasegengineListener) EnterPrimary(ctx *PrimaryContext) {} 26 | 27 | // ExitPrimary is called when production primary is exited. 28 | func (s *BasegengineListener) ExitPrimary(ctx *PrimaryContext) {} 29 | 30 | // EnterRuleEntity is called when production ruleEntity is entered. 31 | func (s *BasegengineListener) EnterRuleEntity(ctx *RuleEntityContext) {} 32 | 33 | // ExitRuleEntity is called when production ruleEntity is exited. 34 | func (s *BasegengineListener) ExitRuleEntity(ctx *RuleEntityContext) {} 35 | 36 | // EnterRuleName is called when production ruleName is entered. 37 | func (s *BasegengineListener) EnterRuleName(ctx *RuleNameContext) {} 38 | 39 | // ExitRuleName is called when production ruleName is exited. 40 | func (s *BasegengineListener) ExitRuleName(ctx *RuleNameContext) {} 41 | 42 | // EnterRuleDescription is called when production ruleDescription is entered. 43 | func (s *BasegengineListener) EnterRuleDescription(ctx *RuleDescriptionContext) {} 44 | 45 | // ExitRuleDescription is called when production ruleDescription is exited. 46 | func (s *BasegengineListener) ExitRuleDescription(ctx *RuleDescriptionContext) {} 47 | 48 | // EnterSalience is called when production salience is entered. 49 | func (s *BasegengineListener) EnterSalience(ctx *SalienceContext) {} 50 | 51 | // ExitSalience is called when production salience is exited. 52 | func (s *BasegengineListener) ExitSalience(ctx *SalienceContext) {} 53 | 54 | // EnterRuleContent is called when production ruleContent is entered. 55 | func (s *BasegengineListener) EnterRuleContent(ctx *RuleContentContext) {} 56 | 57 | // ExitRuleContent is called when production ruleContent is exited. 58 | func (s *BasegengineListener) ExitRuleContent(ctx *RuleContentContext) {} 59 | 60 | // EnterStatements is called when production statements is entered. 61 | func (s *BasegengineListener) EnterStatements(ctx *StatementsContext) {} 62 | 63 | // ExitStatements is called when production statements is exited. 64 | func (s *BasegengineListener) ExitStatements(ctx *StatementsContext) {} 65 | 66 | // EnterStatement is called when production statement is entered. 67 | func (s *BasegengineListener) EnterStatement(ctx *StatementContext) {} 68 | 69 | // ExitStatement is called when production statement is exited. 70 | func (s *BasegengineListener) ExitStatement(ctx *StatementContext) {} 71 | 72 | // EnterExpression is called when production expression is entered. 73 | func (s *BasegengineListener) EnterExpression(ctx *ExpressionContext) {} 74 | 75 | // ExitExpression is called when production expression is exited. 76 | func (s *BasegengineListener) ExitExpression(ctx *ExpressionContext) {} 77 | 78 | // EnterMathExpression is called when production mathExpression is entered. 79 | func (s *BasegengineListener) EnterMathExpression(ctx *MathExpressionContext) {} 80 | 81 | // ExitMathExpression is called when production mathExpression is exited. 82 | func (s *BasegengineListener) ExitMathExpression(ctx *MathExpressionContext) {} 83 | 84 | // EnterExpressionAtom is called when production expressionAtom is entered. 85 | func (s *BasegengineListener) EnterExpressionAtom(ctx *ExpressionAtomContext) {} 86 | 87 | // ExitExpressionAtom is called when production expressionAtom is exited. 88 | func (s *BasegengineListener) ExitExpressionAtom(ctx *ExpressionAtomContext) {} 89 | 90 | // EnterAssignment is called when production assignment is entered. 91 | func (s *BasegengineListener) EnterAssignment(ctx *AssignmentContext) {} 92 | 93 | // ExitAssignment is called when production assignment is exited. 94 | func (s *BasegengineListener) ExitAssignment(ctx *AssignmentContext) {} 95 | 96 | // EnterIfStmt is called when production ifStmt is entered. 97 | func (s *BasegengineListener) EnterIfStmt(ctx *IfStmtContext) {} 98 | 99 | // ExitIfStmt is called when production ifStmt is exited. 100 | func (s *BasegengineListener) ExitIfStmt(ctx *IfStmtContext) {} 101 | 102 | // EnterElseStmt is called when production elseStmt is entered. 103 | func (s *BasegengineListener) EnterElseStmt(ctx *ElseStmtContext) {} 104 | 105 | // ExitElseStmt is called when production elseStmt is exited. 106 | func (s *BasegengineListener) ExitElseStmt(ctx *ElseStmtContext) {} 107 | 108 | // EnterConstant is called when production constant is entered. 109 | func (s *BasegengineListener) EnterConstant(ctx *ConstantContext) {} 110 | 111 | // ExitConstant is called when production constant is exited. 112 | func (s *BasegengineListener) ExitConstant(ctx *ConstantContext) {} 113 | 114 | // EnterFunctionArgs is called when production functionArgs is entered. 115 | func (s *BasegengineListener) EnterFunctionArgs(ctx *FunctionArgsContext) {} 116 | 117 | // ExitFunctionArgs is called when production functionArgs is exited. 118 | func (s *BasegengineListener) ExitFunctionArgs(ctx *FunctionArgsContext) {} 119 | 120 | // EnterInteger is called when production integer is entered. 121 | func (s *BasegengineListener) EnterInteger(ctx *IntegerContext) {} 122 | 123 | // ExitInteger is called when production integer is exited. 124 | func (s *BasegengineListener) ExitInteger(ctx *IntegerContext) {} 125 | 126 | // EnterRealLiteral is called when production realLiteral is entered. 127 | func (s *BasegengineListener) EnterRealLiteral(ctx *RealLiteralContext) {} 128 | 129 | // ExitRealLiteral is called when production realLiteral is exited. 130 | func (s *BasegengineListener) ExitRealLiteral(ctx *RealLiteralContext) {} 131 | 132 | // EnterStringLiteral is called when production stringLiteral is entered. 133 | func (s *BasegengineListener) EnterStringLiteral(ctx *StringLiteralContext) {} 134 | 135 | // ExitStringLiteral is called when production stringLiteral is exited. 136 | func (s *BasegengineListener) ExitStringLiteral(ctx *StringLiteralContext) {} 137 | 138 | // EnterBooleanLiteral is called when production booleanLiteral is entered. 139 | func (s *BasegengineListener) EnterBooleanLiteral(ctx *BooleanLiteralContext) {} 140 | 141 | // ExitBooleanLiteral is called when production booleanLiteral is exited. 142 | func (s *BasegengineListener) ExitBooleanLiteral(ctx *BooleanLiteralContext) {} 143 | 144 | // EnterFunctionCall is called when production functionCall is entered. 145 | func (s *BasegengineListener) EnterFunctionCall(ctx *FunctionCallContext) {} 146 | 147 | // ExitFunctionCall is called when production functionCall is exited. 148 | func (s *BasegengineListener) ExitFunctionCall(ctx *FunctionCallContext) {} 149 | 150 | // EnterMethodCall is called when production methodCall is entered. 151 | func (s *BasegengineListener) EnterMethodCall(ctx *MethodCallContext) {} 152 | 153 | // ExitMethodCall is called when production methodCall is exited. 154 | func (s *BasegengineListener) ExitMethodCall(ctx *MethodCallContext) {} 155 | 156 | // EnterVariable is called when production variable is entered. 157 | func (s *BasegengineListener) EnterVariable(ctx *VariableContext) {} 158 | 159 | // ExitVariable is called when production variable is exited. 160 | func (s *BasegengineListener) ExitVariable(ctx *VariableContext) {} 161 | 162 | // EnterMathPmOperator is called when production mathPmOperator is entered. 163 | func (s *BasegengineListener) EnterMathPmOperator(ctx *MathPmOperatorContext) {} 164 | 165 | // ExitMathPmOperator is called when production mathPmOperator is exited. 166 | func (s *BasegengineListener) ExitMathPmOperator(ctx *MathPmOperatorContext) {} 167 | 168 | // EnterMathMdOperator is called when production mathMdOperator is entered. 169 | func (s *BasegengineListener) EnterMathMdOperator(ctx *MathMdOperatorContext) {} 170 | 171 | // ExitMathMdOperator is called when production mathMdOperator is exited. 172 | func (s *BasegengineListener) ExitMathMdOperator(ctx *MathMdOperatorContext) {} 173 | 174 | // EnterComparisonOperator is called when production comparisonOperator is entered. 175 | func (s *BasegengineListener) EnterComparisonOperator(ctx *ComparisonOperatorContext) {} 176 | 177 | // ExitComparisonOperator is called when production comparisonOperator is exited. 178 | func (s *BasegengineListener) ExitComparisonOperator(ctx *ComparisonOperatorContext) {} 179 | 180 | // EnterLogicalOperator is called when production logicalOperator is entered. 181 | func (s *BasegengineListener) EnterLogicalOperator(ctx *LogicalOperatorContext) {} 182 | 183 | // ExitLogicalOperator is called when production logicalOperator is exited. 184 | func (s *BasegengineListener) ExitLogicalOperator(ctx *LogicalOperatorContext) {} 185 | 186 | // EnterAssignOperator is called when production assignOperator is entered. 187 | func (s *BasegengineListener) EnterAssignOperator(ctx *AssignOperatorContext) {} 188 | 189 | // ExitAssignOperator is called when production assignOperator is exited. 190 | func (s *BasegengineListener) ExitAssignOperator(ctx *AssignOperatorContext) {} 191 | 192 | // EnterSetOperator is called when production setOperator is entered. 193 | func (s *BasegengineListener) EnterSetOperator(ctx *SetOperatorContext) {} 194 | 195 | // ExitSetOperator is called when production setOperator is exited. 196 | func (s *BasegengineListener) ExitSetOperator(ctx *SetOperatorContext) {} 197 | 198 | // EnterNotOperator is called when production notOperator is entered. 199 | func (s *BasegengineListener) EnterNotOperator(ctx *NotOperatorContext) {} 200 | 201 | // ExitNotOperator is called when production notOperator is exited. 202 | func (s *BasegengineListener) ExitNotOperator(ctx *NotOperatorContext) {} 203 | 204 | // EnterAtName is called when production atName is entered. 205 | func (s *BasegengineListener) EnterAtName(ctx *AtNameContext) {} 206 | 207 | // ExitAtName is called when production atName is exited. 208 | func (s *BasegengineListener) ExitAtName(ctx *AtNameContext) {} 209 | -------------------------------------------------------------------------------- /iantlr/alr/gengine_base_visitor.go: -------------------------------------------------------------------------------- 1 | // Code generated from /Users/renyunyi/go/src/gengine/iantlr/gengine.g4 by ANTLR 4.7.2. DO NOT EDIT. 2 | 3 | package parser // gengine 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | 7 | type BasegengineVisitor struct { 8 | *antlr.BaseParseTreeVisitor 9 | } 10 | 11 | func (v *BasegengineVisitor) VisitPrimary(ctx *PrimaryContext) interface{} { 12 | return v.VisitChildren(ctx) 13 | } 14 | 15 | func (v *BasegengineVisitor) VisitRuleEntity(ctx *RuleEntityContext) interface{} { 16 | return v.VisitChildren(ctx) 17 | } 18 | 19 | func (v *BasegengineVisitor) VisitRuleName(ctx *RuleNameContext) interface{} { 20 | return v.VisitChildren(ctx) 21 | } 22 | 23 | func (v *BasegengineVisitor) VisitRuleDescription(ctx *RuleDescriptionContext) interface{} { 24 | return v.VisitChildren(ctx) 25 | } 26 | 27 | func (v *BasegengineVisitor) VisitSalience(ctx *SalienceContext) interface{} { 28 | return v.VisitChildren(ctx) 29 | } 30 | 31 | func (v *BasegengineVisitor) VisitRuleContent(ctx *RuleContentContext) interface{} { 32 | return v.VisitChildren(ctx) 33 | } 34 | 35 | func (v *BasegengineVisitor) VisitStatements(ctx *StatementsContext) interface{} { 36 | return v.VisitChildren(ctx) 37 | } 38 | 39 | func (v *BasegengineVisitor) VisitStatement(ctx *StatementContext) interface{} { 40 | return v.VisitChildren(ctx) 41 | } 42 | 43 | func (v *BasegengineVisitor) VisitExpression(ctx *ExpressionContext) interface{} { 44 | return v.VisitChildren(ctx) 45 | } 46 | 47 | func (v *BasegengineVisitor) VisitMathExpression(ctx *MathExpressionContext) interface{} { 48 | return v.VisitChildren(ctx) 49 | } 50 | 51 | func (v *BasegengineVisitor) VisitExpressionAtom(ctx *ExpressionAtomContext) interface{} { 52 | return v.VisitChildren(ctx) 53 | } 54 | 55 | func (v *BasegengineVisitor) VisitAssignment(ctx *AssignmentContext) interface{} { 56 | return v.VisitChildren(ctx) 57 | } 58 | 59 | func (v *BasegengineVisitor) VisitIfStmt(ctx *IfStmtContext) interface{} { 60 | return v.VisitChildren(ctx) 61 | } 62 | 63 | func (v *BasegengineVisitor) VisitElseStmt(ctx *ElseStmtContext) interface{} { 64 | return v.VisitChildren(ctx) 65 | } 66 | 67 | func (v *BasegengineVisitor) VisitConstant(ctx *ConstantContext) interface{} { 68 | return v.VisitChildren(ctx) 69 | } 70 | 71 | func (v *BasegengineVisitor) VisitFunctionArgs(ctx *FunctionArgsContext) interface{} { 72 | return v.VisitChildren(ctx) 73 | } 74 | 75 | func (v *BasegengineVisitor) VisitInteger(ctx *IntegerContext) interface{} { 76 | return v.VisitChildren(ctx) 77 | } 78 | 79 | func (v *BasegengineVisitor) VisitRealLiteral(ctx *RealLiteralContext) interface{} { 80 | return v.VisitChildren(ctx) 81 | } 82 | 83 | func (v *BasegengineVisitor) VisitStringLiteral(ctx *StringLiteralContext) interface{} { 84 | return v.VisitChildren(ctx) 85 | } 86 | 87 | func (v *BasegengineVisitor) VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{} { 88 | return v.VisitChildren(ctx) 89 | } 90 | 91 | func (v *BasegengineVisitor) VisitFunctionCall(ctx *FunctionCallContext) interface{} { 92 | return v.VisitChildren(ctx) 93 | } 94 | 95 | func (v *BasegengineVisitor) VisitMethodCall(ctx *MethodCallContext) interface{} { 96 | return v.VisitChildren(ctx) 97 | } 98 | 99 | func (v *BasegengineVisitor) VisitVariable(ctx *VariableContext) interface{} { 100 | return v.VisitChildren(ctx) 101 | } 102 | 103 | func (v *BasegengineVisitor) VisitMathPmOperator(ctx *MathPmOperatorContext) interface{} { 104 | return v.VisitChildren(ctx) 105 | } 106 | 107 | func (v *BasegengineVisitor) VisitMathMdOperator(ctx *MathMdOperatorContext) interface{} { 108 | return v.VisitChildren(ctx) 109 | } 110 | 111 | func (v *BasegengineVisitor) VisitComparisonOperator(ctx *ComparisonOperatorContext) interface{} { 112 | return v.VisitChildren(ctx) 113 | } 114 | 115 | func (v *BasegengineVisitor) VisitLogicalOperator(ctx *LogicalOperatorContext) interface{} { 116 | return v.VisitChildren(ctx) 117 | } 118 | 119 | func (v *BasegengineVisitor) VisitAssignOperator(ctx *AssignOperatorContext) interface{} { 120 | return v.VisitChildren(ctx) 121 | } 122 | 123 | func (v *BasegengineVisitor) VisitSetOperator(ctx *SetOperatorContext) interface{} { 124 | return v.VisitChildren(ctx) 125 | } 126 | 127 | func (v *BasegengineVisitor) VisitNotOperator(ctx *NotOperatorContext) interface{} { 128 | return v.VisitChildren(ctx) 129 | } 130 | 131 | func (v *BasegengineVisitor) VisitAtName(ctx *AtNameContext) interface{} { 132 | return v.VisitChildren(ctx) 133 | } 134 | -------------------------------------------------------------------------------- /iantlr/alr/gengine_lexer.go: -------------------------------------------------------------------------------- 1 | // Code generated from /Users/renyunyi/go/src/gengine/iantlr/gengine.g4 by ANTLR 4.7.2. DO NOT EDIT. 2 | 3 | package parser 4 | 5 | import ( 6 | "fmt" 7 | "unicode" 8 | 9 | "github.com/antlr/antlr4/runtime/Go/antlr" 10 | ) 11 | // Suppress unused import error 12 | var _ = fmt.Printf 13 | var _ = unicode.IsLetter 14 | 15 | 16 | var serializedLexerAtn = []uint16{ 17 | 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 42, 403, 18 | 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 19 | 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 20 | 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 21 | 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 22 | 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 23 | 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 24 | 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 25 | 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 26 | 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 27 | 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 28 | 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 29 | 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 30 | 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 3, 2, 3, 31 | 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 32 | 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 33 | 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 34 | 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 35 | 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 36 | 3, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 37 | 31, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 212, 10, 33, 3, 33, 6, 33, 215, 38 | 10, 33, 13, 33, 14, 33, 216, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 39 | 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 40 | 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 40, 41 | 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42 | 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 43 | 3, 43, 3, 43, 3, 44, 6, 44, 270, 10, 44, 13, 44, 14, 44, 271, 3, 45, 6, 44 | 45, 275, 10, 45, 13, 45, 14, 45, 276, 3, 46, 3, 46, 3, 47, 3, 47, 3, 48, 45 | 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 3, 52, 3, 52, 3, 46 | 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 47 | 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 48 | 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 49 | 3, 65, 3, 65, 7, 65, 328, 10, 65, 12, 65, 14, 65, 331, 11, 65, 3, 65, 3, 50 | 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 6, 67, 340, 10, 67, 13, 67, 14, 51 | 67, 341, 5, 67, 344, 10, 67, 3, 67, 3, 67, 6, 67, 348, 10, 67, 13, 67, 52 | 14, 67, 349, 3, 67, 6, 67, 353, 10, 67, 13, 67, 14, 67, 354, 3, 67, 3, 53 | 67, 3, 67, 3, 67, 6, 67, 361, 10, 67, 13, 67, 14, 67, 362, 5, 67, 365, 54 | 10, 67, 3, 67, 3, 67, 6, 67, 369, 10, 67, 13, 67, 14, 67, 370, 3, 67, 3, 55 | 67, 3, 67, 6, 67, 376, 10, 67, 13, 67, 14, 67, 377, 3, 67, 3, 67, 5, 67, 56 | 382, 10, 67, 3, 68, 3, 68, 3, 68, 3, 68, 7, 68, 388, 10, 68, 12, 68, 14, 57 | 68, 391, 11, 68, 3, 68, 3, 68, 3, 68, 3, 68, 3, 69, 6, 69, 398, 10, 69, 58 | 13, 69, 14, 69, 399, 3, 69, 3, 69, 3, 389, 2, 70, 3, 3, 5, 4, 7, 5, 9, 59 | 6, 11, 2, 13, 2, 15, 2, 17, 2, 19, 2, 21, 2, 23, 2, 25, 2, 27, 2, 29, 2, 60 | 31, 2, 33, 2, 35, 2, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 61 | 2, 53, 2, 55, 2, 57, 2, 59, 2, 61, 2, 63, 2, 65, 2, 67, 7, 69, 8, 71, 9, 62 | 73, 10, 75, 11, 77, 12, 79, 13, 81, 14, 83, 15, 85, 16, 87, 17, 89, 18, 63 | 91, 19, 93, 20, 95, 21, 97, 22, 99, 23, 101, 24, 103, 25, 105, 26, 107, 64 | 27, 109, 28, 111, 29, 113, 30, 115, 31, 117, 32, 119, 33, 121, 34, 123, 65 | 35, 125, 36, 127, 37, 129, 38, 131, 39, 133, 40, 135, 41, 137, 42, 3, 2, 66 | 32, 3, 2, 50, 59, 4, 2, 67, 67, 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 67 | 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 68 | 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 69 | 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 70 | 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 71 | 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 72 | 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 73 | 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 74 | 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, 2, 92, 92, 124, 124, 4, 2, 67, 75 | 92, 99, 124, 4, 2, 36, 36, 94, 94, 5, 2, 11, 12, 15, 15, 34, 34, 2, 394, 76 | 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 77 | 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 78 | 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 79 | 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 80 | 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 81 | 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 82 | 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 83 | 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 84 | 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 85 | 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 86 | 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 3, 139, 3, 2, 2, 2, 87 | 5, 142, 3, 2, 2, 2, 7, 147, 3, 2, 2, 2, 9, 149, 3, 2, 2, 2, 11, 155, 3, 88 | 2, 2, 2, 13, 157, 3, 2, 2, 2, 15, 159, 3, 2, 2, 2, 17, 161, 3, 2, 2, 2, 89 | 19, 163, 3, 2, 2, 2, 21, 165, 3, 2, 2, 2, 23, 167, 3, 2, 2, 2, 25, 169, 90 | 3, 2, 2, 2, 27, 171, 3, 2, 2, 2, 29, 173, 3, 2, 2, 2, 31, 175, 3, 2, 2, 91 | 2, 33, 177, 3, 2, 2, 2, 35, 179, 3, 2, 2, 2, 37, 181, 3, 2, 2, 2, 39, 183, 92 | 3, 2, 2, 2, 41, 185, 3, 2, 2, 2, 43, 187, 3, 2, 2, 2, 45, 189, 3, 2, 2, 93 | 2, 47, 191, 3, 2, 2, 2, 49, 193, 3, 2, 2, 2, 51, 195, 3, 2, 2, 2, 53, 197, 94 | 3, 2, 2, 2, 55, 199, 3, 2, 2, 2, 57, 201, 3, 2, 2, 2, 59, 203, 3, 2, 2, 95 | 2, 61, 205, 3, 2, 2, 2, 63, 207, 3, 2, 2, 2, 65, 209, 3, 2, 2, 2, 67, 218, 96 | 3, 2, 2, 2, 69, 222, 3, 2, 2, 2, 71, 227, 3, 2, 2, 2, 73, 230, 3, 2, 2, 97 | 2, 75, 233, 3, 2, 2, 2, 77, 238, 3, 2, 2, 2, 79, 244, 3, 2, 2, 2, 81, 249, 98 | 3, 2, 2, 2, 83, 258, 3, 2, 2, 2, 85, 264, 3, 2, 2, 2, 87, 269, 3, 2, 2, 99 | 2, 89, 274, 3, 2, 2, 2, 91, 278, 3, 2, 2, 2, 93, 280, 3, 2, 2, 2, 95, 282, 100 | 3, 2, 2, 2, 97, 284, 3, 2, 2, 2, 99, 286, 3, 2, 2, 2, 101, 289, 3, 2, 2, 101 | 2, 103, 291, 3, 2, 2, 2, 105, 293, 3, 2, 2, 2, 107, 296, 3, 2, 2, 2, 109, 102 | 299, 3, 2, 2, 2, 111, 302, 3, 2, 2, 2, 113, 304, 3, 2, 2, 2, 115, 307, 103 | 3, 2, 2, 2, 117, 309, 3, 2, 2, 2, 119, 311, 3, 2, 2, 2, 121, 313, 3, 2, 104 | 2, 2, 123, 315, 3, 2, 2, 2, 125, 317, 3, 2, 2, 2, 127, 319, 3, 2, 2, 2, 105 | 129, 321, 3, 2, 2, 2, 131, 334, 3, 2, 2, 2, 133, 381, 3, 2, 2, 2, 135, 106 | 383, 3, 2, 2, 2, 137, 397, 3, 2, 2, 2, 139, 140, 7, 107, 2, 2, 140, 141, 107 | 7, 104, 2, 2, 141, 4, 3, 2, 2, 2, 142, 143, 7, 103, 2, 2, 143, 144, 7, 108 | 110, 2, 2, 144, 145, 7, 117, 2, 2, 145, 146, 7, 103, 2, 2, 146, 6, 3, 2, 109 | 2, 2, 147, 148, 7, 46, 2, 2, 148, 8, 3, 2, 2, 2, 149, 150, 7, 66, 2, 2, 110 | 150, 151, 7, 112, 2, 2, 151, 152, 7, 99, 2, 2, 152, 153, 7, 111, 2, 2, 111 | 153, 154, 7, 103, 2, 2, 154, 10, 3, 2, 2, 2, 155, 156, 9, 2, 2, 2, 156, 112 | 12, 3, 2, 2, 2, 157, 158, 9, 3, 2, 2, 158, 14, 3, 2, 2, 2, 159, 160, 9, 113 | 4, 2, 2, 160, 16, 3, 2, 2, 2, 161, 162, 9, 5, 2, 2, 162, 18, 3, 2, 2, 2, 114 | 163, 164, 9, 6, 2, 2, 164, 20, 3, 2, 2, 2, 165, 166, 9, 7, 2, 2, 166, 22, 115 | 3, 2, 2, 2, 167, 168, 9, 8, 2, 2, 168, 24, 3, 2, 2, 2, 169, 170, 9, 9, 116 | 2, 2, 170, 26, 3, 2, 2, 2, 171, 172, 9, 10, 2, 2, 172, 28, 3, 2, 2, 2, 117 | 173, 174, 9, 11, 2, 2, 174, 30, 3, 2, 2, 2, 175, 176, 9, 12, 2, 2, 176, 118 | 32, 3, 2, 2, 2, 177, 178, 9, 13, 2, 2, 178, 34, 3, 2, 2, 2, 179, 180, 9, 119 | 14, 2, 2, 180, 36, 3, 2, 2, 2, 181, 182, 9, 15, 2, 2, 182, 38, 3, 2, 2, 120 | 2, 183, 184, 9, 16, 2, 2, 184, 40, 3, 2, 2, 2, 185, 186, 9, 17, 2, 2, 186, 121 | 42, 3, 2, 2, 2, 187, 188, 9, 18, 2, 2, 188, 44, 3, 2, 2, 2, 189, 190, 9, 122 | 19, 2, 2, 190, 46, 3, 2, 2, 2, 191, 192, 9, 20, 2, 2, 192, 48, 3, 2, 2, 123 | 2, 193, 194, 9, 21, 2, 2, 194, 50, 3, 2, 2, 2, 195, 196, 9, 22, 2, 2, 196, 124 | 52, 3, 2, 2, 2, 197, 198, 9, 23, 2, 2, 198, 54, 3, 2, 2, 2, 199, 200, 9, 125 | 24, 2, 2, 200, 56, 3, 2, 2, 2, 201, 202, 9, 25, 2, 2, 202, 58, 3, 2, 2, 126 | 2, 203, 204, 9, 26, 2, 2, 204, 60, 3, 2, 2, 2, 205, 206, 9, 27, 2, 2, 206, 127 | 62, 3, 2, 2, 2, 207, 208, 9, 28, 2, 2, 208, 64, 3, 2, 2, 2, 209, 211, 7, 128 | 71, 2, 2, 210, 212, 7, 47, 2, 2, 211, 210, 3, 2, 2, 2, 211, 212, 3, 2, 129 | 2, 2, 212, 214, 3, 2, 2, 2, 213, 215, 5, 11, 6, 2, 214, 213, 3, 2, 2, 2, 130 | 215, 216, 3, 2, 2, 2, 216, 214, 3, 2, 2, 2, 216, 217, 3, 2, 2, 2, 217, 131 | 66, 3, 2, 2, 2, 218, 219, 5, 39, 20, 2, 219, 220, 5, 29, 15, 2, 220, 221, 132 | 5, 35, 18, 2, 221, 68, 3, 2, 2, 2, 222, 223, 5, 47, 24, 2, 223, 224, 5, 133 | 53, 27, 2, 224, 225, 5, 35, 18, 2, 225, 226, 5, 21, 11, 2, 226, 70, 3, 134 | 2, 2, 2, 227, 228, 7, 40, 2, 2, 228, 229, 7, 40, 2, 2, 229, 72, 3, 2, 2, 135 | 2, 230, 231, 7, 126, 2, 2, 231, 232, 7, 126, 2, 2, 232, 74, 3, 2, 2, 2, 136 | 233, 234, 5, 51, 26, 2, 234, 235, 5, 47, 24, 2, 235, 236, 5, 53, 27, 2, 137 | 236, 237, 5, 21, 11, 2, 237, 76, 3, 2, 2, 2, 238, 239, 5, 23, 12, 2, 239, 138 | 240, 5, 13, 7, 2, 240, 241, 5, 35, 18, 2, 241, 242, 5, 49, 25, 2, 242, 139 | 243, 5, 21, 11, 2, 243, 78, 3, 2, 2, 2, 244, 245, 5, 39, 20, 2, 245, 246, 140 | 5, 53, 27, 2, 246, 247, 5, 35, 18, 2, 247, 248, 5, 35, 18, 2, 248, 80, 141 | 3, 2, 2, 2, 249, 250, 5, 49, 25, 2, 250, 251, 5, 13, 7, 2, 251, 252, 5, 142 | 35, 18, 2, 252, 253, 5, 29, 15, 2, 253, 254, 5, 21, 11, 2, 254, 255, 5, 143 | 39, 20, 2, 255, 256, 5, 17, 9, 2, 256, 257, 5, 21, 11, 2, 257, 82, 3, 2, 144 | 2, 2, 258, 259, 5, 15, 8, 2, 259, 260, 5, 21, 11, 2, 260, 261, 5, 25, 13, 145 | 2, 261, 262, 5, 29, 15, 2, 262, 263, 5, 39, 20, 2, 263, 84, 3, 2, 2, 2, 146 | 264, 265, 5, 21, 11, 2, 265, 266, 5, 39, 20, 2, 266, 267, 5, 19, 10, 2, 147 | 267, 86, 3, 2, 2, 2, 268, 270, 9, 29, 2, 2, 269, 268, 3, 2, 2, 2, 270, 148 | 271, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 88, 3, 149 | 2, 2, 2, 273, 275, 4, 50, 59, 2, 274, 273, 3, 2, 2, 2, 275, 276, 3, 2, 150 | 2, 2, 276, 274, 3, 2, 2, 2, 276, 277, 3, 2, 2, 2, 277, 90, 3, 2, 2, 2, 151 | 278, 279, 7, 45, 2, 2, 279, 92, 3, 2, 2, 2, 280, 281, 7, 47, 2, 2, 281, 152 | 94, 3, 2, 2, 2, 282, 283, 7, 49, 2, 2, 283, 96, 3, 2, 2, 2, 284, 285, 7, 153 | 44, 2, 2, 285, 98, 3, 2, 2, 2, 286, 287, 7, 63, 2, 2, 287, 288, 7, 63, 154 | 2, 2, 288, 100, 3, 2, 2, 2, 289, 290, 7, 64, 2, 2, 290, 102, 3, 2, 2, 2, 155 | 291, 292, 7, 62, 2, 2, 292, 104, 3, 2, 2, 2, 293, 294, 7, 64, 2, 2, 294, 156 | 295, 7, 63, 2, 2, 295, 106, 3, 2, 2, 2, 296, 297, 7, 62, 2, 2, 297, 298, 157 | 7, 63, 2, 2, 298, 108, 3, 2, 2, 2, 299, 300, 7, 35, 2, 2, 300, 301, 7, 158 | 63, 2, 2, 301, 110, 3, 2, 2, 2, 302, 303, 7, 35, 2, 2, 303, 112, 3, 2, 159 | 2, 2, 304, 305, 7, 60, 2, 2, 305, 306, 7, 63, 2, 2, 306, 114, 3, 2, 2, 160 | 2, 307, 308, 7, 63, 2, 2, 308, 116, 3, 2, 2, 2, 309, 310, 7, 61, 2, 2, 161 | 310, 118, 3, 2, 2, 2, 311, 312, 7, 125, 2, 2, 312, 120, 3, 2, 2, 2, 313, 162 | 314, 7, 127, 2, 2, 314, 122, 3, 2, 2, 2, 315, 316, 7, 42, 2, 2, 316, 124, 163 | 3, 2, 2, 2, 317, 318, 7, 43, 2, 2, 318, 126, 3, 2, 2, 2, 319, 320, 7, 48, 164 | 2, 2, 320, 128, 3, 2, 2, 2, 321, 329, 7, 36, 2, 2, 322, 323, 7, 94, 2, 165 | 2, 323, 328, 11, 2, 2, 2, 324, 325, 7, 36, 2, 2, 325, 328, 7, 36, 2, 2, 166 | 326, 328, 10, 30, 2, 2, 327, 322, 3, 2, 2, 2, 327, 324, 3, 2, 2, 2, 327, 167 | 326, 3, 2, 2, 2, 328, 331, 3, 2, 2, 2, 329, 327, 3, 2, 2, 2, 329, 330, 168 | 3, 2, 2, 2, 330, 332, 3, 2, 2, 2, 331, 329, 3, 2, 2, 2, 332, 333, 7, 36, 169 | 2, 2, 333, 130, 3, 2, 2, 2, 334, 335, 5, 87, 44, 2, 335, 336, 5, 127, 64, 170 | 2, 336, 337, 5, 87, 44, 2, 337, 132, 3, 2, 2, 2, 338, 340, 5, 11, 6, 2, 171 | 339, 338, 3, 2, 2, 2, 340, 341, 3, 2, 2, 2, 341, 339, 3, 2, 2, 2, 341, 172 | 342, 3, 2, 2, 2, 342, 344, 3, 2, 2, 2, 343, 339, 3, 2, 2, 2, 343, 344, 173 | 3, 2, 2, 2, 344, 345, 3, 2, 2, 2, 345, 347, 7, 48, 2, 2, 346, 348, 5, 11, 174 | 6, 2, 347, 346, 3, 2, 2, 2, 348, 349, 3, 2, 2, 2, 349, 347, 3, 2, 2, 2, 175 | 349, 350, 3, 2, 2, 2, 350, 382, 3, 2, 2, 2, 351, 353, 5, 11, 6, 2, 352, 176 | 351, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354, 352, 3, 2, 2, 2, 354, 355, 177 | 3, 2, 2, 2, 355, 356, 3, 2, 2, 2, 356, 357, 7, 48, 2, 2, 357, 358, 5, 65, 178 | 33, 2, 358, 382, 3, 2, 2, 2, 359, 361, 5, 11, 6, 2, 360, 359, 3, 2, 2, 179 | 2, 361, 362, 3, 2, 2, 2, 362, 360, 3, 2, 2, 2, 362, 363, 3, 2, 2, 2, 363, 180 | 365, 3, 2, 2, 2, 364, 360, 3, 2, 2, 2, 364, 365, 3, 2, 2, 2, 365, 366, 181 | 3, 2, 2, 2, 366, 368, 7, 48, 2, 2, 367, 369, 5, 11, 6, 2, 368, 367, 3, 182 | 2, 2, 2, 369, 370, 3, 2, 2, 2, 370, 368, 3, 2, 2, 2, 370, 371, 3, 2, 2, 183 | 2, 371, 372, 3, 2, 2, 2, 372, 373, 5, 65, 33, 2, 373, 382, 3, 2, 2, 2, 184 | 374, 376, 5, 11, 6, 2, 375, 374, 3, 2, 2, 2, 376, 377, 3, 2, 2, 2, 377, 185 | 375, 3, 2, 2, 2, 377, 378, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 380, 186 | 5, 65, 33, 2, 380, 382, 3, 2, 2, 2, 381, 343, 3, 2, 2, 2, 381, 352, 3, 187 | 2, 2, 2, 381, 364, 3, 2, 2, 2, 381, 375, 3, 2, 2, 2, 382, 134, 3, 2, 2, 188 | 2, 383, 384, 7, 49, 2, 2, 384, 385, 7, 49, 2, 2, 385, 389, 3, 2, 2, 2, 189 | 386, 388, 11, 2, 2, 2, 387, 386, 3, 2, 2, 2, 388, 391, 3, 2, 2, 2, 389, 190 | 390, 3, 2, 2, 2, 389, 387, 3, 2, 2, 2, 390, 392, 3, 2, 2, 2, 391, 389, 191 | 3, 2, 2, 2, 392, 393, 7, 12, 2, 2, 393, 394, 3, 2, 2, 2, 394, 395, 8, 68, 192 | 2, 2, 395, 136, 3, 2, 2, 2, 396, 398, 9, 31, 2, 2, 397, 396, 3, 2, 2, 2, 193 | 398, 399, 3, 2, 2, 2, 399, 397, 3, 2, 2, 2, 399, 400, 3, 2, 2, 2, 400, 194 | 401, 3, 2, 2, 2, 401, 402, 8, 69, 2, 2, 402, 138, 3, 2, 2, 2, 20, 2, 211, 195 | 216, 271, 276, 327, 329, 341, 343, 349, 354, 362, 364, 370, 377, 381, 389, 196 | 399, 3, 8, 2, 2, 197 | } 198 | 199 | var lexerDeserializer = antlr.NewATNDeserializer(nil) 200 | var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) 201 | 202 | var lexerChannelNames = []string{ 203 | "DEFAULT_TOKEN_CHANNEL", "HIDDEN", 204 | } 205 | 206 | var lexerModeNames = []string{ 207 | "DEFAULT_MODE", 208 | } 209 | 210 | var lexerLiteralNames = []string{ 211 | "", "'if'", "'else'", "','", "'@name'", "", "", "'&&'", "'||'", "", "", 212 | "", "", "", "", "", "", "'+'", "'-'", "'/'", "'*'", "'=='", "'>'", "'<'", 213 | "'>='", "'<='", "'!='", "'!'", "':='", "'='", "';'", "'{'", "'}'", "'('", 214 | "')'", "'.'", 215 | } 216 | 217 | var lexerSymbolicNames = []string{ 218 | "", "", "", "", "", "NIL", "RULE", "AND", "OR", "TRUE", "FALSE", "NULL_LITERAL", 219 | "SALIENCE", "BEGIN", "END", "SIMPLENAME", "INT", "PLUS", "MINUS", "DIV", 220 | "MUL", "EQUALS", "GT", "LT", "GTE", "LTE", "NOTEQUALS", "NOT", "ASSIGN", 221 | "SET", "SEMICOLON", "LR_BRACE", "RR_BRACE", "LR_BRACKET", "RR_BRACKET", 222 | "DOT", "DQUOTA_STRING", "DOTTEDNAME", "REAL_LITERAL", "SL_COMMENT", "WS", 223 | } 224 | 225 | var lexerRuleNames = []string{ 226 | "T__0", "T__1", "T__2", "T__3", "DEC_DIGIT", "A", "B", "C", "D", "E", "F", 227 | "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", 228 | "V", "W", "X", "Y", "Z", "EXPONENT_NUM_PART", "NIL", "RULE", "AND", "OR", 229 | "TRUE", "FALSE", "NULL_LITERAL", "SALIENCE", "BEGIN", "END", "SIMPLENAME", 230 | "INT", "PLUS", "MINUS", "DIV", "MUL", "EQUALS", "GT", "LT", "GTE", "LTE", 231 | "NOTEQUALS", "NOT", "ASSIGN", "SET", "SEMICOLON", "LR_BRACE", "RR_BRACE", 232 | "LR_BRACKET", "RR_BRACKET", "DOT", "DQUOTA_STRING", "DOTTEDNAME", "REAL_LITERAL", 233 | "SL_COMMENT", "WS", 234 | } 235 | 236 | type gengineLexer struct { 237 | *antlr.BaseLexer 238 | channelNames []string 239 | modeNames []string 240 | // TODO: EOF string 241 | } 242 | 243 | var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState)) 244 | 245 | func init() { 246 | for index, ds := range lexerAtn.DecisionToState { 247 | lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) 248 | } 249 | } 250 | 251 | func NewgengineLexer(input antlr.CharStream) *gengineLexer { 252 | 253 | l := new(gengineLexer) 254 | 255 | l.BaseLexer = antlr.NewBaseLexer(input) 256 | l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) 257 | 258 | l.channelNames = lexerChannelNames 259 | l.modeNames = lexerModeNames 260 | l.RuleNames = lexerRuleNames 261 | l.LiteralNames = lexerLiteralNames 262 | l.SymbolicNames = lexerSymbolicNames 263 | l.GrammarFileName = "gengine.g4" 264 | // TODO: l.EOF = antlr.TokenEOF 265 | 266 | return l 267 | } 268 | 269 | // gengineLexer tokens. 270 | const ( 271 | gengineLexerT__0 = 1 272 | gengineLexerT__1 = 2 273 | gengineLexerT__2 = 3 274 | gengineLexerT__3 = 4 275 | gengineLexerNIL = 5 276 | gengineLexerRULE = 6 277 | gengineLexerAND = 7 278 | gengineLexerOR = 8 279 | gengineLexerTRUE = 9 280 | gengineLexerFALSE = 10 281 | gengineLexerNULL_LITERAL = 11 282 | gengineLexerSALIENCE = 12 283 | gengineLexerBEGIN = 13 284 | gengineLexerEND = 14 285 | gengineLexerSIMPLENAME = 15 286 | gengineLexerINT = 16 287 | gengineLexerPLUS = 17 288 | gengineLexerMINUS = 18 289 | gengineLexerDIV = 19 290 | gengineLexerMUL = 20 291 | gengineLexerEQUALS = 21 292 | gengineLexerGT = 22 293 | gengineLexerLT = 23 294 | gengineLexerGTE = 24 295 | gengineLexerLTE = 25 296 | gengineLexerNOTEQUALS = 26 297 | gengineLexerNOT = 27 298 | gengineLexerASSIGN = 28 299 | gengineLexerSET = 29 300 | gengineLexerSEMICOLON = 30 301 | gengineLexerLR_BRACE = 31 302 | gengineLexerRR_BRACE = 32 303 | gengineLexerLR_BRACKET = 33 304 | gengineLexerRR_BRACKET = 34 305 | gengineLexerDOT = 35 306 | gengineLexerDQUOTA_STRING = 36 307 | gengineLexerDOTTEDNAME = 37 308 | gengineLexerREAL_LITERAL = 38 309 | gengineLexerSL_COMMENT = 39 310 | gengineLexerWS = 40 311 | ) 312 | 313 | -------------------------------------------------------------------------------- /iantlr/alr/gengine_listener.go: -------------------------------------------------------------------------------- 1 | // Code generated from /Users/renyunyi/go/src/gengine/iantlr/gengine.g4 by ANTLR 4.7.2. DO NOT EDIT. 2 | 3 | package parser // gengine 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | 7 | // gengineListener is a complete listener for a parse tree produced by gengineParser. 8 | type gengineListener interface { 9 | antlr.ParseTreeListener 10 | 11 | // EnterPrimary is called when entering the primary production. 12 | EnterPrimary(c *PrimaryContext) 13 | 14 | // EnterRuleEntity is called when entering the ruleEntity production. 15 | EnterRuleEntity(c *RuleEntityContext) 16 | 17 | // EnterRuleName is called when entering the ruleName production. 18 | EnterRuleName(c *RuleNameContext) 19 | 20 | // EnterRuleDescription is called when entering the ruleDescription production. 21 | EnterRuleDescription(c *RuleDescriptionContext) 22 | 23 | // EnterSalience is called when entering the salience production. 24 | EnterSalience(c *SalienceContext) 25 | 26 | // EnterRuleContent is called when entering the ruleContent production. 27 | EnterRuleContent(c *RuleContentContext) 28 | 29 | // EnterStatements is called when entering the statements production. 30 | EnterStatements(c *StatementsContext) 31 | 32 | // EnterStatement is called when entering the statement production. 33 | EnterStatement(c *StatementContext) 34 | 35 | // EnterExpression is called when entering the expression production. 36 | EnterExpression(c *ExpressionContext) 37 | 38 | // EnterMathExpression is called when entering the mathExpression production. 39 | EnterMathExpression(c *MathExpressionContext) 40 | 41 | // EnterExpressionAtom is called when entering the expressionAtom production. 42 | EnterExpressionAtom(c *ExpressionAtomContext) 43 | 44 | // EnterAssignment is called when entering the assignment production. 45 | EnterAssignment(c *AssignmentContext) 46 | 47 | // EnterIfStmt is called when entering the ifStmt production. 48 | EnterIfStmt(c *IfStmtContext) 49 | 50 | // EnterElseStmt is called when entering the elseStmt production. 51 | EnterElseStmt(c *ElseStmtContext) 52 | 53 | // EnterConstant is called when entering the constant production. 54 | EnterConstant(c *ConstantContext) 55 | 56 | // EnterFunctionArgs is called when entering the functionArgs production. 57 | EnterFunctionArgs(c *FunctionArgsContext) 58 | 59 | // EnterInteger is called when entering the integer production. 60 | EnterInteger(c *IntegerContext) 61 | 62 | // EnterRealLiteral is called when entering the realLiteral production. 63 | EnterRealLiteral(c *RealLiteralContext) 64 | 65 | // EnterStringLiteral is called when entering the stringLiteral production. 66 | EnterStringLiteral(c *StringLiteralContext) 67 | 68 | // EnterBooleanLiteral is called when entering the booleanLiteral production. 69 | EnterBooleanLiteral(c *BooleanLiteralContext) 70 | 71 | // EnterFunctionCall is called when entering the functionCall production. 72 | EnterFunctionCall(c *FunctionCallContext) 73 | 74 | // EnterMethodCall is called when entering the methodCall production. 75 | EnterMethodCall(c *MethodCallContext) 76 | 77 | // EnterVariable is called when entering the variable production. 78 | EnterVariable(c *VariableContext) 79 | 80 | // EnterMathPmOperator is called when entering the mathPmOperator production. 81 | EnterMathPmOperator(c *MathPmOperatorContext) 82 | 83 | // EnterMathMdOperator is called when entering the mathMdOperator production. 84 | EnterMathMdOperator(c *MathMdOperatorContext) 85 | 86 | // EnterComparisonOperator is called when entering the comparisonOperator production. 87 | EnterComparisonOperator(c *ComparisonOperatorContext) 88 | 89 | // EnterLogicalOperator is called when entering the logicalOperator production. 90 | EnterLogicalOperator(c *LogicalOperatorContext) 91 | 92 | // EnterAssignOperator is called when entering the assignOperator production. 93 | EnterAssignOperator(c *AssignOperatorContext) 94 | 95 | // EnterSetOperator is called when entering the setOperator production. 96 | EnterSetOperator(c *SetOperatorContext) 97 | 98 | // EnterNotOperator is called when entering the notOperator production. 99 | EnterNotOperator(c *NotOperatorContext) 100 | 101 | // EnterAtName is called when entering the atName production. 102 | EnterAtName(c *AtNameContext) 103 | 104 | // ExitPrimary is called when exiting the primary production. 105 | ExitPrimary(c *PrimaryContext) 106 | 107 | // ExitRuleEntity is called when exiting the ruleEntity production. 108 | ExitRuleEntity(c *RuleEntityContext) 109 | 110 | // ExitRuleName is called when exiting the ruleName production. 111 | ExitRuleName(c *RuleNameContext) 112 | 113 | // ExitRuleDescription is called when exiting the ruleDescription production. 114 | ExitRuleDescription(c *RuleDescriptionContext) 115 | 116 | // ExitSalience is called when exiting the salience production. 117 | ExitSalience(c *SalienceContext) 118 | 119 | // ExitRuleContent is called when exiting the ruleContent production. 120 | ExitRuleContent(c *RuleContentContext) 121 | 122 | // ExitStatements is called when exiting the statements production. 123 | ExitStatements(c *StatementsContext) 124 | 125 | // ExitStatement is called when exiting the statement production. 126 | ExitStatement(c *StatementContext) 127 | 128 | // ExitExpression is called when exiting the expression production. 129 | ExitExpression(c *ExpressionContext) 130 | 131 | // ExitMathExpression is called when exiting the mathExpression production. 132 | ExitMathExpression(c *MathExpressionContext) 133 | 134 | // ExitExpressionAtom is called when exiting the expressionAtom production. 135 | ExitExpressionAtom(c *ExpressionAtomContext) 136 | 137 | // ExitAssignment is called when exiting the assignment production. 138 | ExitAssignment(c *AssignmentContext) 139 | 140 | // ExitIfStmt is called when exiting the ifStmt production. 141 | ExitIfStmt(c *IfStmtContext) 142 | 143 | // ExitElseStmt is called when exiting the elseStmt production. 144 | ExitElseStmt(c *ElseStmtContext) 145 | 146 | // ExitConstant is called when exiting the constant production. 147 | ExitConstant(c *ConstantContext) 148 | 149 | // ExitFunctionArgs is called when exiting the functionArgs production. 150 | ExitFunctionArgs(c *FunctionArgsContext) 151 | 152 | // ExitInteger is called when exiting the integer production. 153 | ExitInteger(c *IntegerContext) 154 | 155 | // ExitRealLiteral is called when exiting the realLiteral production. 156 | ExitRealLiteral(c *RealLiteralContext) 157 | 158 | // ExitStringLiteral is called when exiting the stringLiteral production. 159 | ExitStringLiteral(c *StringLiteralContext) 160 | 161 | // ExitBooleanLiteral is called when exiting the booleanLiteral production. 162 | ExitBooleanLiteral(c *BooleanLiteralContext) 163 | 164 | // ExitFunctionCall is called when exiting the functionCall production. 165 | ExitFunctionCall(c *FunctionCallContext) 166 | 167 | // ExitMethodCall is called when exiting the methodCall production. 168 | ExitMethodCall(c *MethodCallContext) 169 | 170 | // ExitVariable is called when exiting the variable production. 171 | ExitVariable(c *VariableContext) 172 | 173 | // ExitMathPmOperator is called when exiting the mathPmOperator production. 174 | ExitMathPmOperator(c *MathPmOperatorContext) 175 | 176 | // ExitMathMdOperator is called when exiting the mathMdOperator production. 177 | ExitMathMdOperator(c *MathMdOperatorContext) 178 | 179 | // ExitComparisonOperator is called when exiting the comparisonOperator production. 180 | ExitComparisonOperator(c *ComparisonOperatorContext) 181 | 182 | // ExitLogicalOperator is called when exiting the logicalOperator production. 183 | ExitLogicalOperator(c *LogicalOperatorContext) 184 | 185 | // ExitAssignOperator is called when exiting the assignOperator production. 186 | ExitAssignOperator(c *AssignOperatorContext) 187 | 188 | // ExitSetOperator is called when exiting the setOperator production. 189 | ExitSetOperator(c *SetOperatorContext) 190 | 191 | // ExitNotOperator is called when exiting the notOperator production. 192 | ExitNotOperator(c *NotOperatorContext) 193 | 194 | // ExitAtName is called when exiting the atName production. 195 | ExitAtName(c *AtNameContext) 196 | } 197 | -------------------------------------------------------------------------------- /iantlr/alr/gengine_visitor.go: -------------------------------------------------------------------------------- 1 | // Code generated from /Users/renyunyi/go/src/gengine/iantlr/gengine.g4 by ANTLR 4.7.2. DO NOT EDIT. 2 | 3 | package parser // gengine 4 | 5 | import "github.com/antlr/antlr4/runtime/Go/antlr" 6 | // A complete Visitor for a parse tree produced by gengineParser. 7 | type gengineVisitor interface { 8 | antlr.ParseTreeVisitor 9 | 10 | // Visit a parse tree produced by gengineParser#primary. 11 | VisitPrimary(ctx *PrimaryContext) interface{} 12 | 13 | // Visit a parse tree produced by gengineParser#ruleEntity. 14 | VisitRuleEntity(ctx *RuleEntityContext) interface{} 15 | 16 | // Visit a parse tree produced by gengineParser#ruleName. 17 | VisitRuleName(ctx *RuleNameContext) interface{} 18 | 19 | // Visit a parse tree produced by gengineParser#ruleDescription. 20 | VisitRuleDescription(ctx *RuleDescriptionContext) interface{} 21 | 22 | // Visit a parse tree produced by gengineParser#salience. 23 | VisitSalience(ctx *SalienceContext) interface{} 24 | 25 | // Visit a parse tree produced by gengineParser#ruleContent. 26 | VisitRuleContent(ctx *RuleContentContext) interface{} 27 | 28 | // Visit a parse tree produced by gengineParser#statements. 29 | VisitStatements(ctx *StatementsContext) interface{} 30 | 31 | // Visit a parse tree produced by gengineParser#statement. 32 | VisitStatement(ctx *StatementContext) interface{} 33 | 34 | // Visit a parse tree produced by gengineParser#expression. 35 | VisitExpression(ctx *ExpressionContext) interface{} 36 | 37 | // Visit a parse tree produced by gengineParser#mathExpression. 38 | VisitMathExpression(ctx *MathExpressionContext) interface{} 39 | 40 | // Visit a parse tree produced by gengineParser#expressionAtom. 41 | VisitExpressionAtom(ctx *ExpressionAtomContext) interface{} 42 | 43 | // Visit a parse tree produced by gengineParser#assignment. 44 | VisitAssignment(ctx *AssignmentContext) interface{} 45 | 46 | // Visit a parse tree produced by gengineParser#ifStmt. 47 | VisitIfStmt(ctx *IfStmtContext) interface{} 48 | 49 | // Visit a parse tree produced by gengineParser#elseStmt. 50 | VisitElseStmt(ctx *ElseStmtContext) interface{} 51 | 52 | // Visit a parse tree produced by gengineParser#constant. 53 | VisitConstant(ctx *ConstantContext) interface{} 54 | 55 | // Visit a parse tree produced by gengineParser#functionArgs. 56 | VisitFunctionArgs(ctx *FunctionArgsContext) interface{} 57 | 58 | // Visit a parse tree produced by gengineParser#integer. 59 | VisitInteger(ctx *IntegerContext) interface{} 60 | 61 | // Visit a parse tree produced by gengineParser#realLiteral. 62 | VisitRealLiteral(ctx *RealLiteralContext) interface{} 63 | 64 | // Visit a parse tree produced by gengineParser#stringLiteral. 65 | VisitStringLiteral(ctx *StringLiteralContext) interface{} 66 | 67 | // Visit a parse tree produced by gengineParser#booleanLiteral. 68 | VisitBooleanLiteral(ctx *BooleanLiteralContext) interface{} 69 | 70 | // Visit a parse tree produced by gengineParser#functionCall. 71 | VisitFunctionCall(ctx *FunctionCallContext) interface{} 72 | 73 | // Visit a parse tree produced by gengineParser#methodCall. 74 | VisitMethodCall(ctx *MethodCallContext) interface{} 75 | 76 | // Visit a parse tree produced by gengineParser#variable. 77 | VisitVariable(ctx *VariableContext) interface{} 78 | 79 | // Visit a parse tree produced by gengineParser#mathPmOperator. 80 | VisitMathPmOperator(ctx *MathPmOperatorContext) interface{} 81 | 82 | // Visit a parse tree produced by gengineParser#mathMdOperator. 83 | VisitMathMdOperator(ctx *MathMdOperatorContext) interface{} 84 | 85 | // Visit a parse tree produced by gengineParser#comparisonOperator. 86 | VisitComparisonOperator(ctx *ComparisonOperatorContext) interface{} 87 | 88 | // Visit a parse tree produced by gengineParser#logicalOperator. 89 | VisitLogicalOperator(ctx *LogicalOperatorContext) interface{} 90 | 91 | // Visit a parse tree produced by gengineParser#assignOperator. 92 | VisitAssignOperator(ctx *AssignOperatorContext) interface{} 93 | 94 | // Visit a parse tree produced by gengineParser#setOperator. 95 | VisitSetOperator(ctx *SetOperatorContext) interface{} 96 | 97 | // Visit a parse tree produced by gengineParser#notOperator. 98 | VisitNotOperator(ctx *NotOperatorContext) interface{} 99 | 100 | // Visit a parse tree produced by gengineParser#atName. 101 | VisitAtName(ctx *AtNameContext) interface{} 102 | 103 | } -------------------------------------------------------------------------------- /iantlr/gengine.g4: -------------------------------------------------------------------------------- 1 | grammar gengine; 2 | 3 | primary: ruleEntity+; 4 | 5 | ruleEntity: RULE ruleName ruleDescription? salience? BEGIN ruleContent END; 6 | ruleName : stringLiteral; 7 | ruleDescription : stringLiteral; 8 | salience : SALIENCE integer; 9 | ruleContent : statements; 10 | statements: statement+; 11 | 12 | statement : ifStmt | methodCall | functionCall | assignment; 13 | 14 | expression : mathExpression 15 | | expression comparisonOperator expression 16 | | expression logicalOperator expression 17 | | notOperator ? expressionAtom 18 | | notOperator ? '(' expression ')' 19 | ; 20 | 21 | mathExpression : mathExpression mathMdOperator mathExpression 22 | | mathExpression mathPmOperator mathExpression 23 | | expressionAtom 24 | | '(' mathExpression ')' 25 | ; 26 | 27 | expressionAtom 28 | : methodCall 29 | | functionCall 30 | | constant 31 | | variable 32 | ; 33 | 34 | assignment : variable (assignOperator | setOperator) mathExpression; 35 | 36 | ifStmt : 'if' expression '{' statements '}' elseStmt? ; 37 | 38 | elseStmt : 'else' '{' statements '}'; 39 | 40 | constant 41 | : booleanLiteral 42 | | integer 43 | | realLiteral 44 | | stringLiteral 45 | | atName 46 | ; 47 | 48 | functionArgs 49 | : (constant | variable | functionCall | methodCall ) (','(constant | variable | functionCall | methodCall ))* 50 | ; 51 | 52 | integer : '-'? INT; 53 | 54 | realLiteral : MINUS? REAL_LITERAL; 55 | 56 | stringLiteral: DQUOTA_STRING ; 57 | 58 | booleanLiteral : TRUE | FALSE; 59 | 60 | functionCall : SIMPLENAME '(' functionArgs? ')'; 61 | 62 | methodCall : DOTTEDNAME '(' functionArgs? ')'; 63 | 64 | variable : SIMPLENAME | DOTTEDNAME ; 65 | 66 | mathPmOperator : PLUS | MINUS ; 67 | 68 | mathMdOperator : MUL | DIV ; 69 | 70 | comparisonOperator : GT | LT | GTE | LTE | EQUALS | NOTEQUALS ; 71 | 72 | logicalOperator : AND | OR ; 73 | 74 | assignOperator: ASSIGN ; 75 | 76 | setOperator: SET; 77 | 78 | notOperator: NOT; 79 | 80 | atName : '@name'; 81 | 82 | fragment DEC_DIGIT : [0-9]; 83 | fragment A : [aA] ; 84 | fragment B : [bB] ; 85 | fragment C : [cC] ; 86 | fragment D : [dD] ; 87 | fragment E : [eE] ; 88 | fragment F : [fF] ; 89 | fragment G : [gG] ; 90 | fragment H : [hH] ; 91 | fragment I : [iI] ; 92 | fragment J : [jJ] ; 93 | fragment K : [kK] ; 94 | fragment L : [lL] ; 95 | fragment M : [mM] ; 96 | fragment N : [nN] ; 97 | fragment O : [oO] ; 98 | fragment P : [pP] ; 99 | fragment Q : [qQ] ; 100 | fragment R : [rR] ; 101 | fragment S : [sS] ; 102 | fragment T : [tT] ; 103 | fragment U : [uU] ; 104 | fragment V : [vV] ; 105 | fragment W : [wW] ; 106 | fragment X : [xX] ; 107 | fragment Y : [yY] ; 108 | fragment Z : [zZ] ; 109 | fragment EXPONENT_NUM_PART : 'E' '-'? DEC_DIGIT+; 110 | 111 | NIL : N I L; 112 | RULE : R U L E ; 113 | AND : '&&' ; 114 | OR : '||' ; 115 | 116 | TRUE : T R U E ; 117 | FALSE : F A L S E ; 118 | NULL_LITERAL : N U L L ; 119 | SALIENCE : S A L I E N C E ; 120 | BEGIN : B E G I N; 121 | END : E N D; 122 | 123 | SIMPLENAME : ('a'..'z' |'A'..'Z')+ ; 124 | 125 | INT : '0'..'9' + ; 126 | PLUS : '+' ; 127 | MINUS : '-' ; 128 | DIV : '/' ; 129 | MUL : '*' ; 130 | 131 | EQUALS : '==' ; 132 | GT : '>' ; 133 | LT : '<' ; 134 | GTE : '>=' ; 135 | LTE : '<=' ; 136 | NOTEQUALS : '!=' ; 137 | NOT : '!' ; 138 | 139 | ASSIGN : ':=' ; 140 | SET : '='; 141 | 142 | SEMICOLON : ';' ; 143 | LR_BRACE : '{'; 144 | RR_BRACE : '}'; 145 | LR_BRACKET : '('; 146 | RR_BRACKET : ')'; 147 | DOT : '.' ; 148 | DQUOTA_STRING : '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'; 149 | DOTTEDNAME : SIMPLENAME DOT SIMPLENAME ; 150 | REAL_LITERAL : (DEC_DIGIT+)? '.' DEC_DIGIT+ 151 | | DEC_DIGIT+ '.' EXPONENT_NUM_PART 152 | | (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART) 153 | | DEC_DIGIT+ EXPONENT_NUM_PART 154 | ; 155 | 156 | SL_COMMENT: '//' .*? '\n' -> skip ; 157 | 158 | WS : [ \t\n\r]+ -> skip ; -------------------------------------------------------------------------------- /iparser/GengineErrorListener.go: -------------------------------------------------------------------------------- 1 | package iparser 2 | 3 | import ( 4 | "github.com/antlr/antlr4/runtime/Go/antlr" 5 | "strconv" 6 | ) 7 | 8 | 9 | type GengineErrorListener struct { 10 | antlr.ErrorListener 11 | GrammarErrors []string 12 | } 13 | 14 | func NewGengineErrorListener() *GengineErrorListener{ 15 | return &GengineErrorListener{ 16 | GrammarErrors:make([]string, 0), 17 | } 18 | } 19 | 20 | /** 21 | syntax err check 22 | */ 23 | func (el *GengineErrorListener)SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException){ 24 | el.GrammarErrors = append(el.GrammarErrors, "line" + " " + strconv.Itoa(line) + ":" + strconv.Itoa(column) +" "+ msg) 25 | } 26 | 27 | 28 | func (el *GengineErrorListener)ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet){ 29 | 30 | } 31 | func (el *GengineErrorListener)ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet){ 32 | 33 | } 34 | func (el *GengineErrorListener)ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet){ 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /iparser/GengineParserListener.go: -------------------------------------------------------------------------------- 1 | package iparser 2 | 3 | import ( 4 | "gengine/base" 5 | "gengine/core/errors" 6 | parser "gengine/iantlr/alr" 7 | "github.com/antlr/antlr4/runtime/Go/antlr" 8 | "github.com/golang-collections/collections/stack" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | func NewGengineParserListener(ctx *base.KnowledgeContext) *GengineParserListener { 14 | return &GengineParserListener{ 15 | Stack: stack.New(), 16 | KnowledgeContext: ctx, 17 | ParseErrors: make([]string, 0), 18 | } 19 | } 20 | 21 | type GengineParserListener struct { 22 | parser.BasegengineListener 23 | ParseErrors []string 24 | 25 | KnowledgeContext *base.KnowledgeContext 26 | Stack *stack.Stack 27 | ruleName string 28 | } 29 | 30 | func (g *GengineParserListener)AddError(e error) { 31 | g.ParseErrors = append(g.ParseErrors, e.Error()) 32 | } 33 | 34 | func (g *GengineParserListener) VisitTerminal(node antlr.TerminalNode) {} 35 | 36 | func (g *GengineParserListener) VisitErrorNode(node antlr.ErrorNode) { 37 | g.AddError(errors.Errorf("cannot recognize '"+ node.GetText()+ "' ")) 38 | } 39 | 40 | func (g *GengineParserListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} 41 | 42 | func (g *GengineParserListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} 43 | 44 | func (g *GengineParserListener) EnterPrimary(ctx *parser.PrimaryContext) {} 45 | 46 | func (g *GengineParserListener) ExitPrimary(ctx *parser.PrimaryContext) {} 47 | 48 | func (g *GengineParserListener) EnterRuleEntity(ctx *parser.RuleEntityContext) { 49 | if len(g.ParseErrors) > 0 { 50 | return 51 | } 52 | entity := &base.RuleEntity{} 53 | g.Stack.Push(entity) 54 | } 55 | 56 | func (g *GengineParserListener) ExitRuleEntity(ctx *parser.RuleEntityContext) { 57 | if len(g.ParseErrors) > 0 { 58 | return 59 | } 60 | entity := g.Stack.Pop().(*base.RuleEntity) 61 | if _, ok := g.KnowledgeContext.RuleEntities[entity.RuleName]; ok { 62 | g.AddError(errors.Errorf("already existed entity's name \"%s\"", entity.RuleName)) 63 | return 64 | } 65 | g.KnowledgeContext.RuleEntities[entity.RuleName] = entity 66 | } 67 | 68 | func (g *GengineParserListener) EnterRuleName(ctx *parser.RuleNameContext) {} 69 | 70 | func (g *GengineParserListener) ExitRuleName(ctx *parser.RuleNameContext) { 71 | if len(g.ParseErrors) > 0 { 72 | return 73 | } 74 | ruleName := ctx.GetText() 75 | entity := g.Stack.Peek().(*base.RuleEntity) 76 | g.ruleName = ruleName 77 | entity.RuleName = ruleName 78 | } 79 | 80 | func (g *GengineParserListener) EnterSalience(ctx *parser.SalienceContext) { 81 | } 82 | 83 | func (g *GengineParserListener) ExitSalience(ctx *parser.SalienceContext) {} 84 | 85 | func (g *GengineParserListener) EnterRuleDescription(ctx *parser.RuleDescriptionContext) {} 86 | 87 | func (g *GengineParserListener) ExitRuleDescription(ctx *parser.RuleDescriptionContext) { 88 | if len(g.ParseErrors) > 0 { 89 | return 90 | } 91 | ruleDescription := ctx.GetText() 92 | entity := g.Stack.Peek().(*base.RuleEntity) 93 | entity.RuleDescription = ruleDescription 94 | } 95 | 96 | func (g *GengineParserListener) EnterRuleContent(ctx *parser.RuleContentContext) { 97 | if len(g.ParseErrors) > 0 { 98 | return 99 | } 100 | ruleContent := &base.RuleContent{} 101 | g.Stack.Push(ruleContent) 102 | } 103 | 104 | func (g *GengineParserListener) ExitRuleContent(ctx *parser.RuleContentContext) { 105 | if len(g.ParseErrors) > 0 { 106 | return 107 | } 108 | ruleContent := g.Stack.Pop().(*base.RuleContent) 109 | entity := g.Stack.Peek().(*base.RuleEntity) 110 | entity.RuleContent = ruleContent 111 | } 112 | 113 | func (g *GengineParserListener) EnterAssignment(ctx *parser.AssignmentContext) { 114 | if len(g.ParseErrors) > 0 { 115 | return 116 | } 117 | assignment := &base.Assignment{} 118 | g.Stack.Push(assignment) 119 | } 120 | 121 | func (g *GengineParserListener) ExitAssignment(ctx *parser.AssignmentContext) { 122 | if len(g.ParseErrors) > 0 { 123 | return 124 | } 125 | assignment := g.Stack.Pop().(*base.Assignment) 126 | statement := g.Stack.Peek().(*base.Statement) 127 | statement.Assignment = assignment 128 | } 129 | 130 | func (g *GengineParserListener) EnterMathExpression(ctx *parser.MathExpressionContext) { 131 | if len(g.ParseErrors) > 0 { 132 | return 133 | } 134 | me := &base.MathExpression{} 135 | g.Stack.Push(me) 136 | 137 | } 138 | 139 | func (g *GengineParserListener) ExitMathExpression(ctx *parser.MathExpressionContext) { 140 | if len(g.ParseErrors) > 0 { 141 | return 142 | } 143 | expr := g.Stack.Pop().(*base.MathExpression) 144 | holder := g.Stack.Peek().(base.MathExpressionHolder) 145 | err := holder.AcceptMathExpression(expr) 146 | if err != nil { 147 | g.AddError(err) 148 | } 149 | } 150 | 151 | func (g *GengineParserListener) EnterExpression(ctx *parser.ExpressionContext) { 152 | if len(g.ParseErrors) > 0 { 153 | return 154 | } 155 | expression := &base.Expression{} 156 | g.Stack.Push(expression) 157 | } 158 | 159 | func (g *GengineParserListener) ExitExpression(ctx *parser.ExpressionContext) { 160 | if len(g.ParseErrors) > 0 { 161 | return 162 | } 163 | expr := g.Stack.Pop().(*base.Expression) 164 | holder := g.Stack.Peek().(base.ExpressionHolder) 165 | err := holder.AcceptExpression(expr) 166 | if err != nil { 167 | g.AddError(err) 168 | } 169 | } 170 | 171 | func (g *GengineParserListener) EnterExpressionAtom(ctx *parser.ExpressionAtomContext) { 172 | if len(g.ParseErrors) > 0 { 173 | return 174 | } 175 | exprAtom := &base.ExpressionAtom{} 176 | g.Stack.Push(exprAtom) 177 | } 178 | 179 | func (g *GengineParserListener) ExitExpressionAtom(ctx *parser.ExpressionAtomContext) { 180 | if len(g.ParseErrors) > 0 { 181 | return 182 | } 183 | exprAtom := g.Stack.Pop().(*base.ExpressionAtom) 184 | holder := g.Stack.Peek().(base.ExpressionAtomHolder) 185 | err := holder.AcceptExpressionAtom(exprAtom) 186 | if err != nil { 187 | g.AddError(err) 188 | } 189 | } 190 | 191 | func (g *GengineParserListener) EnterMethodCall(ctx *parser.MethodCallContext) { 192 | if len(g.ParseErrors) > 0 { 193 | return 194 | } 195 | funcCall := &base.MethodCall{ 196 | MethodName: ctx.DOTTEDNAME().GetText(), 197 | } 198 | g.Stack.Push(funcCall) 199 | } 200 | 201 | func (g *GengineParserListener) ExitMethodCall(ctx *parser.MethodCallContext) { 202 | if len(g.ParseErrors) > 0 { 203 | return 204 | } 205 | methodCall := g.Stack.Pop().(*base.MethodCall) 206 | holder := g.Stack.Peek().(base.MethodCallHolder) 207 | err := holder.AcceptMethodCall(methodCall) 208 | if err != nil { 209 | g.AddError(err) 210 | } 211 | } 212 | 213 | func (g *GengineParserListener) EnterFunctionCall(ctx *parser.FunctionCallContext) { 214 | if len(g.ParseErrors) > 0 { 215 | return 216 | } 217 | funcCall := &base.FunctionCall{ 218 | FunctionName: ctx.SIMPLENAME().GetText(), 219 | } 220 | g.Stack.Push(funcCall) 221 | } 222 | 223 | func (g *GengineParserListener) ExitFunctionCall(ctx *parser.FunctionCallContext) { 224 | if len(g.ParseErrors) > 0 { 225 | return 226 | } 227 | funcCall := g.Stack.Pop().(*base.FunctionCall) 228 | holder := g.Stack.Peek().(base.FunctionCallHolder) 229 | err := holder.AcceptFunctionCall(funcCall) 230 | if err != nil { 231 | g.AddError(err) 232 | } 233 | } 234 | 235 | func (g *GengineParserListener) EnterFunctionArgs(ctx *parser.FunctionArgsContext) { 236 | if len(g.ParseErrors) > 0 { 237 | return 238 | } 239 | funcArg := &base.Args{ 240 | ArgList: make([]*base.Arg, 0), 241 | } 242 | g.Stack.Push(funcArg) 243 | } 244 | 245 | func (g *GengineParserListener) ExitFunctionArgs(ctx *parser.FunctionArgsContext) { 246 | if len(g.ParseErrors) > 0 { 247 | return 248 | } 249 | funcArgs := g.Stack.Pop().(*base.Args) 250 | argHolder := g.Stack.Peek().(base.ArgsHolder) 251 | err := argHolder.AcceptArgs(funcArgs) 252 | if err != nil { 253 | g.AddError(err) 254 | } 255 | } 256 | 257 | func (g *GengineParserListener) EnterLogicalOperator(ctx *parser.LogicalOperatorContext) {} 258 | 259 | func (g *GengineParserListener) ExitLogicalOperator(ctx *parser.LogicalOperatorContext) { 260 | if len(g.ParseErrors) > 0 { 261 | return 262 | } 263 | expr := g.Stack.Peek().(*base.Expression) 264 | // && and || 265 | expr.LogicalOperator = ctx.GetText() 266 | } 267 | 268 | func (g *GengineParserListener) EnterNotOperator(ctx *parser.NotOperatorContext) {} 269 | 270 | func (g *GengineParserListener) ExitNotOperator(ctx *parser.NotOperatorContext) { 271 | if len(g.ParseErrors) > 0 { 272 | return 273 | } 274 | expr := g.Stack.Peek().(*base.Expression) 275 | // ! 276 | expr.NotOperator = ctx.GetText() 277 | } 278 | 279 | func (g *GengineParserListener) EnterVariable(ctx *parser.VariableContext) {} 280 | 281 | func (g *GengineParserListener) ExitVariable(ctx *parser.VariableContext) { 282 | if len(g.ParseErrors) > 0 { 283 | return 284 | } 285 | varName := ctx.GetText() 286 | holder := g.Stack.Peek().(base.VariableHolder) 287 | err := holder.AcceptVariable(varName) 288 | if err != nil { 289 | g.AddError(err) 290 | } 291 | } 292 | 293 | func (g *GengineParserListener) EnterMathPmOperator(ctx *parser.MathPmOperatorContext) {} 294 | 295 | func (g *GengineParserListener) ExitMathPmOperator(ctx *parser.MathPmOperatorContext) { 296 | if len(g.ParseErrors) > 0 { 297 | return 298 | } 299 | expr := g.Stack.Peek().(*base.MathExpression) 300 | // + - 301 | expr.MathPmOperator = ctx.GetText() 302 | } 303 | 304 | func (g *GengineParserListener) EnterMathMdOperator(ctx *parser.MathMdOperatorContext) {} 305 | 306 | func (g *GengineParserListener) ExitMathMdOperator(ctx *parser.MathMdOperatorContext) { 307 | if len(g.ParseErrors) > 0 { 308 | return 309 | } 310 | expr := g.Stack.Peek().(*base.MathExpression) 311 | // * / 312 | expr.MathMdOperator = ctx.GetText() 313 | } 314 | 315 | func (g *GengineParserListener) EnterComparisonOperator(ctx *parser.ComparisonOperatorContext) {} 316 | 317 | func (g *GengineParserListener) ExitComparisonOperator(ctx *parser.ComparisonOperatorContext) { 318 | if len(g.ParseErrors) > 0 { 319 | return 320 | } 321 | expr := g.Stack.Peek().(*base.Expression) 322 | // == != < > <= >= 323 | expr.ComparisonOperator = ctx.GetText() 324 | } 325 | 326 | func (g *GengineParserListener) EnterConstant(ctx *parser.ConstantContext) { 327 | if len(g.ParseErrors) > 0 { 328 | return 329 | } 330 | cons := &base.Constant{} 331 | g.Stack.Push(cons) 332 | } 333 | 334 | func (g *GengineParserListener) ExitConstant(ctx *parser.ConstantContext) { 335 | if len(g.ParseErrors) > 0 { 336 | return 337 | } 338 | cons := g.Stack.Pop().(*base.Constant) 339 | holder := g.Stack.Peek().(base.ConstantHolder) 340 | err := holder.AcceptConstant(cons) 341 | if err != nil { 342 | g.AddError(err) 343 | } 344 | } 345 | 346 | func (g *GengineParserListener) EnterStringLiteral(ctx *parser.StringLiteralContext) {} 347 | 348 | func (g *GengineParserListener) ExitStringLiteral(ctx *parser.StringLiteralContext) { 349 | if len(g.ParseErrors) > 0 { 350 | return 351 | } 352 | holder := g.Stack.Peek().(base.StringHolder) 353 | text := ctx.GetText() 354 | err := holder.AcceptString(strings.Trim(text, "\"")) 355 | if err != nil { 356 | g.AddError(err) 357 | } 358 | } 359 | 360 | func (g *GengineParserListener) EnterBooleanLiteral(ctx *parser.BooleanLiteralContext) {} 361 | 362 | func (g *GengineParserListener) ExitBooleanLiteral(ctx *parser.BooleanLiteralContext) { 363 | if len(g.ParseErrors) > 0 { 364 | return 365 | } 366 | cons := g.Stack.Peek().(*base.Constant) 367 | b, e := strconv.ParseBool(ctx.GetText()) 368 | if e != nil{ 369 | g.AddError(e) 370 | return 371 | } 372 | cons.ConstantValue = b 373 | } 374 | 375 | func (g *GengineParserListener) EnterRealLiteral(ctx *parser.RealLiteralContext) {} 376 | 377 | func (g *GengineParserListener) ExitRealLiteral(ctx *parser.RealLiteralContext) { 378 | if len(g.ParseErrors) > 0 { 379 | return 380 | } 381 | cons := g.Stack.Peek().(*base.Constant) 382 | flo, err := strconv.ParseFloat(ctx.GetText(), 64) 383 | if err != nil { 384 | g.AddError(errors.Errorf("string to float conversion error. String is not real type '%s'", ctx.GetText())) 385 | return 386 | } 387 | cons.ConstantValue = flo 388 | } 389 | 390 | func (g *GengineParserListener) EnterIfStmt(ctx *parser.IfStmtContext) { 391 | if len(g.ParseErrors) > 0 { 392 | return 393 | } 394 | ifStmt := &base.IfStmt{} 395 | g.Stack.Push(ifStmt) 396 | } 397 | 398 | func (g *GengineParserListener) ExitIfStmt(ctx *parser.IfStmtContext) { 399 | if len(g.ParseErrors) > 0 { 400 | return 401 | } 402 | ifStmt := g.Stack.Pop().(*base.IfStmt) 403 | statement := g.Stack.Peek().(*base.Statement) 404 | statement.IfStmt = ifStmt 405 | } 406 | 407 | func (g *GengineParserListener)EnterStatement(ctx *parser.StatementContext){ 408 | if len(g.ParseErrors) > 0 { 409 | return 410 | } 411 | statement := &base.Statement{} 412 | g.Stack.Push(statement) 413 | } 414 | 415 | func (g *GengineParserListener)ExitStatement(ctx *parser.StatementContext){ 416 | if len(g.ParseErrors) > 0 { 417 | return 418 | } 419 | statement := g.Stack.Pop().(*base.Statement) 420 | statements := g.Stack.Peek().(*base.Statements) 421 | statements.StatementList = append(statements.StatementList, statement) 422 | } 423 | 424 | func(g *GengineParserListener)EnterStatements(ctx *parser.StatementsContext){ 425 | if len(g.ParseErrors) > 0 { 426 | return 427 | } 428 | statements := &base.Statements{ 429 | StatementList: make([]*base.Statement, 0), 430 | } 431 | g.Stack.Push(statements) 432 | } 433 | 434 | func(g *GengineParserListener)ExitStatements(ctx *parser.StatementsContext){ 435 | if len(g.ParseErrors) > 0 { 436 | return 437 | } 438 | statements := g.Stack.Pop().(*base.Statements) 439 | holder := g.Stack.Peek().(base.StatementsHolder) 440 | err := holder.AcceptStatements(statements) 441 | if err != nil { 442 | g.AddError(err) 443 | } 444 | } 445 | 446 | func (g *GengineParserListener)EnterAssignOperator(ctx *parser.AssignOperatorContext) {} 447 | 448 | func (g *GengineParserListener)ExitAssignOperator(ctx *parser.AssignOperatorContext) {} 449 | 450 | func (g *GengineParserListener)EnterSetOperator(ctx *parser.SetOperatorContext){} 451 | 452 | func (g *GengineParserListener)ExitSetOperator(ctx *parser.SetOperatorContext){} 453 | 454 | func (g *GengineParserListener)EnterElseStmt(ctx *parser.ElseStmtContext){ 455 | if len(g.ParseErrors) > 0{ 456 | return 457 | } 458 | elseStmt := &base.ElseStmt{} 459 | g.Stack.Push(elseStmt) 460 | } 461 | 462 | func (g *GengineParserListener)ExitElseStmt(ctx *parser.ElseStmtContext){ 463 | if len(g.ParseErrors) > 0 { 464 | return 465 | } 466 | elseStmt := g.Stack.Pop().(*base.ElseStmt) 467 | ifStmt := g.Stack.Peek().(*base.IfStmt) 468 | ifStmt.ElseStmt = elseStmt 469 | } 470 | 471 | func (g *GengineParserListener) ExitInteger(ctx *parser.IntegerContext) { 472 | if len(g.ParseErrors) > 0 { 473 | return 474 | } 475 | val,err := strconv.ParseInt(ctx.GetText(),10,64) 476 | if err !=nil { 477 | g.AddError(err) 478 | return 479 | } 480 | holder := g.Stack.Peek().(base.IntegerHolder) 481 | err = holder.AcceptInteger(val) 482 | if err != nil { 483 | g.AddError(err) 484 | } 485 | } 486 | func (g *GengineParserListener) EnterInteger(ctx *parser.IntegerContext) {} 487 | 488 | func (g *GengineParserListener) EnterAtName(ctx *parser.AtNameContext) {} 489 | 490 | func (g *GengineParserListener) ExitAtName(ctx *parser.AtNameContext) { 491 | if len(g.ParseErrors) > 0 { 492 | return 493 | } 494 | holder := g.Stack.Peek().(base.AtNameHolder) 495 | err := holder.AcceptName(strings.ReplaceAll(g.ruleName, "\"", "")) 496 | if err != nil { 497 | g.AddError(err) 498 | } 499 | } -------------------------------------------------------------------------------- /iparser/GenginePaserVistior.go: -------------------------------------------------------------------------------- 1 | package iparser 2 | 3 | import parser "gengine/iantlr/alr" 4 | 5 | type GengineParserVisitor struct { 6 | parser.BasegengineVisitor 7 | } 8 | 9 | func NewGengineParserVisitor() *GengineParserVisitor{ 10 | return &GengineParserVisitor{} 11 | } 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/AtName_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | func PrintName(name string){ 15 | fmt.Println(name) 16 | } 17 | 18 | /** 19 | use '@name',you can get rule name in rule content 20 | */ 21 | const atname_rule =` 22 | rule "测试规则名称1" "规则描述" 23 | begin 24 | va = @name 25 | PrintName(va) 26 | PrintName(@name) 27 | end 28 | rule "测试规则名称2" "规则描述" 29 | begin 30 | va = @name 31 | PrintName(va) 32 | PrintName(@name) 33 | end 34 | ` 35 | 36 | func exec(){ 37 | dataContext := context.NewDataContext() 38 | dataContext.Add("PrintName",PrintName) 39 | 40 | //初始化规则引擎 41 | knowledgeContext := base.NewKnowledgeContext() 42 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 43 | 44 | //读取规则 45 | start1 := time.Now().UnixNano() 46 | err := ruleBuilder.BuildRuleFromString(atname_rule) 47 | end1 := time.Now().UnixNano() 48 | 49 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 50 | 51 | if err != nil{ 52 | logrus.Errorf("err:%s ", err) 53 | }else{ 54 | eng := engine.NewGengine() 55 | 56 | start := time.Now().UnixNano() 57 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 58 | err := eng.Execute(ruleBuilder, true) 59 | end := time.Now().UnixNano() 60 | if err != nil{ 61 | logrus.Errorf("execute rule error: %v", err) 62 | } 63 | logrus.Infof("execute rule cost %d ns",end-start) 64 | } 65 | } 66 | 67 | func Test_AtName(t *testing.T){ 68 | exec() 69 | } 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /test/Gengine_base_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | type User struct { 15 | Name string 16 | Age int64 17 | Male bool 18 | } 19 | 20 | func (u *User)GetNum(i int64) int64 { 21 | return i 22 | } 23 | 24 | func (u *User)Print(s string){ 25 | fmt.Println(s) 26 | } 27 | 28 | func (u *User)Say(){ 29 | fmt.Println("hello world") 30 | } 31 | 32 | const ( 33 | base_rule = ` 34 | rule "测试" "测试描述" salience 0 35 | begin 36 | // 重命名函数 测试; @name represent the rule name "测试" 37 | Sout(@name) 38 | // 普通函数 测试 39 | Hello() 40 | //结构提方法 测试 41 | User.Say() 42 | // if 43 | if !(7 == User.GetNum(7)) || !(7 > 8) { 44 | //自定义变量 和 加法 测试 45 | variable = "hello" + (" world" + "zeze") 46 | // 加法 与 内建函数 测试 ; @name is just a string 47 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 48 | //结构体属性、方法调用 和 除法 测试 49 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 50 | //布尔值设置 测试 51 | User.Male = false 52 | //规则内自定义变量调用 测试 53 | User.Print(variable) 54 | //float测试 也支持科学计数法 55 | f = 9.56 56 | PrintReal(f) 57 | //嵌套if-else测试 58 | if false { 59 | Sout("嵌套if测试") 60 | }else{ 61 | Sout("嵌套else测试") 62 | } 63 | }else{ //else 64 | //字符串设置 测试 65 | User.Name = "yyyy" 66 | } 67 | 68 | if true { 69 | Sout("if true ") 70 | } 71 | 72 | end`) 73 | 74 | func Hello() { 75 | fmt.Println("hello") 76 | } 77 | 78 | func PrintReal(real float64){ 79 | fmt.Println(real) 80 | } 81 | 82 | func exe(user *User){ 83 | /** 84 | 不要注入除函数和结构体指针以外的其他类型(如变量) 85 | */ 86 | dataContext := context.NewDataContext() 87 | //注入结构体指针 88 | dataContext.Add("User", user) 89 | //重命名函数,并注入 90 | dataContext.Add("Sout",fmt.Println) 91 | //直接注入函数 92 | dataContext.Add("Hello",Hello) 93 | dataContext.Add("PrintReal",PrintReal) 94 | 95 | //初始化规则引擎 96 | knowledgeContext := base.NewKnowledgeContext() 97 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 98 | 99 | //读取规则 100 | start1 := time.Now().UnixNano() 101 | err := ruleBuilder.BuildRuleFromString(base_rule) 102 | end1 := time.Now().UnixNano() 103 | 104 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 105 | 106 | if err != nil{ 107 | logrus.Errorf("err:%s ", err) 108 | }else{ 109 | eng := engine.NewGengine() 110 | 111 | start := time.Now().UnixNano() 112 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 113 | err := eng.Execute(ruleBuilder, true) 114 | end := time.Now().UnixNano() 115 | if err != nil{ 116 | logrus.Errorf("execute rule error: %v", err) 117 | } 118 | logrus.Infof("execute rule cost %d ns",end-start) 119 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 120 | } 121 | } 122 | 123 | func Test_Base(t *testing.T){ 124 | user := &User{ 125 | Name: "Calo", 126 | Age: 0, 127 | Male: true, 128 | } 129 | exe(user) 130 | } 131 | -------------------------------------------------------------------------------- /test/Gengine_salience_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | const rule4 = ` 15 | rule "111" "111" salience 80 16 | BEGIN 17 | Print("111") 18 | END 19 | rule "222" "222" salience 10 20 | BEGIN 21 | Print("222") 22 | END 23 | rule "333" "333" salience 11 24 | BEGIN 25 | if false { 26 | Print("333") 27 | }else{ 28 | Print("444") 29 | } 30 | END 31 | 32 | ` 33 | 34 | func Print(s string){ 35 | fmt.Println(s) 36 | } 37 | 38 | func Test_Priority(t *testing.T){ 39 | dataContext := context.NewDataContext() 40 | dataContext.Add("Print", Print) 41 | 42 | //初始化规则引擎 43 | knowledgeContext := base.NewKnowledgeContext() 44 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext,dataContext) 45 | 46 | start1 := time.Now().UnixNano() 47 | err := ruleBuilder.BuildRuleFromString(rule4) 48 | end1 := time.Now().UnixNano() 49 | 50 | logrus.Infof("规则个数:%d, 加载规则耗时:%d", len(knowledgeContext.RuleEntities), end1-start1 ) 51 | 52 | if err != nil{ 53 | logrus.Errorf("err:%s ", err) 54 | }else{ 55 | eng := engine.NewGengine() 56 | start := time.Now().UnixNano() 57 | err := eng.Execute(ruleBuilder, true) 58 | end := time.Now().UnixNano() 59 | if err != nil{ 60 | logrus.Errorf("execute rule error: %v", err) 61 | } 62 | logrus.Infof("execute rule cost %d ns",end-start) 63 | } 64 | } 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /test/Grammar_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | parser "gengine/iantlr/alr" 9 | "gengine/iparser" 10 | "github.com/antlr/antlr4/runtime/Go/antlr" 11 | "github.com/sirupsen/logrus" 12 | "testing" 13 | ) 14 | 15 | const ( 16 | rule3 = ` 17 | rule "姓名测试" "我可以的" salience 0 18 | BEGIN 19 | if 7 == User.GetNum(7){ 20 | User.Age = User.GetNum(89767) + 10000000 21 | User.Print("6666") 22 | }else{ 23 | User.Name = "yyyy" 24 | } 25 | END`) 26 | 27 | func Test_grammar(t *testing.T) { 28 | in := antlr.NewInputStream(rule3) 29 | lexer := parser.NewgengineLexer(in) 30 | stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) 31 | 32 | knowledgeBase := base.NewKnowledgeContext() 33 | listener := iparser.NewGengineParserListener(knowledgeBase) 34 | 35 | psr := parser.NewgengineParser(stream) 36 | psr.BuildParseTrees = true 37 | antlr.ParseTreeWalkerDefault.Walk(listener, psr.Primary()) 38 | if len(listener.ParseErrors) > 0 { 39 | fmt.Println(listener.ParseErrors) 40 | } 41 | } 42 | 43 | func Test_base_msg(t *testing.T){ 44 | 45 | dataContext := context.NewDataContext() 46 | //初始化规则引擎 47 | knowledgeContext := base.NewKnowledgeContext() 48 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext,dataContext) 49 | 50 | //读取规则 51 | err := ruleBuilder.BuildRuleFromString(rule3) 52 | if err != nil { 53 | logrus.Errorf("______%v", err) 54 | } 55 | 56 | rule := knowledgeContext.RuleEntities 57 | for k, v :=range rule{ 58 | fmt.Println(k) 59 | fmt.Println(v.RuleName) 60 | fmt.Println(v.RuleDescription) 61 | fmt.Println(v.Salience) 62 | fmt.Println(v.RuleContent) 63 | } 64 | } 65 | 66 | /** 67 | 测试语法错误 68 | */ 69 | func Test_err(t *testing.T){ 70 | 71 | in := antlr.NewInputStream(rule3) 72 | lexer := parser.NewgengineLexer(in) 73 | stream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel) 74 | 75 | knowledgeBase := base.NewKnowledgeContext() 76 | listener := iparser.NewGengineParserListener(knowledgeBase) 77 | 78 | psr := parser.NewgengineParser(stream) 79 | psr.BuildParseTrees = true 80 | 81 | //test -- here 82 | errListener := iparser.NewGengineErrorListener() 83 | psr.AddErrorListener(errListener) 84 | //test -- here 85 | 86 | antlr.ParseTreeWalkerDefault.Walk(listener, psr.Primary()) 87 | fmt.Println(errListener.GrammarErrors) 88 | } 89 | -------------------------------------------------------------------------------- /test/MutliRules_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "gengine/base" 7 | "gengine/builder" 8 | "gengine/context" 9 | "gengine/engine" 10 | "github.com/sirupsen/logrus" 11 | "io/ioutil" 12 | "strconv" 13 | "strings" 14 | "testing" 15 | "time" 16 | ) 17 | 18 | const rule1 = ` 19 | rule "姓名测试0" "我可以的" salience 0 20 | begin 21 | if 7 == User.GetNum(7){ 22 | User.Age = User.GetNum(89767) + 10000000 23 | User.Print("6666") 24 | }else{ 25 | User.Name = "yyyy" 26 | } 27 | end 28 | rule "姓名测试1" "我可以的" salience 0 29 | begin 30 | if 7 == User.GetNum(7){ 31 | User.Age = User.GetNum(89767) + 10000000 32 | User.Print("6666") 33 | }else{ 34 | User.Name = "yyyy" 35 | } 36 | end 37 | ` 38 | 39 | func Test_Multi(t *testing.T){ 40 | user := &User{ 41 | Name: "Calo", 42 | Age: 0, 43 | Male: true, 44 | } 45 | 46 | dataContext := context.NewDataContext() 47 | dataContext.Add("User", user) 48 | 49 | //初始化规则引擎 50 | knowledgeContext := base.NewKnowledgeContext() 51 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext,dataContext) 52 | 53 | //读取规则 54 | /* bs, e := ioutil.ReadFile("/path/to/file") 55 | if e != nil { 56 | panic(e) 57 | }*/ 58 | 59 | start1 := time.Now().UnixNano() 60 | err := ruleBuilder.BuildRuleFromString(rule1) //string(bs) 61 | end1 := time.Now().UnixNano() 62 | 63 | logrus.Infof("规则个数:%d, 加载规则耗时:%d", len(knowledgeContext.RuleEntities), end1-start1 ) 64 | 65 | if err != nil{ 66 | logrus.Errorf("err:%s ", err) 67 | }else{ 68 | eng := engine.NewGengine() 69 | 70 | start := time.Now().UnixNano() 71 | err := eng.Execute(ruleBuilder,true) 72 | end := time.Now().UnixNano() 73 | if err != nil{ 74 | logrus.Errorf("execute rule error: %v", err) 75 | } 76 | logrus.Infof("execute rule cost %d ns",end-start) 77 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 78 | } 79 | } 80 | 81 | func Test_Read(t*testing.T){ 82 | 83 | bytes, e := ioutil.ReadFile("/path/to/file") 84 | if e != nil { 85 | panic(e) 86 | } 87 | fmt.Println(string(bytes)) 88 | 89 | } 90 | 91 | func Test_Write(t *testing.T){ 92 | 93 | r :=`rule "TTTTTTT" "我可以的" salience 0 94 | begin 95 | if 7 == User.GetNum(7){ 96 | User.Age = User.GetNum(89767) + 10000000 97 | User.Print("6666") 98 | }else{ 99 | User.Name = "yyyy" 100 | } 101 | end 102 | ` 103 | 104 | var buffer bytes.Buffer 105 | for i := 0;i < 100; i++ { 106 | i2 := strconv.Itoa(i) 107 | rep := strings.Replace(r, "TTTTTTT", "姓名测试"+i2, -1) 108 | buffer.WriteString(rep) 109 | } 110 | 111 | cont := buffer.String() 112 | 113 | 114 | fileName := "/Users/renyunyi/go/src/gengine/test/file" 115 | err := ioutil.WriteFile(fileName, []byte(cont), 0664) 116 | if err != nil { 117 | panic(err) 118 | } 119 | fmt.Println("写入文件成功!") 120 | } 121 | -------------------------------------------------------------------------------- /test/complex/extends_test.go: -------------------------------------------------------------------------------- 1 | package complex 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | const ext_rule = ` 15 | rule "extends test" "extends test" 16 | begin 17 | Father.Son = "tom" 18 | Sout(Father.Son) 19 | end 20 | ` 21 | 22 | func exe(father *Father){ 23 | 24 | dataContext := context.NewDataContext() 25 | //注入结构体指针 26 | dataContext.Add("Father", father) 27 | //重命名函数,并注入 28 | dataContext.Add("Sout",fmt.Println) 29 | 30 | //初始化规则引擎 31 | knowledgeContext := base.NewKnowledgeContext() 32 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 33 | 34 | //读取规则 35 | start1 := time.Now().UnixNano() 36 | err := ruleBuilder.BuildRuleFromString(ext_rule) 37 | end1 := time.Now().UnixNano() 38 | 39 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 40 | 41 | if err != nil{ 42 | logrus.Errorf("err:%s ", err) 43 | }else{ 44 | eng := engine.NewGengine() 45 | 46 | start := time.Now().UnixNano() 47 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 48 | err := eng.Execute(ruleBuilder, true) 49 | end := time.Now().UnixNano() 50 | if err != nil{ 51 | logrus.Errorf("execute rule error: %v", err) 52 | } 53 | logrus.Infof("execute rule cost %d ns",end-start) 54 | } 55 | } 56 | 57 | 58 | func Test_ext(t *testing.T) { 59 | father := &Father{} 60 | exe(father) 61 | } 62 | -------------------------------------------------------------------------------- /test/complex/father.go: -------------------------------------------------------------------------------- 1 | package complex 2 | 3 | 4 | type Father struct { 5 | *Man 6 | Son string 7 | } 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/complex/man.go: -------------------------------------------------------------------------------- 1 | package complex 2 | 3 | type Man struct { 4 | eat string 5 | drink string 6 | } 7 | -------------------------------------------------------------------------------- /test/concurrent/concurrent_test.go: -------------------------------------------------------------------------------- 1 | package concurrent 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "io/ioutil" 11 | "os" 12 | "testing" 13 | "time" 14 | ) 15 | 16 | 17 | const ( 18 | base_rule = ` 19 | rule "测试" "测试描述" salience 0 20 | begin 21 | // 重命名函数 测试; @name represent the rule name "测试" 22 | Sout(@name) 23 | // 普通函数 测试 24 | Hello() 25 | //结构提方法 测试 26 | User.Say() 27 | // if 28 | if !(7 == User.GetNum(7)) || !(7 > 8) { 29 | //自定义变量 和 加法 测试 30 | variable = "hello" + (" world" + "zeze") 31 | // 加法 与 内建函数 测试 ; @name is just a string 32 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 33 | //结构体属性、方法调用 和 除法 测试 34 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 35 | //布尔值设置 测试 36 | User.Male = false 37 | //规则内自定义变量调用 测试 38 | User.Print(variable) 39 | //float测试 也支持科学计数法 40 | f = 9.56 41 | PrintReal(f) 42 | //嵌套if-else测试 43 | if false { 44 | Sout("嵌套if测试") 45 | }else{ 46 | Sout("嵌套else测试") 47 | } 48 | }else{ //else 49 | //字符串设置 测试 50 | User.Name = "yyyy" 51 | } 52 | end`) 53 | 54 | func readAll() string { 55 | f, err := os.Open("/Users/renyunyi/go/src/gengine/test/rule.gengine") 56 | if err != nil { 57 | logrus.Errorf("读取文件报错%+v", err) 58 | } 59 | 60 | b,e := ioutil.ReadAll(f) 61 | if e != nil { 62 | logrus.Errorf("读取文件报错%+v", e) 63 | } 64 | return string(b) 65 | 66 | } 67 | 68 | 69 | 70 | func Test_concurrent(t *testing.T) { 71 | user := &User{ 72 | Name: "Calo", 73 | Age: 0, 74 | Male: true, 75 | } 76 | 77 | s := readAll() 78 | exe_concurrent(user , s) 79 | } 80 | 81 | type User struct { 82 | Name string 83 | Age int64 84 | Male bool 85 | } 86 | 87 | func (u *User)GetNum(i int64) int64 { 88 | return i 89 | } 90 | 91 | func (u *User)Print(s string){ 92 | fmt.Println(s) 93 | } 94 | 95 | func (u *User)Say(){ 96 | fmt.Println("hello world") 97 | } 98 | 99 | 100 | func Hello() { 101 | fmt.Println("hello") 102 | } 103 | 104 | func PrintReal(real float64){ 105 | fmt.Println(real) 106 | } 107 | 108 | 109 | func exe_concurrent(user *User, s string){ 110 | /** 111 | 不要注入除函数和结构体指针以外的其他类型(如变量) 112 | */ 113 | dataContext := context.NewDataContext() 114 | //注入结构体指针 115 | dataContext.Add("User", user) 116 | //重命名函数,并注入 117 | dataContext.Add("Sout",fmt.Println) 118 | //直接注入函数 119 | dataContext.Add("Hello",Hello) 120 | dataContext.Add("PrintReal", PrintReal) 121 | 122 | //初始化规则引擎 123 | knowledgeContext := base.NewKnowledgeContext() 124 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 125 | 126 | //读取规则 127 | start1 := time.Now().UnixNano() 128 | err := ruleBuilder.BuildRuleFromString(s) 129 | end1 := time.Now().UnixNano() 130 | 131 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 132 | 133 | if err != nil{ 134 | logrus.Errorf("err:%s ", err) 135 | }else{ 136 | eng := engine.NewGengine() 137 | 138 | for i :=0 ; i< 10 ; i ++ { 139 | start := time.Now().UnixNano() 140 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 141 | eng.ExecuteConcurrent(ruleBuilder) 142 | end := time.Now().UnixNano() 143 | logrus.Infof("execute rule cost %d ns",end-start) 144 | } 145 | 146 | 147 | if err != nil{ 148 | logrus.Errorf("execute rule error: %v", err) 149 | } 150 | 151 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 152 | } 153 | } 154 | 155 | 156 | 157 | 158 | func exe_sort(user *User, s string){ 159 | /** 160 | 不要注入除函数和结构体指针以外的其他类型(如变量) 161 | */ 162 | dataContext := context.NewDataContext() 163 | //注入结构体指针 164 | dataContext.Add("User", user) 165 | //重命名函数,并注入 166 | dataContext.Add("Sout",fmt.Println) 167 | //直接注入函数 168 | dataContext.Add("Hello",Hello) 169 | dataContext.Add("PrintReal", PrintReal) 170 | 171 | //初始化规则引擎 172 | knowledgeContext := base.NewKnowledgeContext() 173 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 174 | 175 | //读取规则 176 | start1 := time.Now().UnixNano() 177 | err := ruleBuilder.BuildRuleFromString(s) 178 | end1 := time.Now().UnixNano() 179 | 180 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 181 | 182 | if err != nil{ 183 | logrus.Errorf("err:%s ", err) 184 | }else{ 185 | eng := engine.NewGengine() 186 | for i :=0 ; i< 10 ; i ++ { 187 | start := time.Now().UnixNano() 188 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 189 | _ = eng.Execute(ruleBuilder, true) 190 | end := time.Now().UnixNano() 191 | logrus.Infof("execute rule cost %d ns",end-start) 192 | } 193 | if err != nil{ 194 | logrus.Errorf("execute rule error: %v", err) 195 | } 196 | 197 | logrus.Infof("user.Age=%d,Name=%s,Male=%t", user.Age, user.Name, user.Male) 198 | } 199 | } 200 | 201 | 202 | -------------------------------------------------------------------------------- /test/rule.gengine: -------------------------------------------------------------------------------- 1 | rule "测试1" "测试描述" salience 0 2 | begin 3 | // 重命名函数 测试; @name represent the rule name "测试" 4 | Sout(@name) 5 | // 普通函数 测试 6 | Hello() 7 | //结构提方法 测试 8 | User.Say() 9 | // if 10 | if !(7 == User.GetNum(7)) || !(7 > 8) { 11 | //自定义变量 和 加法 测试 12 | variable = "hello" + (" world" + "zeze") 13 | // 加法 与 内建函数 测试 ; @name is just a string 14 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 15 | //结构体属性、方法调用 和 除法 测试 16 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 17 | //布尔值设置 测试 18 | User.Male = false 19 | //规则内自定义变量调用 测试 20 | User.Print(variable) 21 | //float测试 也支持科学计数法 22 | f = 9.56 23 | PrintReal(f) 24 | //嵌套if-else测试 25 | if false { 26 | Sout("嵌套if测试") 27 | }else{ 28 | Sout("嵌套else测试") 29 | } 30 | }else{ //else 31 | //字符串设置 测试 32 | User.Name = "yyyy" 33 | } 34 | end 35 | rule "测试2" "测试描述" salience 0 36 | begin 37 | // 重命名函数 测试; @name represent the rule name "测试" 38 | Sout(@name) 39 | // 普通函数 测试 40 | Hello() 41 | //结构提方法 测试 42 | User.Say() 43 | // if 44 | if !(7 == User.GetNum(7)) || !(7 > 8) { 45 | //自定义变量 和 加法 测试 46 | variable = "hello" + (" world" + "zeze") 47 | // 加法 与 内建函数 测试 ; @name is just a string 48 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 49 | //结构体属性、方法调用 和 除法 测试 50 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 51 | //布尔值设置 测试 52 | User.Male = false 53 | //规则内自定义变量调用 测试 54 | User.Print(variable) 55 | //float测试 也支持科学计数法 56 | f = 9.56 57 | PrintReal(f) 58 | //嵌套if-else测试 59 | if false { 60 | Sout("嵌套if测试") 61 | }else{ 62 | Sout("嵌套else测试") 63 | } 64 | }else{ //else 65 | //字符串设置 测试 66 | User.Name = "yyyy" 67 | } 68 | end 69 | rule "测试3" "测试描述" salience 0 70 | begin 71 | // 重命名函数 测试; @name represent the rule name "测试" 72 | Sout(@name) 73 | // 普通函数 测试 74 | Hello() 75 | //结构提方法 测试 76 | User.Say() 77 | // if 78 | if !(7 == User.GetNum(7)) || !(7 > 8) { 79 | //自定义变量 和 加法 测试 80 | variable = "hello" + (" world" + "zeze") 81 | // 加法 与 内建函数 测试 ; @name is just a string 82 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 83 | //结构体属性、方法调用 和 除法 测试 84 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 85 | //布尔值设置 测试 86 | User.Male = false 87 | //规则内自定义变量调用 测试 88 | User.Print(variable) 89 | //float测试 也支持科学计数法 90 | f = 9.56 91 | PrintReal(f) 92 | //嵌套if-else测试 93 | if false { 94 | Sout("嵌套if测试") 95 | }else{ 96 | Sout("嵌套else测试") 97 | } 98 | }else{ //else 99 | //字符串设置 测试 100 | User.Name = "yyyy" 101 | } 102 | end 103 | rule "测试4" "测试描述" salience 0 104 | begin 105 | // 重命名函数 测试; @name represent the rule name "测试" 106 | Sout(@name) 107 | // 普通函数 测试 108 | Hello() 109 | //结构提方法 测试 110 | User.Say() 111 | // if 112 | if !(7 == User.GetNum(7)) || !(7 > 8) { 113 | //自定义变量 和 加法 测试 114 | variable = "hello" + (" world" + "zeze") 115 | // 加法 与 内建函数 测试 ; @name is just a string 116 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 117 | //结构体属性、方法调用 和 除法 测试 118 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 119 | //布尔值设置 测试 120 | User.Male = false 121 | //规则内自定义变量调用 测试 122 | User.Print(variable) 123 | //float测试 也支持科学计数法 124 | f = 9.56 125 | PrintReal(f) 126 | //嵌套if-else测试 127 | if false { 128 | Sout("嵌套if测试") 129 | }else{ 130 | Sout("嵌套else测试") 131 | } 132 | }else{ //else 133 | //字符串设置 测试 134 | User.Name = "yyyy" 135 | } 136 | end 137 | rule "测试5" "测试描述" salience 0 138 | begin 139 | // 重命名函数 测试; @name represent the rule name "测试" 140 | Sout(@name) 141 | // 普通函数 测试 142 | Hello() 143 | //结构提方法 测试 144 | User.Say() 145 | // if 146 | if !(7 == User.GetNum(7)) || !(7 > 8) { 147 | //自定义变量 和 加法 测试 148 | variable = "hello" + (" world" + "zeze") 149 | // 加法 与 内建函数 测试 ; @name is just a string 150 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 151 | //结构体属性、方法调用 和 除法 测试 152 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 153 | //布尔值设置 测试 154 | User.Male = false 155 | //规则内自定义变量调用 测试 156 | User.Print(variable) 157 | //float测试 也支持科学计数法 158 | f = 9.56 159 | PrintReal(f) 160 | //嵌套if-else测试 161 | if false { 162 | Sout("嵌套if测试") 163 | }else{ 164 | Sout("嵌套else测试") 165 | } 166 | }else{ //else 167 | //字符串设置 测试 168 | User.Name = "yyyy" 169 | } 170 | end 171 | rule "测试6" "测试描述" salience 0 172 | begin 173 | // 重命名函数 测试; @name represent the rule name "测试" 174 | Sout(@name) 175 | // 普通函数 测试 176 | Hello() 177 | //结构提方法 测试 178 | User.Say() 179 | // if 180 | if !(7 == User.GetNum(7)) || !(7 > 8) { 181 | //自定义变量 和 加法 测试 182 | variable = "hello" + (" world" + "zeze") 183 | // 加法 与 内建函数 测试 ; @name is just a string 184 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 185 | //结构体属性、方法调用 和 除法 测试 186 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 187 | //布尔值设置 测试 188 | User.Male = false 189 | //规则内自定义变量调用 测试 190 | User.Print(variable) 191 | //float测试 也支持科学计数法 192 | f = 9.56 193 | PrintReal(f) 194 | //嵌套if-else测试 195 | if false { 196 | Sout("嵌套if测试") 197 | }else{ 198 | Sout("嵌套else测试") 199 | } 200 | }else{ //else 201 | //字符串设置 测试 202 | User.Name = "yyyy" 203 | } 204 | end 205 | rule "测试7" "测试描述" salience 0 206 | begin 207 | // 重命名函数 测试; @name represent the rule name "测试" 208 | Sout(@name) 209 | // 普通函数 测试 210 | Hello() 211 | //结构提方法 测试 212 | User.Say() 213 | // if 214 | if !(7 == User.GetNum(7)) || !(7 > 8) { 215 | //自定义变量 和 加法 测试 216 | variable = "hello" + (" world" + "zeze") 217 | // 加法 与 内建函数 测试 ; @name is just a string 218 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 219 | //结构体属性、方法调用 和 除法 测试 220 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 221 | //布尔值设置 测试 222 | User.Male = false 223 | //规则内自定义变量调用 测试 224 | User.Print(variable) 225 | //float测试 也支持科学计数法 226 | f = 9.56 227 | PrintReal(f) 228 | //嵌套if-else测试 229 | if false { 230 | Sout("嵌套if测试") 231 | }else{ 232 | Sout("嵌套else测试") 233 | } 234 | }else{ //else 235 | //字符串设置 测试 236 | User.Name = "yyyy" 237 | } 238 | end 239 | rule "测试8" "测试描述" salience 0 240 | begin 241 | // 重命名函数 测试; @name represent the rule name "测试" 242 | Sout(@name) 243 | // 普通函数 测试 244 | Hello() 245 | //结构提方法 测试 246 | User.Say() 247 | // if 248 | if !(7 == User.GetNum(7)) || !(7 > 8) { 249 | //自定义变量 和 加法 测试 250 | variable = "hello" + (" world" + "zeze") 251 | // 加法 与 内建函数 测试 ; @name is just a string 252 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 253 | //结构体属性、方法调用 和 除法 测试 254 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 255 | //布尔值设置 测试 256 | User.Male = false 257 | //规则内自定义变量调用 测试 258 | User.Print(variable) 259 | //float测试 也支持科学计数法 260 | f = 9.56 261 | PrintReal(f) 262 | //嵌套if-else测试 263 | if false { 264 | Sout("嵌套if测试") 265 | }else{ 266 | Sout("嵌套else测试") 267 | } 268 | }else{ //else 269 | //字符串设置 测试 270 | User.Name = "yyyy" 271 | } 272 | end 273 | rule "测试9" "测试描述" salience 0 274 | begin 275 | // 重命名函数 测试; @name represent the rule name "测试" 276 | Sout(@name) 277 | // 普通函数 测试 278 | Hello() 279 | //结构提方法 测试 280 | User.Say() 281 | // if 282 | if !(7 == User.GetNum(7)) || !(7 > 8) { 283 | //自定义变量 和 加法 测试 284 | variable = "hello" + (" world" + "zeze") 285 | // 加法 与 内建函数 测试 ; @name is just a string 286 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 287 | //结构体属性、方法调用 和 除法 测试 288 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 289 | //布尔值设置 测试 290 | User.Male = false 291 | //规则内自定义变量调用 测试 292 | User.Print(variable) 293 | //float测试 也支持科学计数法 294 | f = 9.56 295 | PrintReal(f) 296 | //嵌套if-else测试 297 | if false { 298 | Sout("嵌套if测试") 299 | }else{ 300 | Sout("嵌套else测试") 301 | } 302 | }else{ //else 303 | //字符串设置 测试 304 | User.Name = "yyyy" 305 | } 306 | end 307 | rule "测试10" "测试描述" salience 0 308 | begin 309 | // 重命名函数 测试; @name represent the rule name "测试" 310 | Sout(@name) 311 | // 普通函数 测试 312 | Hello() 313 | //结构提方法 测试 314 | User.Say() 315 | // if 316 | if !(7 == User.GetNum(7)) || !(7 > 8) { 317 | //自定义变量 和 加法 测试 318 | variable = "hello" + (" world" + "zeze") 319 | // 加法 与 内建函数 测试 ; @name is just a string 320 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 321 | //结构体属性、方法调用 和 除法 测试 322 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 323 | //布尔值设置 测试 324 | User.Male = false 325 | //规则内自定义变量调用 测试 326 | User.Print(variable) 327 | //float测试 也支持科学计数法 328 | f = 9.56 329 | PrintReal(f) 330 | //嵌套if-else测试 331 | if false { 332 | Sout("嵌套if测试") 333 | }else{ 334 | Sout("嵌套else测试") 335 | } 336 | }else{ //else 337 | //字符串设置 测试 338 | User.Name = "yyyy" 339 | } 340 | end 341 | 342 | 343 | rule "测试11" "测试描述" salience 0 344 | begin 345 | // 重命名函数 测试; @name represent the rule name "测试" 346 | Sout(@name) 347 | // 普通函数 测试 348 | Hello() 349 | //结构提方法 测试 350 | User.Say() 351 | // if 352 | if !(7 == User.GetNum(7)) || !(7 > 8) { 353 | //自定义变量 和 加法 测试 354 | variable = "hello" + (" world" + "zeze") 355 | // 加法 与 内建函数 测试 ; @name is just a string 356 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 357 | //结构体属性、方法调用 和 除法 测试 358 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 359 | //布尔值设置 测试 360 | User.Male = false 361 | //规则内自定义变量调用 测试 362 | User.Print(variable) 363 | //float测试 也支持科学计数法 364 | f = 9.56 365 | PrintReal(f) 366 | //嵌套if-else测试 367 | if false { 368 | Sout("嵌套if测试") 369 | }else{ 370 | Sout("嵌套else测试") 371 | } 372 | }else{ //else 373 | //字符串设置 测试 374 | User.Name = "yyyy" 375 | } 376 | end 377 | rule "测试12" "测试描述" salience 0 378 | begin 379 | // 重命名函数 测试; @name represent the rule name "测试" 380 | Sout(@name) 381 | // 普通函数 测试 382 | Hello() 383 | //结构提方法 测试 384 | User.Say() 385 | // if 386 | if !(7 == User.GetNum(7)) || !(7 > 8) { 387 | //自定义变量 和 加法 测试 388 | variable = "hello" + (" world" + "zeze") 389 | // 加法 与 内建函数 测试 ; @name is just a string 390 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 391 | //结构体属性、方法调用 和 除法 测试 392 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 393 | //布尔值设置 测试 394 | User.Male = false 395 | //规则内自定义变量调用 测试 396 | User.Print(variable) 397 | //float测试 也支持科学计数法 398 | f = 9.56 399 | PrintReal(f) 400 | //嵌套if-else测试 401 | if false { 402 | Sout("嵌套if测试") 403 | }else{ 404 | Sout("嵌套else测试") 405 | } 406 | }else{ //else 407 | //字符串设置 测试 408 | User.Name = "yyyy" 409 | } 410 | end 411 | rule "测试13" "测试描述" salience 0 412 | begin 413 | // 重命名函数 测试; @name represent the rule name "测试" 414 | Sout(@name) 415 | // 普通函数 测试 416 | Hello() 417 | //结构提方法 测试 418 | User.Say() 419 | // if 420 | if !(7 == User.GetNum(7)) || !(7 > 8) { 421 | //自定义变量 和 加法 测试 422 | variable = "hello" + (" world" + "zeze") 423 | // 加法 与 内建函数 测试 ; @name is just a string 424 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 425 | //结构体属性、方法调用 和 除法 测试 426 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 427 | //布尔值设置 测试 428 | User.Male = false 429 | //规则内自定义变量调用 测试 430 | User.Print(variable) 431 | //float测试 也支持科学计数法 432 | f = 9.56 433 | PrintReal(f) 434 | //嵌套if-else测试 435 | if false { 436 | Sout("嵌套if测试") 437 | }else{ 438 | Sout("嵌套else测试") 439 | } 440 | }else{ //else 441 | //字符串设置 测试 442 | User.Name = "yyyy" 443 | } 444 | end 445 | rule "测试14" "测试描述" salience 0 446 | begin 447 | // 重命名函数 测试; @name represent the rule name "测试" 448 | Sout(@name) 449 | // 普通函数 测试 450 | Hello() 451 | //结构提方法 测试 452 | User.Say() 453 | // if 454 | if !(7 == User.GetNum(7)) || !(7 > 8) { 455 | //自定义变量 和 加法 测试 456 | variable = "hello" + (" world" + "zeze") 457 | // 加法 与 内建函数 测试 ; @name is just a string 458 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 459 | //结构体属性、方法调用 和 除法 测试 460 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 461 | //布尔值设置 测试 462 | User.Male = false 463 | //规则内自定义变量调用 测试 464 | User.Print(variable) 465 | //float测试 也支持科学计数法 466 | f = 9.56 467 | PrintReal(f) 468 | //嵌套if-else测试 469 | if false { 470 | Sout("嵌套if测试") 471 | }else{ 472 | Sout("嵌套else测试") 473 | } 474 | }else{ //else 475 | //字符串设置 测试 476 | User.Name = "yyyy" 477 | } 478 | end 479 | rule "测试15" "测试描述" salience 0 480 | begin 481 | // 重命名函数 测试; @name represent the rule name "测试" 482 | Sout(@name) 483 | // 普通函数 测试 484 | Hello() 485 | //结构提方法 测试 486 | User.Say() 487 | // if 488 | if !(7 == User.GetNum(7)) || !(7 > 8) { 489 | //自定义变量 和 加法 测试 490 | variable = "hello" + (" world" + "zeze") 491 | // 加法 与 内建函数 测试 ; @name is just a string 492 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 493 | //结构体属性、方法调用 和 除法 测试 494 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 495 | //布尔值设置 测试 496 | User.Male = false 497 | //规则内自定义变量调用 测试 498 | User.Print(variable) 499 | //float测试 也支持科学计数法 500 | f = 9.56 501 | PrintReal(f) 502 | //嵌套if-else测试 503 | if false { 504 | Sout("嵌套if测试") 505 | }else{ 506 | Sout("嵌套else测试") 507 | } 508 | }else{ //else 509 | //字符串设置 测试 510 | User.Name = "yyyy" 511 | } 512 | end 513 | rule "测试16" "测试描述" salience 0 514 | begin 515 | // 重命名函数 测试; @name represent the rule name "测试" 516 | Sout(@name) 517 | // 普通函数 测试 518 | Hello() 519 | //结构提方法 测试 520 | User.Say() 521 | // if 522 | if !(7 == User.GetNum(7)) || !(7 > 8) { 523 | //自定义变量 和 加法 测试 524 | variable = "hello" + (" world" + "zeze") 525 | // 加法 与 内建函数 测试 ; @name is just a string 526 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 527 | //结构体属性、方法调用 和 除法 测试 528 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 529 | //布尔值设置 测试 530 | User.Male = false 531 | //规则内自定义变量调用 测试 532 | User.Print(variable) 533 | //float测试 也支持科学计数法 534 | f = 9.56 535 | PrintReal(f) 536 | //嵌套if-else测试 537 | if false { 538 | Sout("嵌套if测试") 539 | }else{ 540 | Sout("嵌套else测试") 541 | } 542 | }else{ //else 543 | //字符串设置 测试 544 | User.Name = "yyyy" 545 | } 546 | end 547 | rule "测试17" "测试描述" salience 0 548 | begin 549 | // 重命名函数 测试; @name represent the rule name "测试" 550 | Sout(@name) 551 | // 普通函数 测试 552 | Hello() 553 | //结构提方法 测试 554 | User.Say() 555 | // if 556 | if !(7 == User.GetNum(7)) || !(7 > 8) { 557 | //自定义变量 和 加法 测试 558 | variable = "hello" + (" world" + "zeze") 559 | // 加法 与 内建函数 测试 ; @name is just a string 560 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 561 | //结构体属性、方法调用 和 除法 测试 562 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 563 | //布尔值设置 测试 564 | User.Male = false 565 | //规则内自定义变量调用 测试 566 | User.Print(variable) 567 | //float测试 也支持科学计数法 568 | f = 9.56 569 | PrintReal(f) 570 | //嵌套if-else测试 571 | if false { 572 | Sout("嵌套if测试") 573 | }else{ 574 | Sout("嵌套else测试") 575 | } 576 | }else{ //else 577 | //字符串设置 测试 578 | User.Name = "yyyy" 579 | } 580 | end 581 | rule "测试18" "测试描述" salience 0 582 | begin 583 | // 重命名函数 测试; @name represent the rule name "测试" 584 | Sout(@name) 585 | // 普通函数 测试 586 | Hello() 587 | //结构提方法 测试 588 | User.Say() 589 | // if 590 | if !(7 == User.GetNum(7)) || !(7 > 8) { 591 | //自定义变量 和 加法 测试 592 | variable = "hello" + (" world" + "zeze") 593 | // 加法 与 内建函数 测试 ; @name is just a string 594 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 595 | //结构体属性、方法调用 和 除法 测试 596 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 597 | //布尔值设置 测试 598 | User.Male = false 599 | //规则内自定义变量调用 测试 600 | User.Print(variable) 601 | //float测试 也支持科学计数法 602 | f = 9.56 603 | PrintReal(f) 604 | //嵌套if-else测试 605 | if false { 606 | Sout("嵌套if测试") 607 | }else{ 608 | Sout("嵌套else测试") 609 | } 610 | }else{ //else 611 | //字符串设置 测试 612 | User.Name = "yyyy" 613 | } 614 | end 615 | rule "测试19" "测试描述" salience 0 616 | begin 617 | // 重命名函数 测试; @name represent the rule name "测试" 618 | Sout(@name) 619 | // 普通函数 测试 620 | Hello() 621 | //结构提方法 测试 622 | User.Say() 623 | // if 624 | if !(7 == User.GetNum(7)) || !(7 > 8) { 625 | //自定义变量 和 加法 测试 626 | variable = "hello" + (" world" + "zeze") 627 | // 加法 与 内建函数 测试 ; @name is just a string 628 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 629 | //结构体属性、方法调用 和 除法 测试 630 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 631 | //布尔值设置 测试 632 | User.Male = false 633 | //规则内自定义变量调用 测试 634 | User.Print(variable) 635 | //float测试 也支持科学计数法 636 | f = 9.56 637 | PrintReal(f) 638 | //嵌套if-else测试 639 | if false { 640 | Sout("嵌套if测试") 641 | }else{ 642 | Sout("嵌套else测试") 643 | } 644 | }else{ //else 645 | //字符串设置 测试 646 | User.Name = "yyyy" 647 | } 648 | end 649 | rule "测试20" "测试描述" salience 0 650 | begin 651 | // 重命名函数 测试; @name represent the rule name "测试" 652 | Sout(@name) 653 | // 普通函数 测试 654 | Hello() 655 | //结构提方法 测试 656 | User.Say() 657 | // if 658 | if !(7 == User.GetNum(7)) || !(7 > 8) { 659 | //自定义变量 和 加法 测试 660 | variable = "hello" + (" world" + "zeze") 661 | // 加法 与 内建函数 测试 ; @name is just a string 662 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 663 | //结构体属性、方法调用 和 除法 测试 664 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 665 | //布尔值设置 测试 666 | User.Male = false 667 | //规则内自定义变量调用 测试 668 | User.Print(variable) 669 | //float测试 也支持科学计数法 670 | f = 9.56 671 | PrintReal(f) 672 | //嵌套if-else测试 673 | if false { 674 | Sout("嵌套if测试") 675 | }else{ 676 | Sout("嵌套else测试") 677 | } 678 | }else{ //else 679 | //字符串设置 测试 680 | User.Name = "yyyy" 681 | } 682 | end 683 | 684 | 685 | rule "测试21" "测试描述" salience 0 686 | begin 687 | // 重命名函数 测试; @name represent the rule name "测试" 688 | Sout(@name) 689 | // 普通函数 测试 690 | Hello() 691 | //结构提方法 测试 692 | User.Say() 693 | // if 694 | if !(7 == User.GetNum(7)) || !(7 > 8) { 695 | //自定义变量 和 加法 测试 696 | variable = "hello" + (" world" + "zeze") 697 | // 加法 与 内建函数 测试 ; @name is just a string 698 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 699 | //结构体属性、方法调用 和 除法 测试 700 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 701 | //布尔值设置 测试 702 | User.Male = false 703 | //规则内自定义变量调用 测试 704 | User.Print(variable) 705 | //float测试 也支持科学计数法 706 | f = 9.56 707 | PrintReal(f) 708 | //嵌套if-else测试 709 | if false { 710 | Sout("嵌套if测试") 711 | }else{ 712 | Sout("嵌套else测试") 713 | } 714 | }else{ //else 715 | //字符串设置 测试 716 | User.Name = "yyyy" 717 | } 718 | end 719 | rule "测试22" "测试描述" salience 0 720 | begin 721 | // 重命名函数 测试; @name represent the rule name "测试" 722 | Sout(@name) 723 | // 普通函数 测试 724 | Hello() 725 | //结构提方法 测试 726 | User.Say() 727 | // if 728 | if !(7 == User.GetNum(7)) || !(7 > 8) { 729 | //自定义变量 和 加法 测试 730 | variable = "hello" + (" world" + "zeze") 731 | // 加法 与 内建函数 测试 ; @name is just a string 732 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 733 | //结构体属性、方法调用 和 除法 测试 734 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 735 | //布尔值设置 测试 736 | User.Male = false 737 | //规则内自定义变量调用 测试 738 | User.Print(variable) 739 | //float测试 也支持科学计数法 740 | f = 9.56 741 | PrintReal(f) 742 | //嵌套if-else测试 743 | if false { 744 | Sout("嵌套if测试") 745 | }else{ 746 | Sout("嵌套else测试") 747 | } 748 | }else{ //else 749 | //字符串设置 测试 750 | User.Name = "yyyy" 751 | } 752 | end 753 | rule "测试23" "测试描述" salience 0 754 | begin 755 | // 重命名函数 测试; @name represent the rule name "测试" 756 | Sout(@name) 757 | // 普通函数 测试 758 | Hello() 759 | //结构提方法 测试 760 | User.Say() 761 | // if 762 | if !(7 == User.GetNum(7)) || !(7 > 8) { 763 | //自定义变量 和 加法 测试 764 | variable = "hello" + (" world" + "zeze") 765 | // 加法 与 内建函数 测试 ; @name is just a string 766 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 767 | //结构体属性、方法调用 和 除法 测试 768 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 769 | //布尔值设置 测试 770 | User.Male = false 771 | //规则内自定义变量调用 测试 772 | User.Print(variable) 773 | //float测试 也支持科学计数法 774 | f = 9.56 775 | PrintReal(f) 776 | //嵌套if-else测试 777 | if false { 778 | Sout("嵌套if测试") 779 | }else{ 780 | Sout("嵌套else测试") 781 | } 782 | }else{ //else 783 | //字符串设置 测试 784 | User.Name = "yyyy" 785 | } 786 | end 787 | rule "测试24" "测试描述" salience 0 788 | begin 789 | // 重命名函数 测试; @name represent the rule name "测试" 790 | Sout(@name) 791 | // 普通函数 测试 792 | Hello() 793 | //结构提方法 测试 794 | User.Say() 795 | // if 796 | if !(7 == User.GetNum(7)) || !(7 > 8) { 797 | //自定义变量 和 加法 测试 798 | variable = "hello" + (" world" + "zeze") 799 | // 加法 与 内建函数 测试 ; @name is just a string 800 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 801 | //结构体属性、方法调用 和 除法 测试 802 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 803 | //布尔值设置 测试 804 | User.Male = false 805 | //规则内自定义变量调用 测试 806 | User.Print(variable) 807 | //float测试 也支持科学计数法 808 | f = 9.56 809 | PrintReal(f) 810 | //嵌套if-else测试 811 | if false { 812 | Sout("嵌套if测试") 813 | }else{ 814 | Sout("嵌套else测试") 815 | } 816 | }else{ //else 817 | //字符串设置 测试 818 | User.Name = "yyyy" 819 | } 820 | end 821 | rule "测试25" "测试描述" salience 0 822 | begin 823 | // 重命名函数 测试; @name represent the rule name "测试" 824 | Sout(@name) 825 | // 普通函数 测试 826 | Hello() 827 | //结构提方法 测试 828 | User.Say() 829 | // if 830 | if !(7 == User.GetNum(7)) || !(7 > 8) { 831 | //自定义变量 和 加法 测试 832 | variable = "hello" + (" world" + "zeze") 833 | // 加法 与 内建函数 测试 ; @name is just a string 834 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 835 | //结构体属性、方法调用 和 除法 测试 836 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 837 | //布尔值设置 测试 838 | User.Male = false 839 | //规则内自定义变量调用 测试 840 | User.Print(variable) 841 | //float测试 也支持科学计数法 842 | f = 9.56 843 | PrintReal(f) 844 | //嵌套if-else测试 845 | if false { 846 | Sout("嵌套if测试") 847 | }else{ 848 | Sout("嵌套else测试") 849 | } 850 | }else{ //else 851 | //字符串设置 测试 852 | User.Name = "yyyy" 853 | } 854 | end 855 | rule "测试26" "测试描述" salience 0 856 | begin 857 | // 重命名函数 测试; @name represent the rule name "测试" 858 | Sout(@name) 859 | // 普通函数 测试 860 | Hello() 861 | //结构提方法 测试 862 | User.Say() 863 | // if 864 | if !(7 == User.GetNum(7)) || !(7 > 8) { 865 | //自定义变量 和 加法 测试 866 | variable = "hello" + (" world" + "zeze") 867 | // 加法 与 内建函数 测试 ; @name is just a string 868 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 869 | //结构体属性、方法调用 和 除法 测试 870 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 871 | //布尔值设置 测试 872 | User.Male = false 873 | //规则内自定义变量调用 测试 874 | User.Print(variable) 875 | //float测试 也支持科学计数法 876 | f = 9.56 877 | PrintReal(f) 878 | //嵌套if-else测试 879 | if false { 880 | Sout("嵌套if测试") 881 | }else{ 882 | Sout("嵌套else测试") 883 | } 884 | }else{ //else 885 | //字符串设置 测试 886 | User.Name = "yyyy" 887 | } 888 | end 889 | rule "测试27" "测试描述" salience 0 890 | begin 891 | // 重命名函数 测试; @name represent the rule name "测试" 892 | Sout(@name) 893 | // 普通函数 测试 894 | Hello() 895 | //结构提方法 测试 896 | User.Say() 897 | // if 898 | if !(7 == User.GetNum(7)) || !(7 > 8) { 899 | //自定义变量 和 加法 测试 900 | variable = "hello" + (" world" + "zeze") 901 | // 加法 与 内建函数 测试 ; @name is just a string 902 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 903 | //结构体属性、方法调用 和 除法 测试 904 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 905 | //布尔值设置 测试 906 | User.Male = false 907 | //规则内自定义变量调用 测试 908 | User.Print(variable) 909 | //float测试 也支持科学计数法 910 | f = 9.56 911 | PrintReal(f) 912 | //嵌套if-else测试 913 | if false { 914 | Sout("嵌套if测试") 915 | }else{ 916 | Sout("嵌套else测试") 917 | } 918 | }else{ //else 919 | //字符串设置 测试 920 | User.Name = "yyyy" 921 | } 922 | end 923 | rule "测试28" "测试描述" salience 0 924 | begin 925 | // 重命名函数 测试; @name represent the rule name "测试" 926 | Sout(@name) 927 | // 普通函数 测试 928 | Hello() 929 | //结构提方法 测试 930 | User.Say() 931 | // if 932 | if !(7 == User.GetNum(7)) || !(7 > 8) { 933 | //自定义变量 和 加法 测试 934 | variable = "hello" + (" world" + "zeze") 935 | // 加法 与 内建函数 测试 ; @name is just a string 936 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 937 | //结构体属性、方法调用 和 除法 测试 938 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 939 | //布尔值设置 测试 940 | User.Male = false 941 | //规则内自定义变量调用 测试 942 | User.Print(variable) 943 | //float测试 也支持科学计数法 944 | f = 9.56 945 | PrintReal(f) 946 | //嵌套if-else测试 947 | if false { 948 | Sout("嵌套if测试") 949 | }else{ 950 | Sout("嵌套else测试") 951 | } 952 | }else{ //else 953 | //字符串设置 测试 954 | User.Name = "yyyy" 955 | } 956 | end 957 | rule "测试29" "测试描述" salience 0 958 | begin 959 | // 重命名函数 测试; @name represent the rule name "测试" 960 | Sout(@name) 961 | // 普通函数 测试 962 | Hello() 963 | //结构提方法 测试 964 | User.Say() 965 | // if 966 | if !(7 == User.GetNum(7)) || !(7 > 8) { 967 | //自定义变量 和 加法 测试 968 | variable = "hello" + (" world" + "zeze") 969 | // 加法 与 内建函数 测试 ; @name is just a string 970 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 971 | //结构体属性、方法调用 和 除法 测试 972 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 973 | //布尔值设置 测试 974 | User.Male = false 975 | //规则内自定义变量调用 测试 976 | User.Print(variable) 977 | //float测试 也支持科学计数法 978 | f = 9.56 979 | PrintReal(f) 980 | //嵌套if-else测试 981 | if false { 982 | Sout("嵌套if测试") 983 | }else{ 984 | Sout("嵌套else测试") 985 | } 986 | }else{ //else 987 | //字符串设置 测试 988 | User.Name = "yyyy" 989 | } 990 | end 991 | rule "测试30" "测试描述" salience 0 992 | begin 993 | // 重命名函数 测试; @name represent the rule name "测试" 994 | Sout(@name) 995 | // 普通函数 测试 996 | Hello() 997 | //结构提方法 测试 998 | User.Say() 999 | // if 1000 | if !(7 == User.GetNum(7)) || !(7 > 8) { 1001 | //自定义变量 和 加法 测试 1002 | variable = "hello" + (" world" + "zeze") 1003 | // 加法 与 内建函数 测试 ; @name is just a string 1004 | User.Name = "hhh" + strconv.FormatInt(10, 10) + "@name" 1005 | //结构体属性、方法调用 和 除法 测试 1006 | User.Age = User.GetNum(8976) / 1000+ 3*(1+1) 1007 | //布尔值设置 测试 1008 | User.Male = false 1009 | //规则内自定义变量调用 测试 1010 | User.Print(variable) 1011 | //float测试 也支持科学计数法 1012 | f = 9.56 1013 | PrintReal(f) 1014 | //嵌套if-else测试 1015 | if false { 1016 | Sout("嵌套if测试") 1017 | }else{ 1018 | Sout("嵌套else测试") 1019 | } 1020 | }else{ //else 1021 | //字符串设置 测试 1022 | User.Name = "yyyy" 1023 | } 1024 | end -------------------------------------------------------------------------------- /test/struct_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "fmt" 5 | "gengine/base" 6 | "gengine/builder" 7 | "gengine/context" 8 | "gengine/engine" 9 | "github.com/sirupsen/logrus" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | type Person struct { 15 | Name string 16 | Age int64 17 | } 18 | 19 | func getPerson(n string, a int64) *Person{ 20 | return &Person{ 21 | Name: n, 22 | Age: a, 23 | } 24 | } 25 | 26 | func Test_Struct(t *testing.T) { 27 | p := getPerson("777", 5) 28 | println(p.Age) 29 | } 30 | 31 | 32 | const rule_s = ` 33 | rule "test_struct_return" "test" 34 | begin 35 | p = getPerson("hello", 100) 36 | Sout(p.Age) 37 | end 38 | ` 39 | 40 | func exe_struct(){ 41 | /** 42 | 不要注入除函数和结构体指针以外的其他类型(如变量) 43 | */ 44 | dataContext := context.NewDataContext() 45 | //注入结构体指针 46 | //重命名函数,并注入 47 | dataContext.Add("Sout",fmt.Println) 48 | dataContext.Add("getPerson",getPerson) 49 | //初始化规则引擎 50 | knowledgeContext := base.NewKnowledgeContext() 51 | ruleBuilder := builder.NewRuleBuilder(knowledgeContext, dataContext) 52 | 53 | //读取规则 54 | start1 := time.Now().UnixNano() 55 | err := ruleBuilder.BuildRuleFromString(rule_s) 56 | end1 := time.Now().UnixNano() 57 | 58 | logrus.Infof("规则个数:%d, 加载规则耗时:%d ns", len(knowledgeContext.RuleEntities), end1-start1 ) 59 | 60 | if err != nil{ 61 | logrus.Errorf("err:%s ", err) 62 | }else{ 63 | eng := engine.NewGengine() 64 | 65 | start := time.Now().UnixNano() 66 | // true: means when there are many rules, if one rule execute error,continue to execute rules after the occur error rule 67 | err := eng.Execute(ruleBuilder, true) 68 | end := time.Now().UnixNano() 69 | if err != nil{ 70 | logrus.Errorf("execute rule error: %v", err) 71 | } 72 | logrus.Infof("execute rule cost %d ns",end-start) 73 | } 74 | } 75 | 76 | func Test_struct(t *testing.T) { 77 | exe_struct() 78 | } 79 | 80 | 81 | 82 | 83 | 84 | 85 | --------------------------------------------------------------------------------