├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── cmp.go ├── cmp_test.go ├── doc.go ├── example_test.go ├── go.mod ├── go.sum ├── helper.go ├── helper_test.go ├── internal ├── grammar │ ├── Yql.g4 │ ├── Yql.tokens │ ├── YqlLexer.tokens │ ├── yql_base_listener.go │ ├── yql_lexer.go │ ├── yql_listener.go │ └── yql_parser.go ├── lambda │ ├── Lambda.g4 │ ├── Lambda.tokens │ ├── LambdaLexer.tokens │ ├── lambda_base_listener.go │ ├── lambda_lexer.go │ ├── lambda_listener.go │ └── lambda_parser.go └── stack │ └── stack.go ├── lambda ├── instruct.go ├── lambda.go └── lambda_test.go ├── yql.go └── yql_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .antlr 2 | debug.test 3 | .vscode -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.8.x 4 | - 1.9.x 5 | script: go get "github.com/stretchr/testify/assert" && go test . -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Deen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### YQL(Yet another-Query-Language) 2 | [![Build Status](https://www.travis-ci.org/caibirdme/yql.svg?branch=master)](https://www.travis-ci.org/caibirdme/yql) 3 | [![GoDoc](https://godoc.org/github.com/caibirdme/yql?status.svg)](https://godoc.org/github.com/caibirdme/yql) 4 | 5 | 6 | YQL is very similar with the `where` part of sql. You can see it as another sql which also support comparison between two sets. YQL have nearly no new concepts, so you can use it well short after reading the examples.Though it's designed for rule engine, it can be widely used in your code logic. 7 | 8 | ### Install 9 | `go get github.com/caibirdme/yql` 10 | 11 | ### Exmaple 12 | See more examples in the `yql_test.go` and godoc. 13 | 14 | ``` go 15 | rawYQL := `name='deen' and age>=23 and (hobby in ('soccer', 'swim') or score>90))` 16 | result, _ := yql.Match(rawYQL, map[string]interface{}{ 17 | "name": "deen", 18 | "age": int64(23), 19 | "hobby": "basketball", 20 | "score": int64(100), 21 | }) 22 | fmt.Println(result) 23 | rawYQL = `score ∩ (7,1,9,5,3)` 24 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 25 | "score": []int64{3, 100, 200}, 26 | }) 27 | fmt.Println(result) 28 | rawYQL = `score in (7,1,9,5,3)` 29 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 30 | "score": []int64{3, 5, 2}, 31 | }) 32 | fmt.Println(result) 33 | rawYQL = `score.sum() > 10` 34 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 35 | "score": []int{1, 2, 3, 4, 5}, 36 | }) 37 | fmt.Println(result) 38 | //Output: 39 | //true 40 | //true 41 | //false 42 | //true 43 | ``` 44 | 45 | And In most cases, you can use `Rule` to cache the AST and then use `Match` to get the result, which could avoid hundreds of thousands of repeated parsing process. 46 | 47 | ```go 48 | rawYQL := `name='deen' and age>=23 and (hobby in ('soccer', 'swim') or score>90)` 49 | ruler,_ := yql.Rule(rawYQL) 50 | 51 | result, _ := ruler.Match(map[string]interface{}{ 52 | "name": "deen", 53 | "age": 23, 54 | "hobby": "basketball", 55 | "score": int64(100), 56 | }) 57 | fmt.Println(result) 58 | result, _ = ruler.Match(map[string]interface{}{ 59 | "name": "deen", 60 | "age": 23, 61 | "hobby": "basketball", 62 | "score": int64(90), 63 | }) 64 | fmt.Println(result) 65 | //Output: 66 | //true 67 | //false 68 | ``` 69 | 70 | Though the to be matched data is the type of `map[string]interface{}`, there're only 5 types supported: 71 | * int 72 | * int64 73 | * float64 74 | * string 75 | * bool 76 | 77 | ### Helpers 78 | In `score.sum() > 10`, `sum` is a helper function which adds up all the numbers in score, which also means the type of score must be one of the []int,[]int64 or []float64. 79 | 80 | This repo is in the early stage, so now there are just a few helpers, feel free to create an issue about your needs. Supported helpers are listed below: 81 | * sum: ... 82 | * count: return the length of a slice or 1 if not a slice 83 | * avg: return the average number of a slice(`float64(total)/float64(len(slice))`) 84 | * max: return the maximum number in a slice 85 | * min: return the minimum number in a slice 86 | 87 | ### Usage scenario 88 | Obviously, it's easy to use in rule engine. 89 | ```go 90 | var handlers = map[int]func(map[string]interface{}){ 91 | 1: sendEmail, 92 | 2: sendMessage, 93 | 3: alertBoss, 94 | } 95 | 96 | data := resolvePostParamsFromRequest(request) 97 | rules := getRulesFromDB(sql) 98 | 99 | for _,rule := range rules { 100 | if success,_ := yql.Match(rule.YQL, data); success { 101 | handler := handlers[rule.ID] 102 | handler(data) 103 | break 104 | } 105 | } 106 | ``` 107 | 108 | Also, it can be used in your daily work, which could significantly reduce the deeply embebbed `if else` statements: 109 | ```go 110 | func isVIP(user User) bool { 111 | rule := fmt.Sprintf("monthly_vip=true and now<%s or eternal_vip=1 or ab_test!=false", user.ExpireTime) 112 | ok,_ := yql.Match(rule, map[string]interface{}{ 113 | "monthly_vip": user.IsMonthlyVIP, 114 | "now": time.Now().Unix(), 115 | "eternal_vip": user.EternalFlag, 116 | "ab_test": isABTestMatched(user), 117 | }) 118 | return ok 119 | } 120 | ``` 121 | 122 | Even, you can use `json.Marshal` to generate the map[string]interface{} if you don't want to write it manually. Make sure the structure tag should be same as the name in rawYQL. 123 | 124 | ### Syntax 125 | See [grammar file](./internal/grammar/Yql.g4) 126 | 127 | ### Compatibility promise 128 | The API `Match`is stable now. Its grammar won't change any more, and what I only will do next is to optimize, speed up and add more helpers if needed. 129 | 130 | 131 | ### Further Trial 132 | Though it's kinder difficult to create a robust new Go compiler, there're still some interesting things could do. For example, bringing lambda function in Go which maybe look like: 133 | ```go 134 | var scores = []int{1,2,3,4,5,6,7,8,9,10} 135 | newSlice := yql.Filter(`(v) => v % 2 == 0`).Map(`(v) => v*v`).Call(scores).Interface() 136 | //[]int{4,16,36,64,100} 137 | ``` 138 | If the lambda function won't change all time, it can be cached like opcode, which is as fast as the compiled code. And in most cases, who care?(pythoner?) 139 | 140 | It's not easy but interesting, isn't it? Welcome to join me, open some issues and talk about your ideas with me. Maybe one day it can become a pre-compile tool like [babel](http://babeljs.io/) in javascript. 141 | 142 | #### Attention 143 | `Lambda expression` now is in its very early stage, **DO NOT USE IT IN PRODUCTION**. 144 | 145 | You can take a quick preview in [test case](/lambda/lambda_test.go) 146 | 147 | ```go 148 | type Student struct { 149 | Age int 150 | Name string 151 | } 152 | 153 | var students = []Student{ 154 | Student{ 155 | Name: "deen", 156 | Age: 24, 157 | }, 158 | Student{ 159 | Name: "bob", 160 | Age: 22, 161 | }, 162 | Student{ 163 | Name: "alice", 164 | Age: 23, 165 | }, 166 | Student{ 167 | Name: "tom", 168 | Age: 25, 169 | }, 170 | Student{ 171 | Name: "jerry", 172 | Age: 20, 173 | }, 174 | } 175 | 176 | t = yql.Filter(`(v) => v.Age > 23 || v.Name == "alice"`).Call(students).Interface() 177 | res,_ := t.([]Student) 178 | // res: Student{"deen",24} Student{"alice", 23} Student{"tom", 25} 179 | ``` 180 | 181 | Chainable 182 | ```go 183 | dst := []int{1, 2, 3, 4, 5, 6, 7} 184 | r := Filter(`(v) => v > 3 && v <= 7`).Map(`(v) => v << 2`).Filter(`(v) => v % 8 == 0`).Call(dst) 185 | s, err := r.Interface() 186 | ass := assert.New(t) 187 | ass.NoError(err) 188 | ass.Equal([]int{16, 24}, s) 189 | ``` -------------------------------------------------------------------------------- /cmp.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "math" 5 | "sort" 6 | "strconv" 7 | ) 8 | 9 | const ( 10 | opEqual = "=" 11 | opNotEqual = "!=" 12 | opLarger = ">" 13 | opLargerEqual = ">=" 14 | opLess = "<" 15 | opLessEqual = "<=" 16 | opInter = "∩" 17 | opNotInter = "!∩" 18 | opIn = "in" 19 | opNotIn = "!in" 20 | ) 21 | 22 | const ( 23 | epsilon = float64(1e-10) 24 | ) 25 | 26 | func cmpInt(actual, expect int64, op string) bool { 27 | switch op { 28 | case opEqual, opIn: 29 | return actual == expect 30 | case opNotEqual, opNotIn: 31 | return actual != expect 32 | case opLarger: 33 | return actual > expect 34 | case opLargerEqual: 35 | return actual >= expect 36 | case opLess: 37 | return actual < expect 38 | case opLessEqual: 39 | return actual <= expect 40 | default: 41 | return false 42 | } 43 | } 44 | 45 | func cmpFloat(actual, expect float64, op string) bool { 46 | switch op { 47 | case opEqual: 48 | return floatEqual(actual, expect) 49 | case opNotEqual: 50 | return !floatEqual(actual, expect) 51 | case opLarger: 52 | return actual > expect 53 | case opLargerEqual: 54 | return !(actual < expect) 55 | case opLess: 56 | return actual < expect 57 | case opLessEqual: 58 | return floatLessEqual(actual, expect) 59 | default: 60 | return false 61 | } 62 | } 63 | 64 | func cmpStr(actual, expect string, op string) bool { 65 | switch op { 66 | case opEqual, opIn: 67 | return actual == expect 68 | case opNotEqual, opNotIn: 69 | return actual != expect 70 | case opLarger: 71 | return actual > expect 72 | case opLargerEqual: 73 | return actual >= expect 74 | case opLess: 75 | return actual < expect 76 | case opLessEqual: 77 | return actual <= expect 78 | default: 79 | return false 80 | } 81 | } 82 | 83 | func cmpBool(actual, expect bool, op string) bool { 84 | switch op { 85 | case opEqual: 86 | return actual == expect 87 | case opNotEqual: 88 | return actual != expect 89 | default: 90 | return false 91 | } 92 | } 93 | 94 | func shouldCompareSet(op string) bool { 95 | switch op { 96 | case opEqual, opNotEqual, opInter, opNotInter, opIn, opNotIn: 97 | return true 98 | default: 99 | return false 100 | } 101 | } 102 | 103 | func compareSet(actual interface{}, expect []string, op string) bool { 104 | if !shouldCompareSet(op) { 105 | return false 106 | } 107 | switch actualArr := actual.(type) { 108 | case int: 109 | return cmpIntSet([]int64{int64(actualArr)}, expect, op) 110 | case int64: 111 | return cmpIntSet([]int64{actualArr}, expect, op) 112 | case float64: 113 | return cmpFloatSet([]float64{actualArr}, expect, op) 114 | case string: 115 | return cmpStringSet([]string{actualArr}, expect, op) 116 | case []int: 117 | return cmpIntSet(intArr2i64Arr(actualArr), expect, op) 118 | case []int64: 119 | return cmpIntSet(actualArr, expect, op) 120 | case []float64: 121 | return cmpFloatSet(actualArr, expect, op) 122 | case []string: 123 | return cmpStringSet(actualArr, expect, op) 124 | default: 125 | return false 126 | } 127 | } 128 | 129 | func intArr2i64Arr(arr []int) []int64 { 130 | length := len(arr) 131 | if length == 0 { 132 | return nil 133 | } 134 | res := make([]int64, 0, length) 135 | for _, v := range arr { 136 | res = append(res, int64(v)) 137 | } 138 | return res 139 | } 140 | 141 | var intSetCmpFunc = map[string]func([]int64, []int64) bool{ 142 | opInter: intSetInter, 143 | opNotInter: intSetNotInter, 144 | opIn: intSetBelong, 145 | opNotIn: intSetNotBelong, 146 | } 147 | 148 | func cmpIntSet(actualVals []int64, expectVals []string, op string) bool { 149 | expectArr := make([]int64, 0, len(expectVals)) 150 | for _, expect := range expectVals { 151 | v, err := strconv.ParseInt(removeQuote(expect), 10, 64) 152 | if nil != err { 153 | return false 154 | } 155 | expectArr = append(expectArr, v) 156 | } 157 | cmp, ok := intSetCmpFunc[op] 158 | if ok { 159 | return cmp(actualVals, expectArr) 160 | } 161 | return false 162 | } 163 | 164 | var floatSetCmpFunc = map[string]func([]float64, []float64) bool{ 165 | opInter: floatSetInter, 166 | opNotInter: floatSetNotInter, 167 | opIn: floatSetBelong, 168 | opNotIn: floatSetNotBelong, 169 | } 170 | 171 | func cmpFloatSet(actualVals []float64, expectVals []string, op string) bool { 172 | expectArr := make([]float64, 0, len(expectVals)) 173 | for _, expect := range expectVals { 174 | v, err := strconv.ParseFloat(removeQuote(expect), 64) 175 | if nil != err { 176 | return false 177 | } 178 | expectArr = append(expectArr, v) 179 | } 180 | cmp, ok := floatSetCmpFunc[op] 181 | if ok { 182 | return cmp(actualVals, expectArr) 183 | } 184 | return false 185 | } 186 | 187 | var stringSetCmpFunc = map[string]func([]string, []string) bool{ 188 | opInter: strSetInter, 189 | opNotInter: strSetNotInter, 190 | opIn: strSetBelong, 191 | opNotIn: strSetNotBelong, 192 | } 193 | 194 | func cmpStringSet(actual []string, expect []string, op string) bool { 195 | cmp, ok := stringSetCmpFunc[op] 196 | if !ok { 197 | return false 198 | } 199 | expectVals := make([]string, 0, len(expect)) 200 | for _, v := range expect { 201 | expectVals = append(expectVals, removeQuote(v)) 202 | } 203 | return cmp(actual, expectVals) 204 | } 205 | 206 | func intSetBelong(actualVals []int64, expectVals []int64) bool { 207 | length := len(expectVals) 208 | if len(actualVals) == 0 || len(actualVals) > length { 209 | return false 210 | } 211 | expectArr := i64Arr(expectVals) 212 | sort.Sort(expectArr) 213 | for _, actual := range actualVals { 214 | t := sort.Search(length, func(i int) bool { 215 | return actual <= expectArr[i] 216 | }) 217 | if t >= length || actual != expectArr[t] { 218 | return false 219 | } 220 | } 221 | return true 222 | } 223 | 224 | func intSetNotBelong(actualVals []int64, expectVals []int64) bool { 225 | return !intSetBelong(actualVals, expectVals) 226 | } 227 | 228 | func intSetInter(actualVals []int64, expectVals []int64) bool { 229 | length := len(expectVals) 230 | if len(actualVals) == 0 || length == 0 { 231 | return false 232 | } 233 | expectArr := i64Arr(expectVals) 234 | sort.Sort(expectArr) 235 | for _, actual := range actualVals { 236 | t := sort.Search(length, func(i int) bool { 237 | return actual <= expectArr[i] 238 | }) 239 | if t < length && actual == expectArr[t] { 240 | return true 241 | } 242 | } 243 | return false 244 | } 245 | 246 | func intSetNotInter(actualVals []int64, expectVals []int64) bool { 247 | return !intSetInter(actualVals, expectVals) 248 | } 249 | 250 | type i64Arr []int64 251 | 252 | func (arr i64Arr) Len() int { 253 | return len(arr) 254 | } 255 | 256 | func (arr i64Arr) Less(i, j int) bool { 257 | return arr[i] < arr[j] 258 | } 259 | 260 | func (arr i64Arr) Swap(i, j int) { 261 | arr[i], arr[j] = arr[j], arr[i] 262 | } 263 | 264 | func floatSetBelong(actualVals []float64, expectVals []float64) bool { 265 | length := len(expectVals) 266 | if len(actualVals) == 0 || len(actualVals) > length { 267 | return false 268 | } 269 | sort.Float64s(expectVals) 270 | for _, actual := range actualVals { 271 | t := sort.Search(length, func(i int) bool { 272 | return floatLessEqual(actual, expectVals[i]) 273 | }) 274 | if t >= length || !floatEqual(actual, expectVals[t]) { 275 | return false 276 | } 277 | } 278 | return true 279 | } 280 | 281 | func floatSetNotBelong(actualVals []float64, expectVals []float64) bool { 282 | return !floatSetBelong(actualVals, expectVals) 283 | } 284 | 285 | func floatSetInter(actualVals []float64, expectVals []float64) bool { 286 | length := len(expectVals) 287 | if len(actualVals) == 0 || length == 0 { 288 | return false 289 | } 290 | sort.Float64s(expectVals) 291 | for _, actual := range actualVals { 292 | t := sort.Search(length, func(i int) bool { 293 | return floatLessEqual(actual, expectVals[i]) 294 | }) 295 | if t < length && floatEqual(actual, expectVals[t]) { 296 | return true 297 | } 298 | } 299 | return false 300 | } 301 | 302 | func floatSetNotInter(actualVals []float64, expectVals []float64) bool { 303 | return !floatSetInter(actualVals, expectVals) 304 | } 305 | 306 | func strSetBelong(actualVals []string, expectVals []string) bool { 307 | length := len(expectVals) 308 | if len(actualVals) == 0 || len(actualVals) > length { 309 | return false 310 | } 311 | sort.Strings(expectVals) 312 | for _, actual := range actualVals { 313 | t := sort.SearchStrings(expectVals, actual) 314 | if t >= length || actual != expectVals[t] { 315 | return false 316 | } 317 | } 318 | return true 319 | } 320 | 321 | func strSetNotBelong(actualVals []string, expectVals []string) bool { 322 | return !strSetBelong(actualVals, expectVals) 323 | } 324 | 325 | func strSetInter(actualVals []string, expectVals []string) bool { 326 | length := len(expectVals) 327 | if len(actualVals) == 0 || length == 0 { 328 | return false 329 | } 330 | sort.Strings(expectVals) 331 | for _, actual := range actualVals { 332 | t := sort.SearchStrings(expectVals, actual) 333 | if t < length && actual == expectVals[t] { 334 | return true 335 | } 336 | } 337 | return false 338 | } 339 | 340 | func strSetNotInter(actualVals []string, expectVals []string) bool { 341 | return !strSetInter(actualVals, expectVals) 342 | } 343 | 344 | func floatEqual(a, b float64) bool { 345 | return math.Abs(a-b) < epsilon 346 | } 347 | 348 | func floatLessEqual(a, b float64) bool { 349 | return a < b || floatEqual(a, b) 350 | } 351 | -------------------------------------------------------------------------------- /cmp_test.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestIntSetBelong(t *testing.T) { 10 | var testData = []struct { 11 | ina, inb []int64 12 | out bool 13 | }{ 14 | { 15 | ina: []int64{3, 1, 2}, 16 | inb: []int64{5, 1, 4, 3, 2}, 17 | out: true, 18 | }, 19 | { 20 | ina: []int64{3, 1, 2}, 21 | inb: []int64{5, 1, 4, 3, 0}, 22 | out: false, 23 | }, 24 | { 25 | ina: []int64{3, 1, 2, 6, 8, 10, 11}, 26 | inb: []int64{5, 1, 4, 3, 0}, 27 | out: false, 28 | }, 29 | { 30 | ina: []int64{}, 31 | inb: []int64{1}, 32 | out: false, 33 | }, 34 | { 35 | ina: []int64{1}, 36 | inb: []int64{1}, 37 | out: true, 38 | }, 39 | { 40 | ina: []int64{}, 41 | inb: []int64{}, 42 | out: false, 43 | }, 44 | } 45 | ass := assert.New(t) 46 | for _, tc := range testData { 47 | ass.Equal(tc.out, intSetBelong(tc.ina, tc.inb), "ina=%+v||inb=%+v", tc.ina, tc.inb) 48 | } 49 | } 50 | 51 | func TestIntSetInter(t *testing.T) { 52 | var testData = []struct { 53 | ina, inb []int64 54 | out bool 55 | }{ 56 | { 57 | ina: []int64{3, 1, 2}, 58 | inb: []int64{5, 1, 4, 3, 2}, 59 | out: true, 60 | }, 61 | { 62 | ina: []int64{3, 1, 2}, 63 | inb: []int64{5, 1, 4, 3, 0}, 64 | out: true, 65 | }, 66 | { 67 | ina: []int64{3, 1, 2, 6, 8, 10, 11}, 68 | inb: []int64{5, 1, 4, 3, 0}, 69 | out: true, 70 | }, 71 | { 72 | ina: []int64{}, 73 | inb: []int64{1}, 74 | out: false, 75 | }, 76 | { 77 | ina: []int64{1}, 78 | inb: []int64{1}, 79 | out: true, 80 | }, 81 | { 82 | ina: []int64{}, 83 | inb: []int64{}, 84 | out: false, 85 | }, 86 | { 87 | ina: []int64{1, 3, 5, 7, 9}, 88 | inb: []int64{2, 4, 6, 8, 10, 5}, 89 | out: true, 90 | }, 91 | { 92 | ina: []int64{1, 3, 5, 7, 9}, 93 | inb: []int64{2, 4, 6, 8, 10, 12}, 94 | out: false, 95 | }, 96 | } 97 | ass := assert.New(t) 98 | for _, tc := range testData { 99 | ass.Equal(tc.out, intSetInter(tc.ina, tc.inb), "ina=%+v||inb=%+v", tc.ina, tc.inb) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package yql implements sql-like grammar for rule engines. 3 | 4 | yql support compare operators like: 5 | 6 | = 7 | != 8 | > 9 | >= 10 | < 11 | <= 12 | in 13 | !in 14 | ∩ // intersection (not the letter n) 15 | !∩ 16 | 17 | below are legal yqls: 18 | 19 | a=1 and b>2 and (c<=3 or d in ('boy','girl')) or e ∩ (1,2,3) 20 | a=boy and b=1 or c in ('boy','girl') 21 | // boy will be interpreted as string if the type of a is string 22 | // 1 will be interpreted according to b's type 23 | 24 | for more details,see yql_test.go 25 | */ 26 | package yql 27 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package yql_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/caibirdme/yql" 7 | ) 8 | 9 | func ExampleMatch() { 10 | rawYQL := `name='deen' and age>=23 and (hobby in ('soccer', 'swim') or score>90)` 11 | result, _ := yql.Match(rawYQL, map[string]interface{}{ 12 | "name": "deen", 13 | "age": 23, 14 | "hobby": "basketball", 15 | "score": int64(100), 16 | }) 17 | fmt.Println(result) 18 | rawYQL = `score ∩ (7,1,9,5,3)` 19 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 20 | "score": []int64{3, 100, 200}, 21 | }) 22 | fmt.Println(result) 23 | rawYQL = `score in (7,1,9,5,3)` 24 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 25 | "score": []int64{3, 5, 2}, 26 | }) 27 | fmt.Println(result) 28 | rawYQL = `score.sum() > 10` 29 | result, _ = yql.Match(rawYQL, map[string]interface{}{ 30 | "score": []int{1, 2, 3, 4, 5}, 31 | }) 32 | fmt.Println(result) 33 | //Output: 34 | //true 35 | //true 36 | //false 37 | //true 38 | } 39 | 40 | func ExampleRule() { 41 | rawYQL := `name='deen' and age>=23 and (hobby in ('soccer', 'swim') or score>90)` 42 | ruler, _ := yql.Rule(rawYQL) 43 | result, _ := ruler.Match(map[string]interface{}{ 44 | "name": "deen", 45 | "age": 23, 46 | "hobby": "basketball", 47 | "score": int64(100), 48 | }) 49 | fmt.Println(result) 50 | result, _ = ruler.Match(map[string]interface{}{ 51 | "name": "deen", 52 | "age": 23, 53 | "hobby": "basketball", 54 | "score": int64(90), 55 | }) 56 | fmt.Println(result) 57 | //Output: 58 | //true 59 | //false 60 | } 61 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/caibirdme/yql 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/antlr/antlr4 v0.0.0-20210121092344-5dce78c87a9e 7 | github.com/stretchr/testify v1.7.0 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/antlr/antlr4 v0.0.0-20210121092344-5dce78c87a9e h1:1YJFJAhOCHWLME6YEBM0BI96x4P5mKEl6i6pdgg36WI= 2 | github.com/antlr/antlr4 v0.0.0-20210121092344-5dce78c87a9e/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y= 3 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= 8 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 9 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 10 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 11 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 12 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 13 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 14 | -------------------------------------------------------------------------------- /helper.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | var supportFuncHandler = map[string]func(interface{}) interface{}{ 9 | "count": countRunner, 10 | "sum": sumRunner, 11 | "avg": avgRunner, 12 | "max": maxRunner, 13 | "min": minRunner, 14 | } 15 | 16 | func errFuncNotSupport(funcName string) error { 17 | return fmt.Errorf("%s isn't supported", funcName) 18 | } 19 | 20 | func funcRuner(actual interface{}, funcs []string) (interface{}, error) { 21 | if 0 == len(funcs) { 22 | return actual, nil 23 | } 24 | for _, fName := range funcs { 25 | fn, ok := supportFuncHandler[fName] 26 | if !ok { 27 | return nil, errFuncNotSupport(fName) 28 | } 29 | actual = fn(actual) 30 | } 31 | return actual, nil 32 | } 33 | 34 | func countRunner(in interface{}) interface{} { 35 | arr := reflect.ValueOf(in) 36 | if arr.Type().Kind() == reflect.Slice { 37 | return arr.Len() 38 | } 39 | return 1 40 | } 41 | 42 | func sumRunner(in interface{}) interface{} { 43 | switch t := in.(type) { 44 | case []int: 45 | return sumInt(t) 46 | case []int64: 47 | return sumInt64(t) 48 | case []float64: 49 | return sumFloat64(t) 50 | default: 51 | return in 52 | } 53 | } 54 | 55 | func sumInt(arr []int) int { 56 | var res int 57 | for _, v := range arr { 58 | res += v 59 | } 60 | return res 61 | } 62 | 63 | func sumInt64(arr []int64) int64 { 64 | var res int64 65 | for _, v := range arr { 66 | res += v 67 | } 68 | return res 69 | } 70 | 71 | func sumFloat64(arr []float64) float64 { 72 | var res float64 73 | for _, v := range arr { 74 | res += v 75 | } 76 | return res 77 | } 78 | 79 | func maxRunner(in interface{}) interface{} { 80 | switch t := in.(type) { 81 | case []int: 82 | return maxInt(t) 83 | case []int64: 84 | return maxInt64(t) 85 | case []float64: 86 | return maxFloat64(t) 87 | default: 88 | return in 89 | } 90 | } 91 | 92 | func maxInt(arr []int) int { 93 | var res = arr[0] 94 | length := len(arr) 95 | for i := 1; i < length; i++ { 96 | t := arr[i] 97 | if t > res { 98 | res = t 99 | } 100 | } 101 | return res 102 | } 103 | 104 | func maxInt64(arr []int64) int64 { 105 | var res = arr[0] 106 | length := len(arr) 107 | for i := 1; i < length; i++ { 108 | t := arr[i] 109 | if t > res { 110 | res = t 111 | } 112 | } 113 | return res 114 | } 115 | 116 | func maxFloat64(arr []float64) float64 { 117 | var res = arr[0] 118 | length := len(arr) 119 | for i := 1; i < length; i++ { 120 | t := arr[i] 121 | if t > res { 122 | res = t 123 | } 124 | } 125 | return res 126 | } 127 | 128 | func minRunner(in interface{}) interface{} { 129 | switch t := in.(type) { 130 | case []int: 131 | return minInt(t) 132 | case []int64: 133 | return minInt64(t) 134 | case []float64: 135 | return minFloat64(t) 136 | default: 137 | return in 138 | } 139 | } 140 | 141 | func minInt(arr []int) int { 142 | var res = arr[0] 143 | length := len(arr) 144 | for i := 1; i < length; i++ { 145 | t := arr[i] 146 | if t < res { 147 | res = t 148 | } 149 | } 150 | return res 151 | } 152 | 153 | func minInt64(arr []int64) int64 { 154 | var res = arr[0] 155 | length := len(arr) 156 | for i := 1; i < length; i++ { 157 | t := arr[i] 158 | if t < res { 159 | res = t 160 | } 161 | } 162 | return res 163 | } 164 | 165 | func minFloat64(arr []float64) float64 { 166 | var res = arr[0] 167 | length := len(arr) 168 | for i := 1; i < length; i++ { 169 | t := arr[i] 170 | if t < res { 171 | res = t 172 | } 173 | } 174 | return res 175 | } 176 | 177 | func avgRunner(in interface{}) interface{} { 178 | switch t := in.(type) { 179 | case []int: 180 | return avgInt(t) 181 | case []int64: 182 | return avgInt64(t) 183 | case []float64: 184 | return avgFloat64(t) 185 | default: 186 | return in 187 | } 188 | } 189 | 190 | func avgInt(arr []int) float64 { 191 | var total int 192 | for _, v := range arr { 193 | total += v 194 | } 195 | return float64(total) / float64(len(arr)) 196 | } 197 | 198 | func avgInt64(arr []int64) float64 { 199 | var total int64 200 | for _, v := range arr { 201 | total += v 202 | } 203 | return float64(total) / float64(len(arr)) 204 | } 205 | 206 | func avgFloat64(arr []float64) float64 { 207 | var total float64 208 | for _, v := range arr { 209 | total += v 210 | } 211 | return total / float64(len(arr)) 212 | } 213 | -------------------------------------------------------------------------------- /helper_test.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestSum_Int(t *testing.T) { 10 | var testData = []struct { 11 | ryql string 12 | data map[string]interface{} 13 | out bool 14 | }{ 15 | { 16 | ryql: `a.sum() > 10`, 17 | data: map[string]interface{}{ 18 | "a": []int{1, 2, 3, 4}, 19 | }, 20 | out: false, 21 | }, 22 | { 23 | ryql: `a.sum() >= 10`, 24 | data: map[string]interface{}{ 25 | "a": []int{1, 2, 3, 4}, 26 | }, 27 | out: true, 28 | }, 29 | { 30 | ryql: `a.sum() > 10`, 31 | data: map[string]interface{}{ 32 | "a": []int{2, 2, 3, 4}, 33 | }, 34 | out: true, 35 | }, 36 | } 37 | ass := assert.New(t) 38 | for _, tc := range testData { 39 | actual, err := Match(tc.ryql, tc.data) 40 | ass.NoError(err) 41 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 42 | } 43 | } 44 | 45 | func TestSum_Int64(t *testing.T) { 46 | var testData = []struct { 47 | ryql string 48 | data map[string]interface{} 49 | out bool 50 | }{ 51 | { 52 | ryql: `a.sum() > 10`, 53 | data: map[string]interface{}{ 54 | "a": []int64{1, 2, 3, 4}, 55 | }, 56 | out: false, 57 | }, 58 | { 59 | ryql: `a.sum() >= 10`, 60 | data: map[string]interface{}{ 61 | "a": []int64{1, 2, 3, 4}, 62 | }, 63 | out: true, 64 | }, 65 | { 66 | ryql: `a.sum() > 10`, 67 | data: map[string]interface{}{ 68 | "a": []int64{2, 2, 3, 4}, 69 | }, 70 | out: true, 71 | }, 72 | } 73 | ass := assert.New(t) 74 | for _, tc := range testData { 75 | actual, err := Match(tc.ryql, tc.data) 76 | ass.NoError(err) 77 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 78 | } 79 | } 80 | 81 | func TestSum_Float64(t *testing.T) { 82 | var testData = []struct { 83 | ryql string 84 | data map[string]interface{} 85 | out bool 86 | }{ 87 | { 88 | ryql: `a.sum() >= 10`, 89 | data: map[string]interface{}{ 90 | "a": []float64{1.0, 2.0, 3.0, 4.0}, 91 | }, 92 | out: true, 93 | }, 94 | { 95 | ryql: `a.sum() > 10`, 96 | data: map[string]interface{}{ 97 | "a": []float64{1.0, 2.0, 3.0, 4.0}, 98 | }, 99 | out: false, 100 | }, 101 | { 102 | ryql: `a.sum() > 10`, 103 | data: map[string]interface{}{ 104 | "a": []float64{2.0, 2.0, 3.0, 4.0}, 105 | }, 106 | out: true, 107 | }, 108 | } 109 | ass := assert.New(t) 110 | for _, tc := range testData { 111 | actual, err := Match(tc.ryql, tc.data) 112 | ass.NoError(err) 113 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 114 | } 115 | } 116 | 117 | func TestSum(t *testing.T) { 118 | var testData = []struct { 119 | ryql string 120 | data map[string]interface{} 121 | out bool 122 | }{ 123 | { 124 | ryql: `a.sum() > 10 and foo=true`, 125 | data: map[string]interface{}{ 126 | "a": []int{2, 2, 3, 4}, 127 | "foo": true, 128 | }, 129 | out: true, 130 | }, 131 | { 132 | ryql: `a.sum() > 10 and foo=false`, 133 | data: map[string]interface{}{ 134 | "a": []int{2, 2, 3, 4}, 135 | "foo": true, 136 | }, 137 | out: false, 138 | }, 139 | { 140 | ryql: `a.sum() > 10 or foo=true`, 141 | data: map[string]interface{}{ 142 | "a": []int{2, 2, 3, 4}, 143 | "foo": false, 144 | }, 145 | out: true, 146 | }, 147 | { 148 | ryql: `a.sum() > 10 and a.sum() < 12 or foo=true`, 149 | data: map[string]interface{}{ 150 | "a": []int{2, 2, 3, 4}, 151 | "foo": false, 152 | }, 153 | out: true, 154 | }, 155 | } 156 | ass := assert.New(t) 157 | for _, tc := range testData { 158 | actual, err := Match(tc.ryql, tc.data) 159 | ass.NoError(err) 160 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 161 | } 162 | } 163 | 164 | func TestCount(t *testing.T) { 165 | var testData = []struct { 166 | ryql string 167 | data map[string]interface{} 168 | out bool 169 | }{ 170 | { 171 | ryql: `a.count()=4`, 172 | data: map[string]interface{}{ 173 | "a": []int{2, 2, 3, 4}, 174 | }, 175 | out: true, 176 | }, 177 | { 178 | ryql: `a.count()=4`, 179 | data: map[string]interface{}{ 180 | "a": []int64{2, 2, 3, 4}, 181 | }, 182 | out: true, 183 | }, 184 | { 185 | ryql: `a.count()=4`, 186 | data: map[string]interface{}{ 187 | "a": []float64{2, 2, 3, 4}, 188 | }, 189 | out: true, 190 | }, 191 | { 192 | ryql: `a.count()=4`, 193 | data: map[string]interface{}{ 194 | "a": []string{"1", "2", "3", "4"}, 195 | }, 196 | out: true, 197 | }, 198 | { 199 | ryql: `a.count()=1`, 200 | data: map[string]interface{}{ 201 | "a": "hello", 202 | }, 203 | out: true, 204 | }, 205 | { 206 | ryql: `a.count() > 3 and foo=false`, 207 | data: map[string]interface{}{ 208 | "a": []int{2, 2, 3, 4}, 209 | "foo": true, 210 | }, 211 | out: false, 212 | }, 213 | { 214 | ryql: `a.count() > 3 or foo=true`, 215 | data: map[string]interface{}{ 216 | "a": []int{2, 2, 3, 4}, 217 | "foo": false, 218 | }, 219 | out: true, 220 | }, 221 | } 222 | ass := assert.New(t) 223 | for _, tc := range testData { 224 | actual, err := Match(tc.ryql, tc.data) 225 | ass.NoError(err) 226 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 227 | } 228 | } 229 | 230 | func TestAvg(t *testing.T) { 231 | var testData = []struct { 232 | ryql string 233 | data map[string]interface{} 234 | out bool 235 | }{ 236 | { 237 | ryql: `a.avg()>3`, 238 | data: map[string]interface{}{ 239 | "a": []float64{4, 4}, 240 | }, 241 | out: true, 242 | }, 243 | { 244 | ryql: `a.avg()=4.5`, 245 | data: map[string]interface{}{ 246 | "a": []float64{4, 5}, 247 | }, 248 | out: true, 249 | }, 250 | { 251 | ryql: `a.avg()>3.99999`, 252 | data: map[string]interface{}{ 253 | "a": []float64{4, 4}, 254 | }, 255 | out: true, 256 | }, 257 | { 258 | ryql: `a.avg()>4`, 259 | data: map[string]interface{}{ 260 | "a": []int64{4, 4}, 261 | }, 262 | out: false, 263 | }, 264 | { 265 | ryql: `a.avg()>4`, 266 | data: map[string]interface{}{ 267 | "a": []int{4, 5}, 268 | }, 269 | out: true, 270 | }, 271 | } 272 | ass := assert.New(t) 273 | for _, tc := range testData { 274 | actual, err := Match(tc.ryql, tc.data) 275 | ass.NoError(err) 276 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 277 | } 278 | } 279 | 280 | func TestMax(t *testing.T) { 281 | var testData = []struct { 282 | ryql string 283 | data map[string]interface{} 284 | out bool 285 | }{ 286 | { 287 | ryql: `a.max()=3`, 288 | data: map[string]interface{}{ 289 | "a": []float64{1, 4}, 290 | }, 291 | out: false, 292 | }, 293 | { 294 | ryql: `a.max()=4.5`, 295 | data: map[string]interface{}{ 296 | "a": []float64{4.5, 2}, 297 | }, 298 | out: true, 299 | }, 300 | { 301 | ryql: `a.max()<10`, 302 | data: map[string]interface{}{ 303 | "a": []int64{4, 2, 8, 9}, 304 | }, 305 | out: true, 306 | }, 307 | { 308 | ryql: `a.max()<10`, 309 | data: map[string]interface{}{ 310 | "a": []int{4, 2, 10, 8, 9}, 311 | }, 312 | out: false, 313 | }, 314 | } 315 | ass := assert.New(t) 316 | for _, tc := range testData { 317 | actual, err := Match(tc.ryql, tc.data) 318 | ass.NoError(err) 319 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 320 | } 321 | } 322 | 323 | func TestMin(t *testing.T) { 324 | var testData = []struct { 325 | ryql string 326 | data map[string]interface{} 327 | out bool 328 | }{ 329 | { 330 | ryql: `a.min()=4`, 331 | data: map[string]interface{}{ 332 | "a": []float64{1, 4}, 333 | }, 334 | out: false, 335 | }, 336 | { 337 | ryql: `a.min()=4.5`, 338 | data: map[string]interface{}{ 339 | "a": []float64{4.5, 2}, 340 | }, 341 | out: false, 342 | }, 343 | { 344 | ryql: `a.min()=4.5`, 345 | data: map[string]interface{}{ 346 | "a": []float64{4.5, 4.51}, 347 | }, 348 | out: true, 349 | }, 350 | { 351 | ryql: `a.min()<10`, 352 | data: map[string]interface{}{ 353 | "a": []int64{40, 20, 80, 9, 100}, 354 | }, 355 | out: true, 356 | }, 357 | { 358 | ryql: `a.min()>10`, 359 | data: map[string]interface{}{ 360 | "a": []int{4, 2, 10, 8, 9}, 361 | }, 362 | out: false, 363 | }, 364 | } 365 | ass := assert.New(t) 366 | for _, tc := range testData { 367 | actual, err := Match(tc.ryql, tc.data) 368 | ass.NoError(err) 369 | ass.Equal(tc.out, actual, "rawYQL:%s||data:%+v", tc.ryql, tc.data) 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /internal/grammar/Yql.g4: -------------------------------------------------------------------------------- 1 | grammar Yql; 2 | 3 | query: expr; 4 | 5 | expr: booleanExpr #boolExpr 6 | | expr 'and' expr #andExpr 7 | | expr 'or' expr #orExpr 8 | | '(' expr ')' #embbedExpr 9 | ; 10 | 11 | booleanExpr: leftexpr op=('='|'!='|'>'|'<'|'>='|'<=') value 12 | | leftexpr op=('in'|'!in'|'∩'|'!∩') '(' value (',' value)* ')' 13 | ; 14 | leftexpr: FIELDNAME (('.' FUNC '()')+)? 15 | ; 16 | value: STRING | INT | FLOAT | TRUE | FALSE; 17 | 18 | TRUE: 'true'; 19 | FALSE: 'false'; 20 | FUNC: 'count'|'sum'|'avg'|'max'|'min'; 21 | FIELDNAME: ([a-zA-Z]|'_')+; 22 | STRING: '\'' .*? '\''; 23 | fragment DIGIT: [0-9]; 24 | INT: ('+'|'-')? DIGIT+; 25 | FLOAT: ('+'|'-')? DIGIT+ '.' DIGIT*; 26 | WS: [ \t\r\n]+ -> skip; 27 | -------------------------------------------------------------------------------- /internal/grammar/Yql.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | TRUE=18 19 | FALSE=19 20 | FUNC=20 21 | FIELDNAME=21 22 | STRING=22 23 | INT=23 24 | FLOAT=24 25 | WS=25 26 | 'and'=1 27 | 'or'=2 28 | '('=3 29 | ')'=4 30 | '='=5 31 | '!='=6 32 | '>'=7 33 | '<'=8 34 | '>='=9 35 | '<='=10 36 | 'in'=11 37 | '!in'=12 38 | '∩'=13 39 | '!∩'=14 40 | ','=15 41 | '.'=16 42 | '()'=17 43 | 'true'=18 44 | 'false'=19 45 | -------------------------------------------------------------------------------- /internal/grammar/YqlLexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | TRUE=18 19 | FALSE=19 20 | FUNC=20 21 | FIELDNAME=21 22 | STRING=22 23 | INT=23 24 | FLOAT=24 25 | WS=25 26 | 'and'=1 27 | 'or'=2 28 | '('=3 29 | ')'=4 30 | '='=5 31 | '!='=6 32 | '>'=7 33 | '<'=8 34 | '>='=9 35 | '<='=10 36 | 'in'=11 37 | '!in'=12 38 | '∩'=13 39 | '!∩'=14 40 | ','=15 41 | '.'=16 42 | '()'=17 43 | 'true'=18 44 | 'false'=19 45 | -------------------------------------------------------------------------------- /internal/grammar/yql_base_listener.go: -------------------------------------------------------------------------------- 1 | // Generated from Yql.g4 by ANTLR 4.7. 2 | 3 | package grammar // Yql 4 | import "github.com/antlr/antlr4/runtime/Go/antlr" 5 | 6 | // BaseYqlListener is a complete listener for a parse tree produced by YqlParser. 7 | type BaseYqlListener struct{} 8 | 9 | var _ YqlListener = &BaseYqlListener{} 10 | 11 | // VisitTerminal is called when a terminal node is visited. 12 | func (s *BaseYqlListener) VisitTerminal(node antlr.TerminalNode) {} 13 | 14 | // VisitErrorNode is called when an error node is visited. 15 | func (s *BaseYqlListener) VisitErrorNode(node antlr.ErrorNode) {} 16 | 17 | // EnterEveryRule is called when any rule is entered. 18 | func (s *BaseYqlListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} 19 | 20 | // ExitEveryRule is called when any rule is exited. 21 | func (s *BaseYqlListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} 22 | 23 | // EnterQuery is called when production query is entered. 24 | func (s *BaseYqlListener) EnterQuery(ctx *QueryContext) {} 25 | 26 | // ExitQuery is called when production query is exited. 27 | func (s *BaseYqlListener) ExitQuery(ctx *QueryContext) {} 28 | 29 | // EnterEmbbedExpr is called when production embbedExpr is entered. 30 | func (s *BaseYqlListener) EnterEmbbedExpr(ctx *EmbbedExprContext) {} 31 | 32 | // ExitEmbbedExpr is called when production embbedExpr is exited. 33 | func (s *BaseYqlListener) ExitEmbbedExpr(ctx *EmbbedExprContext) {} 34 | 35 | // EnterOrExpr is called when production orExpr is entered. 36 | func (s *BaseYqlListener) EnterOrExpr(ctx *OrExprContext) {} 37 | 38 | // ExitOrExpr is called when production orExpr is exited. 39 | func (s *BaseYqlListener) ExitOrExpr(ctx *OrExprContext) {} 40 | 41 | // EnterBoolExpr is called when production boolExpr is entered. 42 | func (s *BaseYqlListener) EnterBoolExpr(ctx *BoolExprContext) {} 43 | 44 | // ExitBoolExpr is called when production boolExpr is exited. 45 | func (s *BaseYqlListener) ExitBoolExpr(ctx *BoolExprContext) {} 46 | 47 | // EnterAndExpr is called when production andExpr is entered. 48 | func (s *BaseYqlListener) EnterAndExpr(ctx *AndExprContext) {} 49 | 50 | // ExitAndExpr is called when production andExpr is exited. 51 | func (s *BaseYqlListener) ExitAndExpr(ctx *AndExprContext) {} 52 | 53 | // EnterBooleanExpr is called when production booleanExpr is entered. 54 | func (s *BaseYqlListener) EnterBooleanExpr(ctx *BooleanExprContext) {} 55 | 56 | // ExitBooleanExpr is called when production booleanExpr is exited. 57 | func (s *BaseYqlListener) ExitBooleanExpr(ctx *BooleanExprContext) {} 58 | 59 | // EnterLeftexpr is called when production leftexpr is entered. 60 | func (s *BaseYqlListener) EnterLeftexpr(ctx *LeftexprContext) {} 61 | 62 | // ExitLeftexpr is called when production leftexpr is exited. 63 | func (s *BaseYqlListener) ExitLeftexpr(ctx *LeftexprContext) {} 64 | 65 | // EnterValue is called when production value is entered. 66 | func (s *BaseYqlListener) EnterValue(ctx *ValueContext) {} 67 | 68 | // ExitValue is called when production value is exited. 69 | func (s *BaseYqlListener) ExitValue(ctx *ValueContext) {} 70 | -------------------------------------------------------------------------------- /internal/grammar/yql_lexer.go: -------------------------------------------------------------------------------- 1 | // Generated from Yql.g4 by ANTLR 4.7. 2 | 3 | package grammar 4 | 5 | import ( 6 | "fmt" 7 | "unicode" 8 | 9 | "github.com/antlr/antlr4/runtime/Go/antlr" 10 | ) 11 | 12 | // Suppress unused import error 13 | var _ = fmt.Printf 14 | var _ = unicode.IsLetter 15 | 16 | var serializedLexerAtn = []uint16{ 17 | 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 27, 176, 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, 3, 2, 3, 23 | 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 24 | 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 25 | 3, 11, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 26 | 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 27 | 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 28 | 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 29 | 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 129, 10, 21, 3, 22, 6, 30 | 22, 132, 10, 22, 13, 22, 14, 22, 133, 3, 23, 3, 23, 7, 23, 138, 10, 23, 31 | 12, 23, 14, 23, 141, 11, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 5, 25, 32 | 148, 10, 25, 3, 25, 6, 25, 151, 10, 25, 13, 25, 14, 25, 152, 3, 26, 5, 33 | 26, 156, 10, 26, 3, 26, 6, 26, 159, 10, 26, 13, 26, 14, 26, 160, 3, 26, 34 | 3, 26, 7, 26, 165, 10, 26, 12, 26, 14, 26, 168, 11, 26, 3, 27, 6, 27, 171, 35 | 10, 27, 13, 27, 14, 27, 172, 3, 27, 3, 27, 3, 139, 2, 28, 3, 3, 5, 4, 7, 36 | 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 37 | 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 38 | 24, 47, 2, 49, 25, 51, 26, 53, 27, 3, 2, 6, 5, 2, 67, 92, 97, 97, 99, 124, 39 | 3, 2, 50, 59, 4, 2, 45, 45, 47, 47, 5, 2, 11, 12, 15, 15, 34, 34, 2, 186, 40 | 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 41 | 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 42 | 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 43 | 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 44 | 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 45 | 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 46 | 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 3, 55, 3, 2, 2, 2, 5, 59, 3, 2, 2, 2, 47 | 7, 62, 3, 2, 2, 2, 9, 64, 3, 2, 2, 2, 11, 66, 3, 2, 2, 2, 13, 68, 3, 2, 48 | 2, 2, 15, 71, 3, 2, 2, 2, 17, 73, 3, 2, 2, 2, 19, 75, 3, 2, 2, 2, 21, 78, 49 | 3, 2, 2, 2, 23, 81, 3, 2, 2, 2, 25, 84, 3, 2, 2, 2, 27, 88, 3, 2, 2, 2, 50 | 29, 90, 3, 2, 2, 2, 31, 93, 3, 2, 2, 2, 33, 95, 3, 2, 2, 2, 35, 97, 3, 51 | 2, 2, 2, 37, 100, 3, 2, 2, 2, 39, 105, 3, 2, 2, 2, 41, 128, 3, 2, 2, 2, 52 | 43, 131, 3, 2, 2, 2, 45, 135, 3, 2, 2, 2, 47, 144, 3, 2, 2, 2, 49, 147, 53 | 3, 2, 2, 2, 51, 155, 3, 2, 2, 2, 53, 170, 3, 2, 2, 2, 55, 56, 7, 99, 2, 54 | 2, 56, 57, 7, 112, 2, 2, 57, 58, 7, 102, 2, 2, 58, 4, 3, 2, 2, 2, 59, 60, 55 | 7, 113, 2, 2, 60, 61, 7, 116, 2, 2, 61, 6, 3, 2, 2, 2, 62, 63, 7, 42, 2, 56 | 2, 63, 8, 3, 2, 2, 2, 64, 65, 7, 43, 2, 2, 65, 10, 3, 2, 2, 2, 66, 67, 57 | 7, 63, 2, 2, 67, 12, 3, 2, 2, 2, 68, 69, 7, 35, 2, 2, 69, 70, 7, 63, 2, 58 | 2, 70, 14, 3, 2, 2, 2, 71, 72, 7, 64, 2, 2, 72, 16, 3, 2, 2, 2, 73, 74, 59 | 7, 62, 2, 2, 74, 18, 3, 2, 2, 2, 75, 76, 7, 64, 2, 2, 76, 77, 7, 63, 2, 60 | 2, 77, 20, 3, 2, 2, 2, 78, 79, 7, 62, 2, 2, 79, 80, 7, 63, 2, 2, 80, 22, 61 | 3, 2, 2, 2, 81, 82, 7, 107, 2, 2, 82, 83, 7, 112, 2, 2, 83, 24, 3, 2, 2, 62 | 2, 84, 85, 7, 35, 2, 2, 85, 86, 7, 107, 2, 2, 86, 87, 7, 112, 2, 2, 87, 63 | 26, 3, 2, 2, 2, 88, 89, 7, 8747, 2, 2, 89, 28, 3, 2, 2, 2, 90, 91, 7, 35, 64 | 2, 2, 91, 92, 7, 8747, 2, 2, 92, 30, 3, 2, 2, 2, 93, 94, 7, 46, 2, 2, 94, 65 | 32, 3, 2, 2, 2, 95, 96, 7, 48, 2, 2, 96, 34, 3, 2, 2, 2, 97, 98, 7, 42, 66 | 2, 2, 98, 99, 7, 43, 2, 2, 99, 36, 3, 2, 2, 2, 100, 101, 7, 118, 2, 2, 67 | 101, 102, 7, 116, 2, 2, 102, 103, 7, 119, 2, 2, 103, 104, 7, 103, 2, 2, 68 | 104, 38, 3, 2, 2, 2, 105, 106, 7, 104, 2, 2, 106, 107, 7, 99, 2, 2, 107, 69 | 108, 7, 110, 2, 2, 108, 109, 7, 117, 2, 2, 109, 110, 7, 103, 2, 2, 110, 70 | 40, 3, 2, 2, 2, 111, 112, 7, 101, 2, 2, 112, 113, 7, 113, 2, 2, 113, 114, 71 | 7, 119, 2, 2, 114, 115, 7, 112, 2, 2, 115, 129, 7, 118, 2, 2, 116, 117, 72 | 7, 117, 2, 2, 117, 118, 7, 119, 2, 2, 118, 129, 7, 111, 2, 2, 119, 120, 73 | 7, 99, 2, 2, 120, 121, 7, 120, 2, 2, 121, 129, 7, 105, 2, 2, 122, 123, 74 | 7, 111, 2, 2, 123, 124, 7, 99, 2, 2, 124, 129, 7, 122, 2, 2, 125, 126, 75 | 7, 111, 2, 2, 126, 127, 7, 107, 2, 2, 127, 129, 7, 112, 2, 2, 128, 111, 76 | 3, 2, 2, 2, 128, 116, 3, 2, 2, 2, 128, 119, 3, 2, 2, 2, 128, 122, 3, 2, 77 | 2, 2, 128, 125, 3, 2, 2, 2, 129, 42, 3, 2, 2, 2, 130, 132, 9, 2, 2, 2, 78 | 131, 130, 3, 2, 2, 2, 132, 133, 3, 2, 2, 2, 133, 131, 3, 2, 2, 2, 133, 79 | 134, 3, 2, 2, 2, 134, 44, 3, 2, 2, 2, 135, 139, 7, 41, 2, 2, 136, 138, 80 | 11, 2, 2, 2, 137, 136, 3, 2, 2, 2, 138, 141, 3, 2, 2, 2, 139, 140, 3, 2, 81 | 2, 2, 139, 137, 3, 2, 2, 2, 140, 142, 3, 2, 2, 2, 141, 139, 3, 2, 2, 2, 82 | 142, 143, 7, 41, 2, 2, 143, 46, 3, 2, 2, 2, 144, 145, 9, 3, 2, 2, 145, 83 | 48, 3, 2, 2, 2, 146, 148, 9, 4, 2, 2, 147, 146, 3, 2, 2, 2, 147, 148, 3, 84 | 2, 2, 2, 148, 150, 3, 2, 2, 2, 149, 151, 5, 47, 24, 2, 150, 149, 3, 2, 85 | 2, 2, 151, 152, 3, 2, 2, 2, 152, 150, 3, 2, 2, 2, 152, 153, 3, 2, 2, 2, 86 | 153, 50, 3, 2, 2, 2, 154, 156, 9, 4, 2, 2, 155, 154, 3, 2, 2, 2, 155, 156, 87 | 3, 2, 2, 2, 156, 158, 3, 2, 2, 2, 157, 159, 5, 47, 24, 2, 158, 157, 3, 88 | 2, 2, 2, 159, 160, 3, 2, 2, 2, 160, 158, 3, 2, 2, 2, 160, 161, 3, 2, 2, 89 | 2, 161, 162, 3, 2, 2, 2, 162, 166, 7, 48, 2, 2, 163, 165, 5, 47, 24, 2, 90 | 164, 163, 3, 2, 2, 2, 165, 168, 3, 2, 2, 2, 166, 164, 3, 2, 2, 2, 166, 91 | 167, 3, 2, 2, 2, 167, 52, 3, 2, 2, 2, 168, 166, 3, 2, 2, 2, 169, 171, 9, 92 | 5, 2, 2, 170, 169, 3, 2, 2, 2, 171, 172, 3, 2, 2, 2, 172, 170, 3, 2, 2, 93 | 2, 172, 173, 3, 2, 2, 2, 173, 174, 3, 2, 2, 2, 174, 175, 8, 27, 2, 2, 175, 94 | 54, 3, 2, 2, 2, 13, 2, 128, 131, 133, 139, 147, 152, 155, 160, 166, 172, 95 | 3, 8, 2, 2, 96 | } 97 | 98 | var lexerDeserializer = antlr.NewATNDeserializer(nil) 99 | var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) 100 | 101 | var lexerChannelNames = []string{ 102 | "DEFAULT_TOKEN_CHANNEL", "HIDDEN", 103 | } 104 | 105 | var lexerModeNames = []string{ 106 | "DEFAULT_MODE", 107 | } 108 | 109 | var lexerLiteralNames = []string{ 110 | "", "'and'", "'or'", "'('", "')'", "'='", "'!='", "'>'", "'<'", "'>='", 111 | "'<='", "'in'", "'!in'", "'\u2229'", "'!\u2229'", "','", "'.'", "'()'", 112 | "'true'", "'false'", 113 | } 114 | 115 | var lexerSymbolicNames = []string{ 116 | "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 117 | "TRUE", "FALSE", "FUNC", "FIELDNAME", "STRING", "INT", "FLOAT", "WS", 118 | } 119 | 120 | var lexerRuleNames = []string{ 121 | "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", 122 | "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", 123 | "TRUE", "FALSE", "FUNC", "FIELDNAME", "STRING", "DIGIT", "INT", "FLOAT", 124 | "WS", 125 | } 126 | 127 | type YqlLexer struct { 128 | *antlr.BaseLexer 129 | channelNames []string 130 | modeNames []string 131 | // TODO: EOF string 132 | } 133 | 134 | var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState)) 135 | 136 | func init() { 137 | for index, ds := range lexerAtn.DecisionToState { 138 | lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) 139 | } 140 | } 141 | 142 | func NewYqlLexer(input antlr.CharStream) *YqlLexer { 143 | 144 | l := new(YqlLexer) 145 | 146 | l.BaseLexer = antlr.NewBaseLexer(input) 147 | l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) 148 | 149 | l.channelNames = lexerChannelNames 150 | l.modeNames = lexerModeNames 151 | l.RuleNames = lexerRuleNames 152 | l.LiteralNames = lexerLiteralNames 153 | l.SymbolicNames = lexerSymbolicNames 154 | l.GrammarFileName = "Yql.g4" 155 | // TODO: l.EOF = antlr.TokenEOF 156 | 157 | return l 158 | } 159 | 160 | // YqlLexer tokens. 161 | const ( 162 | YqlLexerT__0 = 1 163 | YqlLexerT__1 = 2 164 | YqlLexerT__2 = 3 165 | YqlLexerT__3 = 4 166 | YqlLexerT__4 = 5 167 | YqlLexerT__5 = 6 168 | YqlLexerT__6 = 7 169 | YqlLexerT__7 = 8 170 | YqlLexerT__8 = 9 171 | YqlLexerT__9 = 10 172 | YqlLexerT__10 = 11 173 | YqlLexerT__11 = 12 174 | YqlLexerT__12 = 13 175 | YqlLexerT__13 = 14 176 | YqlLexerT__14 = 15 177 | YqlLexerT__15 = 16 178 | YqlLexerT__16 = 17 179 | YqlLexerTRUE = 18 180 | YqlLexerFALSE = 19 181 | YqlLexerFUNC = 20 182 | YqlLexerFIELDNAME = 21 183 | YqlLexerSTRING = 22 184 | YqlLexerINT = 23 185 | YqlLexerFLOAT = 24 186 | YqlLexerWS = 25 187 | ) 188 | -------------------------------------------------------------------------------- /internal/grammar/yql_listener.go: -------------------------------------------------------------------------------- 1 | // Generated from Yql.g4 by ANTLR 4.7. 2 | 3 | package grammar // Yql 4 | import "github.com/antlr/antlr4/runtime/Go/antlr" 5 | 6 | // YqlListener is a complete listener for a parse tree produced by YqlParser. 7 | type YqlListener interface { 8 | antlr.ParseTreeListener 9 | 10 | // EnterQuery is called when entering the query production. 11 | EnterQuery(c *QueryContext) 12 | 13 | // EnterEmbbedExpr is called when entering the embbedExpr production. 14 | EnterEmbbedExpr(c *EmbbedExprContext) 15 | 16 | // EnterOrExpr is called when entering the orExpr production. 17 | EnterOrExpr(c *OrExprContext) 18 | 19 | // EnterBoolExpr is called when entering the boolExpr production. 20 | EnterBoolExpr(c *BoolExprContext) 21 | 22 | // EnterAndExpr is called when entering the andExpr production. 23 | EnterAndExpr(c *AndExprContext) 24 | 25 | // EnterBooleanExpr is called when entering the booleanExpr production. 26 | EnterBooleanExpr(c *BooleanExprContext) 27 | 28 | // EnterLeftexpr is called when entering the leftexpr production. 29 | EnterLeftexpr(c *LeftexprContext) 30 | 31 | // EnterValue is called when entering the value production. 32 | EnterValue(c *ValueContext) 33 | 34 | // ExitQuery is called when exiting the query production. 35 | ExitQuery(c *QueryContext) 36 | 37 | // ExitEmbbedExpr is called when exiting the embbedExpr production. 38 | ExitEmbbedExpr(c *EmbbedExprContext) 39 | 40 | // ExitOrExpr is called when exiting the orExpr production. 41 | ExitOrExpr(c *OrExprContext) 42 | 43 | // ExitBoolExpr is called when exiting the boolExpr production. 44 | ExitBoolExpr(c *BoolExprContext) 45 | 46 | // ExitAndExpr is called when exiting the andExpr production. 47 | ExitAndExpr(c *AndExprContext) 48 | 49 | // ExitBooleanExpr is called when exiting the booleanExpr production. 50 | ExitBooleanExpr(c *BooleanExprContext) 51 | 52 | // ExitLeftexpr is called when exiting the leftexpr production. 53 | ExitLeftexpr(c *LeftexprContext) 54 | 55 | // ExitValue is called when exiting the value production. 56 | ExitValue(c *ValueContext) 57 | } 58 | -------------------------------------------------------------------------------- /internal/grammar/yql_parser.go: -------------------------------------------------------------------------------- 1 | // Generated from Yql.g4 by ANTLR 4.7. 2 | 3 | package grammar // Yql 4 | import ( 5 | "fmt" 6 | "reflect" 7 | "strconv" 8 | 9 | "github.com/antlr/antlr4/runtime/Go/antlr" 10 | ) 11 | 12 | // Suppress unused import errors 13 | var _ = fmt.Printf 14 | var _ = reflect.Copy 15 | var _ = strconv.Itoa 16 | 17 | var parserATN = []uint16{ 18 | 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 27, 65, 4, 19 | 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 3, 2, 3, 2, 3, 20 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 21, 10, 3, 3, 3, 3, 3, 3, 3, 3, 21 | 3, 3, 3, 3, 3, 7, 3, 29, 10, 3, 12, 3, 14, 3, 32, 11, 3, 3, 4, 3, 4, 3, 22 | 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 44, 10, 4, 12, 4, 14, 23 | 4, 47, 11, 4, 3, 4, 3, 4, 5, 4, 51, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 6, 5, 24 | 57, 10, 5, 13, 5, 14, 5, 58, 5, 5, 61, 10, 5, 3, 6, 3, 6, 3, 6, 2, 3, 4, 25 | 7, 2, 4, 6, 8, 10, 2, 5, 3, 2, 7, 12, 3, 2, 13, 16, 4, 2, 20, 21, 24, 26, 26 | 2, 66, 2, 12, 3, 2, 2, 2, 4, 20, 3, 2, 2, 2, 6, 50, 3, 2, 2, 2, 8, 52, 27 | 3, 2, 2, 2, 10, 62, 3, 2, 2, 2, 12, 13, 5, 4, 3, 2, 13, 3, 3, 2, 2, 2, 28 | 14, 15, 8, 3, 1, 2, 15, 21, 5, 6, 4, 2, 16, 17, 7, 5, 2, 2, 17, 18, 5, 29 | 4, 3, 2, 18, 19, 7, 6, 2, 2, 19, 21, 3, 2, 2, 2, 20, 14, 3, 2, 2, 2, 20, 30 | 16, 3, 2, 2, 2, 21, 30, 3, 2, 2, 2, 22, 23, 12, 5, 2, 2, 23, 24, 7, 3, 31 | 2, 2, 24, 29, 5, 4, 3, 6, 25, 26, 12, 4, 2, 2, 26, 27, 7, 4, 2, 2, 27, 32 | 29, 5, 4, 3, 5, 28, 22, 3, 2, 2, 2, 28, 25, 3, 2, 2, 2, 29, 32, 3, 2, 2, 33 | 2, 30, 28, 3, 2, 2, 2, 30, 31, 3, 2, 2, 2, 31, 5, 3, 2, 2, 2, 32, 30, 3, 34 | 2, 2, 2, 33, 34, 5, 8, 5, 2, 34, 35, 9, 2, 2, 2, 35, 36, 5, 10, 6, 2, 36, 35 | 51, 3, 2, 2, 2, 37, 38, 5, 8, 5, 2, 38, 39, 9, 3, 2, 2, 39, 40, 7, 5, 2, 36 | 2, 40, 45, 5, 10, 6, 2, 41, 42, 7, 17, 2, 2, 42, 44, 5, 10, 6, 2, 43, 41, 37 | 3, 2, 2, 2, 44, 47, 3, 2, 2, 2, 45, 43, 3, 2, 2, 2, 45, 46, 3, 2, 2, 2, 38 | 46, 48, 3, 2, 2, 2, 47, 45, 3, 2, 2, 2, 48, 49, 7, 6, 2, 2, 49, 51, 3, 39 | 2, 2, 2, 50, 33, 3, 2, 2, 2, 50, 37, 3, 2, 2, 2, 51, 7, 3, 2, 2, 2, 52, 40 | 60, 7, 23, 2, 2, 53, 54, 7, 18, 2, 2, 54, 55, 7, 22, 2, 2, 55, 57, 7, 19, 41 | 2, 2, 56, 53, 3, 2, 2, 2, 57, 58, 3, 2, 2, 2, 58, 56, 3, 2, 2, 2, 58, 59, 42 | 3, 2, 2, 2, 59, 61, 3, 2, 2, 2, 60, 56, 3, 2, 2, 2, 60, 61, 3, 2, 2, 2, 43 | 61, 9, 3, 2, 2, 2, 62, 63, 9, 4, 2, 2, 63, 11, 3, 2, 2, 2, 9, 20, 28, 30, 44 | 45, 50, 58, 60, 45 | } 46 | var deserializer = antlr.NewATNDeserializer(nil) 47 | var deserializedATN = deserializer.DeserializeFromUInt16(parserATN) 48 | 49 | var literalNames = []string{ 50 | "", "'and'", "'or'", "'('", "')'", "'='", "'!='", "'>'", "'<'", "'>='", 51 | "'<='", "'in'", "'!in'", "'\u2229'", "'!\u2229'", "','", "'.'", "'()'", 52 | "'true'", "'false'", 53 | } 54 | var symbolicNames = []string{ 55 | "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 56 | "TRUE", "FALSE", "FUNC", "FIELDNAME", "STRING", "INT", "FLOAT", "WS", 57 | } 58 | 59 | var ruleNames = []string{ 60 | "query", "expr", "booleanExpr", "leftexpr", "value", 61 | } 62 | var decisionToDFA = make([]*antlr.DFA, len(deserializedATN.DecisionToState)) 63 | 64 | func init() { 65 | for index, ds := range deserializedATN.DecisionToState { 66 | decisionToDFA[index] = antlr.NewDFA(ds, index) 67 | } 68 | } 69 | 70 | type YqlParser struct { 71 | *antlr.BaseParser 72 | } 73 | 74 | func NewYqlParser(input antlr.TokenStream) *YqlParser { 75 | this := new(YqlParser) 76 | 77 | this.BaseParser = antlr.NewBaseParser(input) 78 | 79 | this.Interpreter = antlr.NewParserATNSimulator(this, deserializedATN, decisionToDFA, antlr.NewPredictionContextCache()) 80 | this.RuleNames = ruleNames 81 | this.LiteralNames = literalNames 82 | this.SymbolicNames = symbolicNames 83 | this.GrammarFileName = "Yql.g4" 84 | 85 | return this 86 | } 87 | 88 | // YqlParser tokens. 89 | const ( 90 | YqlParserEOF = antlr.TokenEOF 91 | YqlParserT__0 = 1 92 | YqlParserT__1 = 2 93 | YqlParserT__2 = 3 94 | YqlParserT__3 = 4 95 | YqlParserT__4 = 5 96 | YqlParserT__5 = 6 97 | YqlParserT__6 = 7 98 | YqlParserT__7 = 8 99 | YqlParserT__8 = 9 100 | YqlParserT__9 = 10 101 | YqlParserT__10 = 11 102 | YqlParserT__11 = 12 103 | YqlParserT__12 = 13 104 | YqlParserT__13 = 14 105 | YqlParserT__14 = 15 106 | YqlParserT__15 = 16 107 | YqlParserT__16 = 17 108 | YqlParserTRUE = 18 109 | YqlParserFALSE = 19 110 | YqlParserFUNC = 20 111 | YqlParserFIELDNAME = 21 112 | YqlParserSTRING = 22 113 | YqlParserINT = 23 114 | YqlParserFLOAT = 24 115 | YqlParserWS = 25 116 | ) 117 | 118 | // YqlParser rules. 119 | const ( 120 | YqlParserRULE_query = 0 121 | YqlParserRULE_expr = 1 122 | YqlParserRULE_booleanExpr = 2 123 | YqlParserRULE_leftexpr = 3 124 | YqlParserRULE_value = 4 125 | ) 126 | 127 | // IQueryContext is an interface to support dynamic dispatch. 128 | type IQueryContext interface { 129 | antlr.ParserRuleContext 130 | 131 | // GetParser returns the parser. 132 | GetParser() antlr.Parser 133 | 134 | // IsQueryContext differentiates from other interfaces. 135 | IsQueryContext() 136 | } 137 | 138 | type QueryContext struct { 139 | *antlr.BaseParserRuleContext 140 | parser antlr.Parser 141 | } 142 | 143 | func NewEmptyQueryContext() *QueryContext { 144 | var p = new(QueryContext) 145 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) 146 | p.RuleIndex = YqlParserRULE_query 147 | return p 148 | } 149 | 150 | func (*QueryContext) IsQueryContext() {} 151 | 152 | func NewQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *QueryContext { 153 | var p = new(QueryContext) 154 | 155 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) 156 | 157 | p.parser = parser 158 | p.RuleIndex = YqlParserRULE_query 159 | 160 | return p 161 | } 162 | 163 | func (s *QueryContext) GetParser() antlr.Parser { return s.parser } 164 | 165 | func (s *QueryContext) Expr() IExprContext { 166 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) 167 | 168 | if t == nil { 169 | return nil 170 | } 171 | 172 | return t.(IExprContext) 173 | } 174 | 175 | func (s *QueryContext) GetRuleContext() antlr.RuleContext { 176 | return s 177 | } 178 | 179 | func (s *QueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { 180 | return antlr.TreesStringTree(s, ruleNames, recog) 181 | } 182 | 183 | func (s *QueryContext) EnterRule(listener antlr.ParseTreeListener) { 184 | if listenerT, ok := listener.(YqlListener); ok { 185 | listenerT.EnterQuery(s) 186 | } 187 | } 188 | 189 | func (s *QueryContext) ExitRule(listener antlr.ParseTreeListener) { 190 | if listenerT, ok := listener.(YqlListener); ok { 191 | listenerT.ExitQuery(s) 192 | } 193 | } 194 | 195 | func (p *YqlParser) Query() (localctx IQueryContext) { 196 | localctx = NewQueryContext(p, p.GetParserRuleContext(), p.GetState()) 197 | p.EnterRule(localctx, 0, YqlParserRULE_query) 198 | 199 | defer func() { 200 | p.ExitRule() 201 | }() 202 | 203 | defer func() { 204 | if err := recover(); err != nil { 205 | if v, ok := err.(antlr.RecognitionException); ok { 206 | localctx.SetException(v) 207 | p.GetErrorHandler().ReportError(p, v) 208 | p.GetErrorHandler().Recover(p, v) 209 | } else { 210 | panic(err) 211 | } 212 | } 213 | }() 214 | 215 | p.EnterOuterAlt(localctx, 1) 216 | { 217 | p.SetState(10) 218 | p.expr(0) 219 | } 220 | 221 | return localctx 222 | } 223 | 224 | // IExprContext is an interface to support dynamic dispatch. 225 | type IExprContext interface { 226 | antlr.ParserRuleContext 227 | 228 | // GetParser returns the parser. 229 | GetParser() antlr.Parser 230 | 231 | // IsExprContext differentiates from other interfaces. 232 | IsExprContext() 233 | } 234 | 235 | type ExprContext struct { 236 | *antlr.BaseParserRuleContext 237 | parser antlr.Parser 238 | } 239 | 240 | func NewEmptyExprContext() *ExprContext { 241 | var p = new(ExprContext) 242 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) 243 | p.RuleIndex = YqlParserRULE_expr 244 | return p 245 | } 246 | 247 | func (*ExprContext) IsExprContext() {} 248 | 249 | func NewExprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExprContext { 250 | var p = new(ExprContext) 251 | 252 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) 253 | 254 | p.parser = parser 255 | p.RuleIndex = YqlParserRULE_expr 256 | 257 | return p 258 | } 259 | 260 | func (s *ExprContext) GetParser() antlr.Parser { return s.parser } 261 | 262 | func (s *ExprContext) CopyFrom(ctx *ExprContext) { 263 | s.BaseParserRuleContext.CopyFrom(ctx.BaseParserRuleContext) 264 | } 265 | 266 | func (s *ExprContext) GetRuleContext() antlr.RuleContext { 267 | return s 268 | } 269 | 270 | func (s *ExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { 271 | return antlr.TreesStringTree(s, ruleNames, recog) 272 | } 273 | 274 | type EmbbedExprContext struct { 275 | *ExprContext 276 | } 277 | 278 | func NewEmbbedExprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *EmbbedExprContext { 279 | var p = new(EmbbedExprContext) 280 | 281 | p.ExprContext = NewEmptyExprContext() 282 | p.parser = parser 283 | p.CopyFrom(ctx.(*ExprContext)) 284 | 285 | return p 286 | } 287 | 288 | func (s *EmbbedExprContext) GetRuleContext() antlr.RuleContext { 289 | return s 290 | } 291 | 292 | func (s *EmbbedExprContext) Expr() IExprContext { 293 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), 0) 294 | 295 | if t == nil { 296 | return nil 297 | } 298 | 299 | return t.(IExprContext) 300 | } 301 | 302 | func (s *EmbbedExprContext) EnterRule(listener antlr.ParseTreeListener) { 303 | if listenerT, ok := listener.(YqlListener); ok { 304 | listenerT.EnterEmbbedExpr(s) 305 | } 306 | } 307 | 308 | func (s *EmbbedExprContext) ExitRule(listener antlr.ParseTreeListener) { 309 | if listenerT, ok := listener.(YqlListener); ok { 310 | listenerT.ExitEmbbedExpr(s) 311 | } 312 | } 313 | 314 | type OrExprContext struct { 315 | *ExprContext 316 | } 317 | 318 | func NewOrExprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *OrExprContext { 319 | var p = new(OrExprContext) 320 | 321 | p.ExprContext = NewEmptyExprContext() 322 | p.parser = parser 323 | p.CopyFrom(ctx.(*ExprContext)) 324 | 325 | return p 326 | } 327 | 328 | func (s *OrExprContext) GetRuleContext() antlr.RuleContext { 329 | return s 330 | } 331 | 332 | func (s *OrExprContext) AllExpr() []IExprContext { 333 | var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExprContext)(nil)).Elem()) 334 | var tst = make([]IExprContext, len(ts)) 335 | 336 | for i, t := range ts { 337 | if t != nil { 338 | tst[i] = t.(IExprContext) 339 | } 340 | } 341 | 342 | return tst 343 | } 344 | 345 | func (s *OrExprContext) Expr(i int) IExprContext { 346 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), i) 347 | 348 | if t == nil { 349 | return nil 350 | } 351 | 352 | return t.(IExprContext) 353 | } 354 | 355 | func (s *OrExprContext) EnterRule(listener antlr.ParseTreeListener) { 356 | if listenerT, ok := listener.(YqlListener); ok { 357 | listenerT.EnterOrExpr(s) 358 | } 359 | } 360 | 361 | func (s *OrExprContext) ExitRule(listener antlr.ParseTreeListener) { 362 | if listenerT, ok := listener.(YqlListener); ok { 363 | listenerT.ExitOrExpr(s) 364 | } 365 | } 366 | 367 | type BoolExprContext struct { 368 | *ExprContext 369 | } 370 | 371 | func NewBoolExprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *BoolExprContext { 372 | var p = new(BoolExprContext) 373 | 374 | p.ExprContext = NewEmptyExprContext() 375 | p.parser = parser 376 | p.CopyFrom(ctx.(*ExprContext)) 377 | 378 | return p 379 | } 380 | 381 | func (s *BoolExprContext) GetRuleContext() antlr.RuleContext { 382 | return s 383 | } 384 | 385 | func (s *BoolExprContext) BooleanExpr() IBooleanExprContext { 386 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IBooleanExprContext)(nil)).Elem(), 0) 387 | 388 | if t == nil { 389 | return nil 390 | } 391 | 392 | return t.(IBooleanExprContext) 393 | } 394 | 395 | func (s *BoolExprContext) EnterRule(listener antlr.ParseTreeListener) { 396 | if listenerT, ok := listener.(YqlListener); ok { 397 | listenerT.EnterBoolExpr(s) 398 | } 399 | } 400 | 401 | func (s *BoolExprContext) ExitRule(listener antlr.ParseTreeListener) { 402 | if listenerT, ok := listener.(YqlListener); ok { 403 | listenerT.ExitBoolExpr(s) 404 | } 405 | } 406 | 407 | type AndExprContext struct { 408 | *ExprContext 409 | } 410 | 411 | func NewAndExprContext(parser antlr.Parser, ctx antlr.ParserRuleContext) *AndExprContext { 412 | var p = new(AndExprContext) 413 | 414 | p.ExprContext = NewEmptyExprContext() 415 | p.parser = parser 416 | p.CopyFrom(ctx.(*ExprContext)) 417 | 418 | return p 419 | } 420 | 421 | func (s *AndExprContext) GetRuleContext() antlr.RuleContext { 422 | return s 423 | } 424 | 425 | func (s *AndExprContext) AllExpr() []IExprContext { 426 | var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IExprContext)(nil)).Elem()) 427 | var tst = make([]IExprContext, len(ts)) 428 | 429 | for i, t := range ts { 430 | if t != nil { 431 | tst[i] = t.(IExprContext) 432 | } 433 | } 434 | 435 | return tst 436 | } 437 | 438 | func (s *AndExprContext) Expr(i int) IExprContext { 439 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IExprContext)(nil)).Elem(), i) 440 | 441 | if t == nil { 442 | return nil 443 | } 444 | 445 | return t.(IExprContext) 446 | } 447 | 448 | func (s *AndExprContext) EnterRule(listener antlr.ParseTreeListener) { 449 | if listenerT, ok := listener.(YqlListener); ok { 450 | listenerT.EnterAndExpr(s) 451 | } 452 | } 453 | 454 | func (s *AndExprContext) ExitRule(listener antlr.ParseTreeListener) { 455 | if listenerT, ok := listener.(YqlListener); ok { 456 | listenerT.ExitAndExpr(s) 457 | } 458 | } 459 | 460 | func (p *YqlParser) Expr() (localctx IExprContext) { 461 | return p.expr(0) 462 | } 463 | 464 | func (p *YqlParser) expr(_p int) (localctx IExprContext) { 465 | var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext() 466 | _parentState := p.GetState() 467 | localctx = NewExprContext(p, p.GetParserRuleContext(), _parentState) 468 | var _prevctx IExprContext = localctx 469 | var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning. 470 | _startState := 2 471 | p.EnterRecursionRule(localctx, 2, YqlParserRULE_expr, _p) 472 | 473 | defer func() { 474 | p.UnrollRecursionContexts(_parentctx) 475 | }() 476 | 477 | defer func() { 478 | if err := recover(); err != nil { 479 | if v, ok := err.(antlr.RecognitionException); ok { 480 | localctx.SetException(v) 481 | p.GetErrorHandler().ReportError(p, v) 482 | p.GetErrorHandler().Recover(p, v) 483 | } else { 484 | panic(err) 485 | } 486 | } 487 | }() 488 | 489 | var _alt int 490 | 491 | p.EnterOuterAlt(localctx, 1) 492 | p.SetState(18) 493 | p.GetErrorHandler().Sync(p) 494 | 495 | switch p.GetTokenStream().LA(1) { 496 | case YqlParserFIELDNAME: 497 | localctx = NewBoolExprContext(p, localctx) 498 | p.SetParserRuleContext(localctx) 499 | _prevctx = localctx 500 | 501 | { 502 | p.SetState(13) 503 | p.BooleanExpr() 504 | } 505 | 506 | case YqlParserT__2: 507 | localctx = NewEmbbedExprContext(p, localctx) 508 | p.SetParserRuleContext(localctx) 509 | _prevctx = localctx 510 | { 511 | p.SetState(14) 512 | p.Match(YqlParserT__2) 513 | } 514 | { 515 | p.SetState(15) 516 | p.expr(0) 517 | } 518 | { 519 | p.SetState(16) 520 | p.Match(YqlParserT__3) 521 | } 522 | 523 | default: 524 | panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) 525 | } 526 | p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) 527 | p.SetState(28) 528 | p.GetErrorHandler().Sync(p) 529 | _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) 530 | 531 | for _alt != 2 && _alt != antlr.ATNInvalidAltNumber { 532 | if _alt == 1 { 533 | if p.GetParseListeners() != nil { 534 | p.TriggerExitRuleEvent() 535 | } 536 | _prevctx = localctx 537 | p.SetState(26) 538 | p.GetErrorHandler().Sync(p) 539 | switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) { 540 | case 1: 541 | localctx = NewAndExprContext(p, NewExprContext(p, _parentctx, _parentState)) 542 | p.PushNewRecursionContext(localctx, _startState, YqlParserRULE_expr) 543 | p.SetState(20) 544 | 545 | if !(p.Precpred(p.GetParserRuleContext(), 3)) { 546 | panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", "")) 547 | } 548 | { 549 | p.SetState(21) 550 | p.Match(YqlParserT__0) 551 | } 552 | { 553 | p.SetState(22) 554 | p.expr(4) 555 | } 556 | 557 | case 2: 558 | localctx = NewOrExprContext(p, NewExprContext(p, _parentctx, _parentState)) 559 | p.PushNewRecursionContext(localctx, _startState, YqlParserRULE_expr) 560 | p.SetState(23) 561 | 562 | if !(p.Precpred(p.GetParserRuleContext(), 2)) { 563 | panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", "")) 564 | } 565 | { 566 | p.SetState(24) 567 | p.Match(YqlParserT__1) 568 | } 569 | { 570 | p.SetState(25) 571 | p.expr(3) 572 | } 573 | 574 | } 575 | 576 | } 577 | p.SetState(30) 578 | p.GetErrorHandler().Sync(p) 579 | _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 2, p.GetParserRuleContext()) 580 | } 581 | 582 | return localctx 583 | } 584 | 585 | // IBooleanExprContext is an interface to support dynamic dispatch. 586 | type IBooleanExprContext interface { 587 | antlr.ParserRuleContext 588 | 589 | // GetParser returns the parser. 590 | GetParser() antlr.Parser 591 | 592 | // GetOp returns the op token. 593 | GetOp() antlr.Token 594 | 595 | // SetOp sets the op token. 596 | SetOp(antlr.Token) 597 | 598 | // IsBooleanExprContext differentiates from other interfaces. 599 | IsBooleanExprContext() 600 | } 601 | 602 | type BooleanExprContext struct { 603 | *antlr.BaseParserRuleContext 604 | parser antlr.Parser 605 | op antlr.Token 606 | } 607 | 608 | func NewEmptyBooleanExprContext() *BooleanExprContext { 609 | var p = new(BooleanExprContext) 610 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) 611 | p.RuleIndex = YqlParserRULE_booleanExpr 612 | return p 613 | } 614 | 615 | func (*BooleanExprContext) IsBooleanExprContext() {} 616 | 617 | func NewBooleanExprContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BooleanExprContext { 618 | var p = new(BooleanExprContext) 619 | 620 | p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) 621 | 622 | p.parser = parser 623 | p.RuleIndex = YqlParserRULE_booleanExpr 624 | 625 | return p 626 | } 627 | 628 | func (s *BooleanExprContext) GetParser() antlr.Parser { return s.parser } 629 | 630 | func (s *BooleanExprContext) GetOp() antlr.Token { return s.op } 631 | 632 | func (s *BooleanExprContext) SetOp(v antlr.Token) { s.op = v } 633 | 634 | func (s *BooleanExprContext) Leftexpr() ILeftexprContext { 635 | var t = s.GetTypedRuleContext(reflect.TypeOf((*ILeftexprContext)(nil)).Elem(), 0) 636 | 637 | if t == nil { 638 | return nil 639 | } 640 | 641 | return t.(ILeftexprContext) 642 | } 643 | 644 | func (s *BooleanExprContext) AllValue() []IValueContext { 645 | var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IValueContext)(nil)).Elem()) 646 | var tst = make([]IValueContext, len(ts)) 647 | 648 | for i, t := range ts { 649 | if t != nil { 650 | tst[i] = t.(IValueContext) 651 | } 652 | } 653 | 654 | return tst 655 | } 656 | 657 | func (s *BooleanExprContext) Value(i int) IValueContext { 658 | var t = s.GetTypedRuleContext(reflect.TypeOf((*IValueContext)(nil)).Elem(), i) 659 | 660 | if t == nil { 661 | return nil 662 | } 663 | 664 | return t.(IValueContext) 665 | } 666 | 667 | func (s *BooleanExprContext) GetRuleContext() antlr.RuleContext { 668 | return s 669 | } 670 | 671 | func (s *BooleanExprContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { 672 | return antlr.TreesStringTree(s, ruleNames, recog) 673 | } 674 | 675 | func (s *BooleanExprContext) EnterRule(listener antlr.ParseTreeListener) { 676 | if listenerT, ok := listener.(YqlListener); ok { 677 | listenerT.EnterBooleanExpr(s) 678 | } 679 | } 680 | 681 | func (s *BooleanExprContext) ExitRule(listener antlr.ParseTreeListener) { 682 | if listenerT, ok := listener.(YqlListener); ok { 683 | listenerT.ExitBooleanExpr(s) 684 | } 685 | } 686 | 687 | func (p *YqlParser) BooleanExpr() (localctx IBooleanExprContext) { 688 | localctx = NewBooleanExprContext(p, p.GetParserRuleContext(), p.GetState()) 689 | p.EnterRule(localctx, 4, YqlParserRULE_booleanExpr) 690 | var _la int 691 | 692 | defer func() { 693 | p.ExitRule() 694 | }() 695 | 696 | defer func() { 697 | if err := recover(); err != nil { 698 | if v, ok := err.(antlr.RecognitionException); ok { 699 | localctx.SetException(v) 700 | p.GetErrorHandler().ReportError(p, v) 701 | p.GetErrorHandler().Recover(p, v) 702 | } else { 703 | panic(err) 704 | } 705 | } 706 | }() 707 | 708 | p.SetState(48) 709 | p.GetErrorHandler().Sync(p) 710 | switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) { 711 | case 1: 712 | p.EnterOuterAlt(localctx, 1) 713 | { 714 | p.SetState(31) 715 | p.Leftexpr() 716 | } 717 | p.SetState(32) 718 | 719 | var _lt = p.GetTokenStream().LT(1) 720 | 721 | localctx.(*BooleanExprContext).op = _lt 722 | 723 | _la = p.GetTokenStream().LA(1) 724 | 725 | if !(((_la)&-(0x1f+1)) == 0 && ((1<' expression 5 | ; 6 | 7 | signature: '(' ( IDENTIFIER ( ',' IDENTIFIER )*)? ')'; 8 | 9 | 10 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 11 | // Operands 12 | 13 | //Operand = Literal | OperandName | MethodExpr | "(" Expression ")" . 14 | //Literal = BasicLit | CompositeLit | FunctionLit . 15 | //BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit . 16 | //OperandName = identifier | QualifiedIdent. 17 | 18 | operand 19 | : basicLit 20 | | operandName 21 | ; 22 | 23 | basicLit 24 | : INT_LIT 25 | | BOOL_LIT 26 | | FLOAT_LIT 27 | | IMAGINARY_LIT 28 | | RUNE_LIT 29 | | STRING_LIT 30 | ; 31 | 32 | operandName: IDENTIFIER ('.' IDENTIFIER)*; 33 | 34 | 35 | //PrimaryExpr = 36 | // Operand | 37 | // Conversion | 38 | // PrimaryExpr Selector | 39 | // PrimaryExpr Index | 40 | // PrimaryExpr Slice | 41 | // PrimaryExpr TypeAssertion | 42 | // PrimaryExpr Arguments . 43 | // 44 | //Selector = "." identifier . 45 | //Index = "[" Expression "]" . 46 | //Slice = "[" ( [ Expression ] ":" [ Expression ] ) | 47 | // ( [ Expression ] ":" Expression ":" Expression ) 48 | // "]" . 49 | //TypeAssertion = "." "(" Type ")" . 50 | //Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" . 51 | 52 | primaryExpr 53 | : operand 54 | ; 55 | 56 | selector 57 | : '.' IDENTIFIER 58 | ; 59 | 60 | 61 | //Expression = UnaryExpr | Expression binary_op Expression . 62 | //UnaryExpr = PrimaryExpr | unary_op UnaryExpr . 63 | 64 | expression 65 | : '(' expression ')' #quoteExpr 66 | | expression op=('*' | '/' | '%' | '<<' | '>>' | '&' | '&^') expression #firstExpr 67 | | expression op=('+' | '-' | '|' | '^') expression #secondExpr 68 | | expression op=('==' | '!=' | '<' | '<=' | '>' | '>=') expression #thirdExpr 69 | | expression op='&&' expression #andExpr 70 | | expression op='||' expression #orExpr 71 | | unaryExpr #valueExpr 72 | ; 73 | 74 | unaryExpr 75 | : primaryExpr 76 | | ('+'|'-'|'!'|'^'|'*'|'&'|'<-') unaryExpr 77 | ; 78 | 79 | 80 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 81 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 82 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 83 | // LEXER 84 | 85 | 86 | // Identifiers 87 | //identifier = letter { letter | unicode_digit } . 88 | IDENTIFIER 89 | : LETTER ( LETTER | UNICODE_DIGIT )* 90 | ; 91 | 92 | 93 | // Operators 94 | 95 | //binary_op = "||" | "&&" | rel_op | add_op | mul_op . 96 | BINARY_OP 97 | : '||' | '&&' | REL_OP | ADD_OP | MUL_OP 98 | ; 99 | 100 | //rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" . 101 | fragment REL_OP 102 | : '==' 103 | | '!=' 104 | | '<' 105 | | '<=' 106 | | '>' 107 | | '>=' 108 | ; 109 | 110 | //add_op = "+" | "-" | "|" | "^" . 111 | fragment ADD_OP 112 | : '+' 113 | | '-' 114 | | '|' 115 | | '^' 116 | ; 117 | 118 | //mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" . 119 | fragment MUL_OP 120 | : '*' 121 | | '/' 122 | | '%' 123 | | '<<' 124 | | '>>' 125 | | '&' 126 | | '&^' 127 | ; 128 | 129 | //unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" . 130 | fragment UNARY_OP 131 | : '+' 132 | | '-' 133 | | '!' 134 | | '^' 135 | | '*' 136 | | '&' 137 | | '<-' 138 | ; 139 | 140 | 141 | // Integer literals 142 | 143 | //int_lit = decimal_lit | octal_lit | hex_lit . 144 | INT_LIT 145 | : DECIMAL_LIT 146 | | OCTAL_LIT 147 | | HEX_LIT 148 | ; 149 | 150 | BOOL_LIT: ('true'|'false'); 151 | 152 | //decimal_lit = ( "1" … "9" ) { decimal_digit } . 153 | fragment DECIMAL_LIT 154 | : [1-9] DECIMAL_DIGIT* 155 | ; 156 | 157 | //octal_lit = "0" { octal_digit } . 158 | fragment OCTAL_LIT 159 | : '0' OCTAL_DIGIT* 160 | ; 161 | 162 | //hex_lit = "0" ( "x" | "X" ) hex_digit { hex_digit } . 163 | fragment HEX_LIT 164 | : '0' ( 'x' | 'X' ) HEX_DIGIT+ 165 | ; 166 | 167 | 168 | // Floating-point literals 169 | 170 | //float_lit = decimals "." [ decimals ] [ exponent ] | 171 | // decimals exponent | 172 | // "." decimals [ exponent ] . 173 | FLOAT_LIT 174 | : DECIMALS '.' DECIMALS? EXPONENT? 175 | | DECIMALS EXPONENT 176 | | '.' DECIMALS EXPONENT? 177 | ; 178 | 179 | //decimals = decimal_digit { decimal_digit } . 180 | fragment DECIMALS 181 | : DECIMAL_DIGIT+ 182 | ; 183 | 184 | //exponent = ( "e" | "E" ) [ "+" | "-" ] decimals . 185 | fragment EXPONENT 186 | : ( 'e' | 'E' ) ( '+' | '-' )? DECIMALS 187 | ; 188 | 189 | // Imaginary literals 190 | //imaginary_lit = (decimals | float_lit) "i" . 191 | IMAGINARY_LIT 192 | : (DECIMALS | FLOAT_LIT) 'i' 193 | ; 194 | 195 | 196 | // Rune literals 197 | 198 | //rune_lit = "'" ( unicode_value | byte_value ) "'" . 199 | RUNE_LIT 200 | : '\'' ( UNICODE_VALUE | BYTE_VALUE ) '\'' 201 | ; 202 | 203 | //unicode_value = unicode_char | little_u_value | big_u_value | escaped_char . 204 | fragment UNICODE_VALUE 205 | : UNICODE_CHAR 206 | | LITTLE_U_VALUE 207 | | BIG_U_VALUE 208 | | ESCAPED_CHAR 209 | ; 210 | 211 | //byte_value = octal_byte_value | hex_byte_value . 212 | fragment BYTE_VALUE 213 | : OCTAL_BYTE_VALUE | HEX_BYTE_VALUE 214 | ; 215 | 216 | //octal_byte_value = `\` octal_digit octal_digit octal_digit . 217 | fragment OCTAL_BYTE_VALUE 218 | : '\\' OCTAL_DIGIT OCTAL_DIGIT OCTAL_DIGIT 219 | ; 220 | 221 | //hex_byte_value = `\` "x" hex_digit hex_digit . 222 | fragment HEX_BYTE_VALUE 223 | : '\\' 'x' HEX_DIGIT HEX_DIGIT 224 | ; 225 | 226 | //little_u_value = `\` "u" hex_digit hex_digit hex_digit hex_digit . 227 | // hex_digit hex_digit hex_digit hex_digit . 228 | LITTLE_U_VALUE 229 | : '\\u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 230 | ; 231 | 232 | //big_u_value = `\` "U" hex_digit hex_digit hex_digit hex_digit 233 | BIG_U_VALUE 234 | : '\\U' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 235 | ; 236 | 237 | //escaped_char = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) . 238 | fragment ESCAPED_CHAR 239 | : '\\' ( 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' | '\\' | '\'' | '"' ) 240 | ; 241 | 242 | 243 | // String literals 244 | 245 | //string_lit = raw_string_lit | interpreted_string_lit . 246 | STRING_LIT 247 | : RAW_STRING_LIT 248 | | INTERPRETED_STRING_LIT 249 | ; 250 | 251 | //raw_string_lit = "`" { unicode_char | newline } "`" . 252 | fragment RAW_STRING_LIT 253 | : '`' ( UNICODE_CHAR | NEWLINE )* '`' 254 | ; 255 | 256 | //interpreted_string_lit = `"` { unicode_value | byte_value } `"` . 257 | fragment INTERPRETED_STRING_LIT 258 | : '"' ( UNICODE_VALUE | BYTE_VALUE )* '"' 259 | ; 260 | 261 | 262 | // 263 | // Source code representation 264 | // 265 | 266 | //letter = unicode_letter | "_" . 267 | fragment LETTER 268 | : UNICODE_LETTER 269 | | '_' 270 | ; 271 | 272 | //decimal_digit = "0" … "9" . 273 | fragment DECIMAL_DIGIT 274 | : [0-9] 275 | ; 276 | 277 | //octal_digit = "0" … "7" . 278 | fragment OCTAL_DIGIT 279 | : [0-7] 280 | ; 281 | 282 | //hex_digit = "0" … "9" | "A" … "F" | "a" … "f" . 283 | fragment HEX_DIGIT 284 | : [0-9a-fA-F] 285 | ; 286 | 287 | //newline = /* the Unicode code point U+000A */ . 288 | fragment NEWLINE 289 | : [\u000A] 290 | ; 291 | 292 | //unicode_char = /* an arbitrary Unicode code point except newline */ . 293 | fragment UNICODE_CHAR : ~[\u000A] ; 294 | 295 | //unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ . 296 | fragment UNICODE_DIGIT 297 | : [\u0030-\u0039] 298 | | [\u0660-\u0669] 299 | | [\u06F0-\u06F9] 300 | | [\u0966-\u096F] 301 | | [\u09E6-\u09EF] 302 | | [\u0A66-\u0A6F] 303 | | [\u0AE6-\u0AEF] 304 | | [\u0B66-\u0B6F] 305 | | [\u0BE7-\u0BEF] 306 | | [\u0C66-\u0C6F] 307 | | [\u0CE6-\u0CEF] 308 | | [\u0D66-\u0D6F] 309 | | [\u0E50-\u0E59] 310 | | [\u0ED0-\u0ED9] 311 | | [\u0F20-\u0F29] 312 | | [\u1040-\u1049] 313 | | [\u1369-\u1371] 314 | | [\u17E0-\u17E9] 315 | | [\u1810-\u1819] 316 | | [\uFF10-\uFF19] 317 | ; 318 | 319 | //unicode_letter = /* a Unicode code point classified as "Letter" */ . 320 | fragment UNICODE_LETTER 321 | : [\u0041-\u005A] 322 | | [\u0061-\u007A] 323 | | [\u00AA] 324 | | [\u00B5] 325 | | [\u00BA] 326 | | [\u00C0-\u00D6] 327 | | [\u00D8-\u00F6] 328 | | [\u00F8-\u021F] 329 | | [\u0222-\u0233] 330 | | [\u0250-\u02AD] 331 | | [\u02B0-\u02B8] 332 | | [\u02BB-\u02C1] 333 | | [\u02D0-\u02D1] 334 | | [\u02E0-\u02E4] 335 | | [\u02EE] 336 | | [\u037A] 337 | | [\u0386] 338 | | [\u0388-\u038A] 339 | | [\u038C] 340 | | [\u038E-\u03A1] 341 | | [\u03A3-\u03CE] 342 | | [\u03D0-\u03D7] 343 | | [\u03DA-\u03F3] 344 | | [\u0400-\u0481] 345 | | [\u048C-\u04C4] 346 | | [\u04C7-\u04C8] 347 | | [\u04CB-\u04CC] 348 | | [\u04D0-\u04F5] 349 | | [\u04F8-\u04F9] 350 | | [\u0531-\u0556] 351 | | [\u0559] 352 | | [\u0561-\u0587] 353 | | [\u05D0-\u05EA] 354 | | [\u05F0-\u05F2] 355 | | [\u0621-\u063A] 356 | | [\u0640-\u064A] 357 | | [\u0671-\u06D3] 358 | | [\u06D5] 359 | | [\u06E5-\u06E6] 360 | | [\u06FA-\u06FC] 361 | | [\u0710] 362 | | [\u0712-\u072C] 363 | | [\u0780-\u07A5] 364 | | [\u0905-\u0939] 365 | | [\u093D] 366 | | [\u0950] 367 | | [\u0958-\u0961] 368 | | [\u0985-\u098C] 369 | | [\u098F-\u0990] 370 | | [\u0993-\u09A8] 371 | | [\u09AA-\u09B0] 372 | | [\u09B2] 373 | | [\u09B6-\u09B9] 374 | | [\u09DC-\u09DD] 375 | | [\u09DF-\u09E1] 376 | | [\u09F0-\u09F1] 377 | | [\u0A05-\u0A0A] 378 | | [\u0A0F-\u0A10] 379 | | [\u0A13-\u0A28] 380 | | [\u0A2A-\u0A30] 381 | | [\u0A32-\u0A33] 382 | | [\u0A35-\u0A36] 383 | | [\u0A38-\u0A39] 384 | | [\u0A59-\u0A5C] 385 | | [\u0A5E] 386 | | [\u0A72-\u0A74] 387 | | [\u0A85-\u0A8B] 388 | | [\u0A8D] 389 | | [\u0A8F-\u0A91] 390 | | [\u0A93-\u0AA8] 391 | | [\u0AAA-\u0AB0] 392 | | [\u0AB2-\u0AB3] 393 | | [\u0AB5-\u0AB9] 394 | | [\u0ABD] 395 | | [\u0AD0] 396 | | [\u0AE0] 397 | | [\u0B05-\u0B0C] 398 | | [\u0B0F-\u0B10] 399 | | [\u0B13-\u0B28] 400 | | [\u0B2A-\u0B30] 401 | | [\u0B32-\u0B33] 402 | | [\u0B36-\u0B39] 403 | | [\u0B3D] 404 | | [\u0B5C-\u0B5D] 405 | | [\u0B5F-\u0B61] 406 | | [\u0B85-\u0B8A] 407 | | [\u0B8E-\u0B90] 408 | | [\u0B92-\u0B95] 409 | | [\u0B99-\u0B9A] 410 | | [\u0B9C] 411 | | [\u0B9E-\u0B9F] 412 | | [\u0BA3-\u0BA4] 413 | | [\u0BA8-\u0BAA] 414 | | [\u0BAE-\u0BB5] 415 | | [\u0BB7-\u0BB9] 416 | | [\u0C05-\u0C0C] 417 | | [\u0C0E-\u0C10] 418 | | [\u0C12-\u0C28] 419 | | [\u0C2A-\u0C33] 420 | | [\u0C35-\u0C39] 421 | | [\u0C60-\u0C61] 422 | | [\u0C85-\u0C8C] 423 | | [\u0C8E-\u0C90] 424 | | [\u0C92-\u0CA8] 425 | | [\u0CAA-\u0CB3] 426 | | [\u0CB5-\u0CB9] 427 | | [\u0CDE] 428 | | [\u0CE0-\u0CE1] 429 | | [\u0D05-\u0D0C] 430 | | [\u0D0E-\u0D10] 431 | | [\u0D12-\u0D28] 432 | | [\u0D2A-\u0D39] 433 | | [\u0D60-\u0D61] 434 | | [\u0D85-\u0D96] 435 | | [\u0D9A-\u0DB1] 436 | | [\u0DB3-\u0DBB] 437 | | [\u0DBD] 438 | | [\u0DC0-\u0DC6] 439 | | [\u0E01-\u0E30] 440 | | [\u0E32-\u0E33] 441 | | [\u0E40-\u0E46] 442 | | [\u0E81-\u0E82] 443 | | [\u0E84] 444 | | [\u0E87-\u0E88] 445 | | [\u0E8A] 446 | | [\u0E8D] 447 | | [\u0E94-\u0E97] 448 | | [\u0E99-\u0E9F] 449 | | [\u0EA1-\u0EA3] 450 | | [\u0EA5] 451 | | [\u0EA7] 452 | | [\u0EAA-\u0EAB] 453 | | [\u0EAD-\u0EB0] 454 | | [\u0EB2-\u0EB3] 455 | | [\u0EBD-\u0EC4] 456 | | [\u0EC6] 457 | | [\u0EDC-\u0EDD] 458 | | [\u0F00] 459 | | [\u0F40-\u0F6A] 460 | | [\u0F88-\u0F8B] 461 | | [\u1000-\u1021] 462 | | [\u1023-\u1027] 463 | | [\u1029-\u102A] 464 | | [\u1050-\u1055] 465 | | [\u10A0-\u10C5] 466 | | [\u10D0-\u10F6] 467 | | [\u1100-\u1159] 468 | | [\u115F-\u11A2] 469 | | [\u11A8-\u11F9] 470 | | [\u1200-\u1206] 471 | | [\u1208-\u1246] 472 | | [\u1248] 473 | | [\u124A-\u124D] 474 | | [\u1250-\u1256] 475 | | [\u1258] 476 | | [\u125A-\u125D] 477 | | [\u1260-\u1286] 478 | | [\u1288] 479 | | [\u128A-\u128D] 480 | | [\u1290-\u12AE] 481 | | [\u12B0] 482 | | [\u12B2-\u12B5] 483 | | [\u12B8-\u12BE] 484 | | [\u12C0] 485 | | [\u12C2-\u12C5] 486 | | [\u12C8-\u12CE] 487 | | [\u12D0-\u12D6] 488 | | [\u12D8-\u12EE] 489 | | [\u12F0-\u130E] 490 | | [\u1310] 491 | | [\u1312-\u1315] 492 | | [\u1318-\u131E] 493 | | [\u1320-\u1346] 494 | | [\u1348-\u135A] 495 | | [\u13A0-\u13B0] 496 | | [\u13B1-\u13F4] 497 | | [\u1401-\u1676] 498 | | [\u1681-\u169A] 499 | | [\u16A0-\u16EA] 500 | | [\u1780-\u17B3] 501 | | [\u1820-\u1877] 502 | | [\u1880-\u18A8] 503 | | [\u1E00-\u1E9B] 504 | | [\u1EA0-\u1EE0] 505 | | [\u1EE1-\u1EF9] 506 | | [\u1F00-\u1F15] 507 | | [\u1F18-\u1F1D] 508 | | [\u1F20-\u1F39] 509 | | [\u1F3A-\u1F45] 510 | | [\u1F48-\u1F4D] 511 | | [\u1F50-\u1F57] 512 | | [\u1F59] 513 | | [\u1F5B] 514 | | [\u1F5D] 515 | | [\u1F5F-\u1F7D] 516 | | [\u1F80-\u1FB4] 517 | | [\u1FB6-\u1FBC] 518 | | [\u1FBE] 519 | | [\u1FC2-\u1FC4] 520 | | [\u1FC6-\u1FCC] 521 | | [\u1FD0-\u1FD3] 522 | | [\u1FD6-\u1FDB] 523 | | [\u1FE0-\u1FEC] 524 | | [\u1FF2-\u1FF4] 525 | | [\u1FF6-\u1FFC] 526 | | [\u207F] 527 | | [\u2102] 528 | | [\u2107] 529 | | [\u210A-\u2113] 530 | | [\u2115] 531 | | [\u2119-\u211D] 532 | | [\u2124] 533 | | [\u2126] 534 | | [\u2128] 535 | | [\u212A-\u212D] 536 | | [\u212F-\u2131] 537 | | [\u2133-\u2139] 538 | | [\u2160-\u2183] 539 | | [\u3005-\u3007] 540 | | [\u3021-\u3029] 541 | | [\u3031-\u3035] 542 | | [\u3038-\u303A] 543 | | [\u3041-\u3094] 544 | | [\u309D-\u309E] 545 | | [\u30A1-\u30FA] 546 | | [\u30FC-\u30FE] 547 | | [\u3105-\u312C] 548 | | [\u3131-\u318E] 549 | | [\u31A0-\u31B7] 550 | | [\u3400] 551 | | [\u4DB5] 552 | | [\u4E00] 553 | | [\u9FA5] 554 | | [\uA000-\uA48C] 555 | | [\uAC00] 556 | | [\uD7A3] 557 | | [\uF900-\uFA2D] 558 | | [\uFB00-\uFB06] 559 | | [\uFB13-\uFB17] 560 | | [\uFB1D] 561 | | [\uFB1F-\uFB28] 562 | | [\uFB2A-\uFB36] 563 | | [\uFB38-\uFB3C] 564 | | [\uFB3E] 565 | | [\uFB40-\uFB41] 566 | | [\uFB43-\uFB44] 567 | | [\uFB46-\uFBB1] 568 | | [\uFBD3-\uFD3D] 569 | | [\uFD50-\uFD8F] 570 | | [\uFD92-\uFDC7] 571 | | [\uFDF0-\uFDFB] 572 | | [\uFE70-\uFE72] 573 | | [\uFE74] 574 | | [\uFE76-\uFEFC] 575 | | [\uFF21-\uFF3A] 576 | | [\uFF41-\uFF5A] 577 | | [\uFF66-\uFFBE] 578 | | [\uFFC2-\uFFC7] 579 | | [\uFFCA-\uFFCF] 580 | | [\uFFD2-\uFFD7] 581 | | [\uFFDA-\uFFDC] 582 | ; 583 | 584 | WS : [ \r\n\t]+ -> skip 585 | ; -------------------------------------------------------------------------------- /internal/lambda/Lambda.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | T__17=18 19 | T__18=19 20 | T__19=20 21 | T__20=21 22 | T__21=22 23 | T__22=23 24 | T__23=24 25 | T__24=25 26 | T__25=26 27 | IDENTIFIER=27 28 | BINARY_OP=28 29 | INT_LIT=29 30 | BOOL_LIT=30 31 | FLOAT_LIT=31 32 | IMAGINARY_LIT=32 33 | RUNE_LIT=33 34 | LITTLE_U_VALUE=34 35 | BIG_U_VALUE=35 36 | STRING_LIT=36 37 | WS=37 38 | '=>'=1 39 | '('=2 40 | ','=3 41 | ')'=4 42 | '.'=5 43 | '*'=6 44 | '/'=7 45 | '%'=8 46 | '<<'=9 47 | '>>'=10 48 | '&'=11 49 | '&^'=12 50 | '+'=13 51 | '-'=14 52 | '|'=15 53 | '^'=16 54 | '=='=17 55 | '!='=18 56 | '<'=19 57 | '<='=20 58 | '>'=21 59 | '>='=22 60 | '&&'=23 61 | '||'=24 62 | '!'=25 63 | '<-'=26 64 | -------------------------------------------------------------------------------- /internal/lambda/LambdaLexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | T__8=9 10 | T__9=10 11 | T__10=11 12 | T__11=12 13 | T__12=13 14 | T__13=14 15 | T__14=15 16 | T__15=16 17 | T__16=17 18 | T__17=18 19 | T__18=19 20 | T__19=20 21 | T__20=21 22 | T__21=22 23 | T__22=23 24 | T__23=24 25 | T__24=25 26 | T__25=26 27 | IDENTIFIER=27 28 | BINARY_OP=28 29 | INT_LIT=29 30 | BOOL_LIT=30 31 | FLOAT_LIT=31 32 | IMAGINARY_LIT=32 33 | RUNE_LIT=33 34 | LITTLE_U_VALUE=34 35 | BIG_U_VALUE=35 36 | STRING_LIT=36 37 | WS=37 38 | '=>'=1 39 | '('=2 40 | ','=3 41 | ')'=4 42 | '.'=5 43 | '*'=6 44 | '/'=7 45 | '%'=8 46 | '<<'=9 47 | '>>'=10 48 | '&'=11 49 | '&^'=12 50 | '+'=13 51 | '-'=14 52 | '|'=15 53 | '^'=16 54 | '=='=17 55 | '!='=18 56 | '<'=19 57 | '<='=20 58 | '>'=21 59 | '>='=22 60 | '&&'=23 61 | '||'=24 62 | '!'=25 63 | '<-'=26 64 | -------------------------------------------------------------------------------- /internal/lambda/lambda_base_listener.go: -------------------------------------------------------------------------------- 1 | // Generated from Lambda.g4 by ANTLR 4.7. 2 | 3 | package lambda // Lambda 4 | import "github.com/antlr/antlr4/runtime/Go/antlr" 5 | 6 | // BaseLambdaListener is a complete listener for a parse tree produced by LambdaParser. 7 | type BaseLambdaListener struct{} 8 | 9 | var _ LambdaListener = &BaseLambdaListener{} 10 | 11 | // VisitTerminal is called when a terminal node is visited. 12 | func (s *BaseLambdaListener) VisitTerminal(node antlr.TerminalNode) {} 13 | 14 | // VisitErrorNode is called when an error node is visited. 15 | func (s *BaseLambdaListener) VisitErrorNode(node antlr.ErrorNode) {} 16 | 17 | // EnterEveryRule is called when any rule is entered. 18 | func (s *BaseLambdaListener) EnterEveryRule(ctx antlr.ParserRuleContext) {} 19 | 20 | // ExitEveryRule is called when any rule is exited. 21 | func (s *BaseLambdaListener) ExitEveryRule(ctx antlr.ParserRuleContext) {} 22 | 23 | // EnterLambda is called when production lambda is entered. 24 | func (s *BaseLambdaListener) EnterLambda(ctx *LambdaContext) {} 25 | 26 | // ExitLambda is called when production lambda is exited. 27 | func (s *BaseLambdaListener) ExitLambda(ctx *LambdaContext) {} 28 | 29 | // EnterSignature is called when production signature is entered. 30 | func (s *BaseLambdaListener) EnterSignature(ctx *SignatureContext) {} 31 | 32 | // ExitSignature is called when production signature is exited. 33 | func (s *BaseLambdaListener) ExitSignature(ctx *SignatureContext) {} 34 | 35 | // EnterOperand is called when production operand is entered. 36 | func (s *BaseLambdaListener) EnterOperand(ctx *OperandContext) {} 37 | 38 | // ExitOperand is called when production operand is exited. 39 | func (s *BaseLambdaListener) ExitOperand(ctx *OperandContext) {} 40 | 41 | // EnterBasicLit is called when production basicLit is entered. 42 | func (s *BaseLambdaListener) EnterBasicLit(ctx *BasicLitContext) {} 43 | 44 | // ExitBasicLit is called when production basicLit is exited. 45 | func (s *BaseLambdaListener) ExitBasicLit(ctx *BasicLitContext) {} 46 | 47 | // EnterOperandName is called when production operandName is entered. 48 | func (s *BaseLambdaListener) EnterOperandName(ctx *OperandNameContext) {} 49 | 50 | // ExitOperandName is called when production operandName is exited. 51 | func (s *BaseLambdaListener) ExitOperandName(ctx *OperandNameContext) {} 52 | 53 | // EnterPrimaryExpr is called when production primaryExpr is entered. 54 | func (s *BaseLambdaListener) EnterPrimaryExpr(ctx *PrimaryExprContext) {} 55 | 56 | // ExitPrimaryExpr is called when production primaryExpr is exited. 57 | func (s *BaseLambdaListener) ExitPrimaryExpr(ctx *PrimaryExprContext) {} 58 | 59 | // EnterSelector is called when production selector is entered. 60 | func (s *BaseLambdaListener) EnterSelector(ctx *SelectorContext) {} 61 | 62 | // ExitSelector is called when production selector is exited. 63 | func (s *BaseLambdaListener) ExitSelector(ctx *SelectorContext) {} 64 | 65 | // EnterFirstExpr is called when production firstExpr is entered. 66 | func (s *BaseLambdaListener) EnterFirstExpr(ctx *FirstExprContext) {} 67 | 68 | // ExitFirstExpr is called when production firstExpr is exited. 69 | func (s *BaseLambdaListener) ExitFirstExpr(ctx *FirstExprContext) {} 70 | 71 | // EnterValueExpr is called when production valueExpr is entered. 72 | func (s *BaseLambdaListener) EnterValueExpr(ctx *ValueExprContext) {} 73 | 74 | // ExitValueExpr is called when production valueExpr is exited. 75 | func (s *BaseLambdaListener) ExitValueExpr(ctx *ValueExprContext) {} 76 | 77 | // EnterSecondExpr is called when production secondExpr is entered. 78 | func (s *BaseLambdaListener) EnterSecondExpr(ctx *SecondExprContext) {} 79 | 80 | // ExitSecondExpr is called when production secondExpr is exited. 81 | func (s *BaseLambdaListener) ExitSecondExpr(ctx *SecondExprContext) {} 82 | 83 | // EnterQuoteExpr is called when production quoteExpr is entered. 84 | func (s *BaseLambdaListener) EnterQuoteExpr(ctx *QuoteExprContext) {} 85 | 86 | // ExitQuoteExpr is called when production quoteExpr is exited. 87 | func (s *BaseLambdaListener) ExitQuoteExpr(ctx *QuoteExprContext) {} 88 | 89 | // EnterThirdExpr is called when production thirdExpr is entered. 90 | func (s *BaseLambdaListener) EnterThirdExpr(ctx *ThirdExprContext) {} 91 | 92 | // ExitThirdExpr is called when production thirdExpr is exited. 93 | func (s *BaseLambdaListener) ExitThirdExpr(ctx *ThirdExprContext) {} 94 | 95 | // EnterOrExpr is called when production orExpr is entered. 96 | func (s *BaseLambdaListener) EnterOrExpr(ctx *OrExprContext) {} 97 | 98 | // ExitOrExpr is called when production orExpr is exited. 99 | func (s *BaseLambdaListener) ExitOrExpr(ctx *OrExprContext) {} 100 | 101 | // EnterAndExpr is called when production andExpr is entered. 102 | func (s *BaseLambdaListener) EnterAndExpr(ctx *AndExprContext) {} 103 | 104 | // ExitAndExpr is called when production andExpr is exited. 105 | func (s *BaseLambdaListener) ExitAndExpr(ctx *AndExprContext) {} 106 | 107 | // EnterUnaryExpr is called when production unaryExpr is entered. 108 | func (s *BaseLambdaListener) EnterUnaryExpr(ctx *UnaryExprContext) {} 109 | 110 | // ExitUnaryExpr is called when production unaryExpr is exited. 111 | func (s *BaseLambdaListener) ExitUnaryExpr(ctx *UnaryExprContext) {} 112 | -------------------------------------------------------------------------------- /internal/lambda/lambda_lexer.go: -------------------------------------------------------------------------------- 1 | // Generated from Lambda.g4 by ANTLR 4.7. 2 | 3 | package lambda 4 | 5 | import ( 6 | "fmt" 7 | "unicode" 8 | 9 | "github.com/antlr/antlr4/runtime/Go/antlr" 10 | ) 11 | 12 | // Suppress unused import error 13 | var _ = fmt.Printf 14 | var _ = unicode.IsLetter 15 | 16 | var serializedLexerAtn = []uint16{ 17 | 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 39, 407, 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, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 30 | 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 31 | 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 32 | 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 33 | 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 34 | 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 26, 3, 35 | 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 7, 28, 192, 10, 28, 12, 28, 36 | 14, 28, 195, 11, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 37 | 29, 204, 10, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 38 | 3, 30, 3, 30, 5, 30, 216, 10, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 39 | 32, 3, 32, 3, 32, 3, 32, 3, 32, 5, 32, 228, 10, 32, 3, 33, 3, 33, 3, 33, 40 | 5, 33, 233, 10, 33, 3, 34, 3, 34, 3, 34, 5, 34, 238, 10, 34, 3, 35, 3, 41 | 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 5, 35, 249, 10, 35, 42 | 3, 36, 3, 36, 7, 36, 253, 10, 36, 12, 36, 14, 36, 256, 11, 36, 3, 37, 3, 43 | 37, 7, 37, 260, 10, 37, 12, 37, 14, 37, 263, 11, 37, 3, 38, 3, 38, 3, 38, 44 | 6, 38, 268, 10, 38, 13, 38, 14, 38, 269, 3, 39, 3, 39, 3, 39, 5, 39, 275, 45 | 10, 39, 3, 39, 5, 39, 278, 10, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 39, 3, 46 | 39, 5, 39, 286, 10, 39, 5, 39, 288, 10, 39, 3, 40, 6, 40, 291, 10, 40, 47 | 13, 40, 14, 40, 292, 3, 41, 3, 41, 5, 41, 297, 10, 41, 3, 41, 3, 41, 3, 48 | 42, 3, 42, 5, 42, 303, 10, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 5, 43, 49 | 310, 10, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 5, 44, 318, 10, 50 | 44, 3, 45, 3, 45, 5, 45, 322, 10, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 51 | 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 52 | 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 53 | 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 51, 3, 51, 5, 51, 359, 54 | 10, 51, 3, 52, 3, 52, 3, 52, 7, 52, 364, 10, 52, 12, 52, 14, 52, 367, 11, 55 | 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 7, 53, 374, 10, 53, 12, 53, 14, 56 | 53, 377, 11, 53, 3, 53, 3, 53, 3, 54, 3, 54, 5, 54, 383, 10, 54, 3, 55, 57 | 3, 55, 3, 56, 3, 56, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 60, 5, 58 | 60, 396, 10, 60, 3, 61, 5, 61, 399, 10, 61, 3, 62, 6, 62, 402, 10, 62, 59 | 13, 62, 14, 62, 403, 3, 62, 3, 62, 2, 2, 63, 3, 3, 5, 4, 7, 5, 9, 6, 11, 60 | 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 61 | 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 62 | 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 2, 61, 2, 63, 2, 65, 2, 67, 63 | 31, 69, 32, 71, 2, 73, 2, 75, 2, 77, 33, 79, 2, 81, 2, 83, 34, 85, 35, 64 | 87, 2, 89, 2, 91, 2, 93, 2, 95, 36, 97, 37, 99, 2, 101, 38, 103, 2, 105, 65 | 2, 107, 2, 109, 2, 111, 2, 113, 2, 115, 2, 117, 2, 119, 2, 121, 2, 123, 66 | 39, 3, 2, 17, 6, 2, 45, 45, 47, 47, 96, 96, 126, 126, 5, 2, 39, 39, 44, 67 | 44, 49, 49, 7, 2, 35, 35, 40, 40, 44, 45, 47, 47, 96, 96, 3, 2, 51, 59, 68 | 4, 2, 90, 90, 122, 122, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 11, 69 | 2, 36, 36, 41, 41, 94, 94, 99, 100, 104, 104, 112, 112, 116, 116, 118, 70 | 118, 120, 120, 3, 2, 50, 59, 3, 2, 50, 57, 5, 2, 50, 59, 67, 72, 99, 104, 71 | 3, 2, 12, 12, 22, 2, 50, 59, 1634, 1643, 1778, 1787, 2408, 2417, 2536, 72 | 2545, 2664, 2673, 2792, 2801, 2920, 2929, 3049, 3057, 3176, 3185, 3304, 73 | 3313, 3432, 3441, 3666, 3675, 3794, 3803, 3874, 3883, 4162, 4171, 4971, 74 | 4979, 6114, 6123, 6162, 6171, 65298, 65307, 260, 2, 67, 92, 99, 124, 172, 75 | 172, 183, 183, 188, 188, 194, 216, 218, 248, 250, 545, 548, 565, 594, 687, 76 | 690, 698, 701, 707, 722, 723, 738, 742, 752, 752, 892, 892, 904, 904, 906, 77 | 908, 910, 910, 912, 931, 933, 976, 978, 985, 988, 1013, 1026, 1155, 1166, 78 | 1222, 1225, 1226, 1229, 1230, 1234, 1271, 1274, 1275, 1331, 1368, 1371, 79 | 1371, 1379, 1417, 1490, 1516, 1522, 1524, 1571, 1596, 1602, 1612, 1651, 80 | 1749, 1751, 1751, 1767, 1768, 1788, 1790, 1810, 1810, 1812, 1838, 1922, 81 | 1959, 2311, 2363, 2367, 2367, 2386, 2386, 2394, 2403, 2439, 2446, 2449, 82 | 2450, 2453, 2474, 2476, 2482, 2484, 2484, 2488, 2491, 2526, 2527, 2529, 83 | 2531, 2546, 2547, 2567, 2572, 2577, 2578, 2581, 2602, 2604, 2610, 2612, 84 | 2613, 2615, 2616, 2618, 2619, 2651, 2654, 2656, 2656, 2676, 2678, 2695, 85 | 2701, 2703, 2703, 2705, 2707, 2709, 2730, 2732, 2738, 2740, 2741, 2743, 86 | 2747, 2751, 2751, 2770, 2770, 2786, 2786, 2823, 2830, 2833, 2834, 2837, 87 | 2858, 2860, 2866, 2868, 2869, 2872, 2875, 2879, 2879, 2910, 2911, 2913, 88 | 2915, 2951, 2956, 2960, 2962, 2964, 2967, 2971, 2972, 2974, 2974, 2976, 89 | 2977, 2981, 2982, 2986, 2988, 2992, 2999, 3001, 3003, 3079, 3086, 3088, 90 | 3090, 3092, 3114, 3116, 3125, 3127, 3131, 3170, 3171, 3207, 3214, 3216, 91 | 3218, 3220, 3242, 3244, 3253, 3255, 3259, 3296, 3296, 3298, 3299, 3335, 92 | 3342, 3344, 3346, 3348, 3370, 3372, 3387, 3426, 3427, 3463, 3480, 3484, 93 | 3507, 3509, 3517, 3519, 3519, 3522, 3528, 3587, 3634, 3636, 3637, 3650, 94 | 3656, 3715, 3716, 3718, 3718, 3721, 3722, 3724, 3724, 3727, 3727, 3734, 95 | 3737, 3739, 3745, 3747, 3749, 3751, 3751, 3753, 3753, 3756, 3757, 3759, 96 | 3762, 3764, 3765, 3775, 3782, 3784, 3784, 3806, 3807, 3842, 3842, 3906, 97 | 3948, 3978, 3981, 4098, 4131, 4133, 4137, 4139, 4140, 4178, 4183, 4258, 98 | 4295, 4306, 4344, 4354, 4443, 4449, 4516, 4522, 4603, 4610, 4616, 4618, 99 | 4680, 4682, 4682, 4684, 4687, 4690, 4696, 4698, 4698, 4700, 4703, 4706, 100 | 4744, 4746, 4746, 4748, 4751, 4754, 4784, 4786, 4786, 4788, 4791, 4794, 101 | 4800, 4802, 4802, 4804, 4807, 4810, 4816, 4818, 4824, 4826, 4848, 4850, 102 | 4880, 4882, 4882, 4884, 4887, 4890, 4896, 4898, 4936, 4938, 4956, 5026, 103 | 5110, 5123, 5752, 5763, 5788, 5794, 5868, 6018, 6069, 6178, 6265, 6274, 104 | 6314, 7682, 7837, 7842, 7931, 7938, 7959, 7962, 7967, 7970, 8007, 8010, 105 | 8015, 8018, 8025, 8027, 8027, 8029, 8029, 8031, 8031, 8033, 8063, 8066, 106 | 8118, 8120, 8126, 8128, 8128, 8132, 8134, 8136, 8142, 8146, 8149, 8152, 107 | 8157, 8162, 8174, 8180, 8182, 8184, 8190, 8321, 8321, 8452, 8452, 8457, 108 | 8457, 8460, 8469, 8471, 8471, 8475, 8479, 8486, 8486, 8488, 8488, 8490, 109 | 8490, 8492, 8495, 8497, 8499, 8501, 8507, 8546, 8581, 12295, 12297, 12323, 110 | 12331, 12339, 12343, 12346, 12348, 12355, 12438, 12447, 12448, 12451, 12540, 111 | 12542, 12544, 12551, 12590, 12595, 12688, 12706, 12729, 13314, 13314, 19895, 112 | 19895, 19970, 19970, 40871, 40871, 40962, 42126, 44034, 44034, 55205, 55205, 113 | 63746, 64047, 64258, 64264, 64277, 64281, 64287, 64287, 64289, 64298, 64300, 114 | 64312, 64314, 64318, 64320, 64320, 64322, 64323, 64325, 64326, 64328, 64435, 115 | 64469, 64831, 64850, 64913, 64916, 64969, 65010, 65021, 65138, 65140, 65142, 116 | 65142, 65144, 65278, 65315, 65340, 65347, 65372, 65384, 65472, 65476, 65481, 117 | 65484, 65489, 65492, 65497, 65500, 65502, 5, 2, 11, 12, 15, 15, 34, 34, 118 | 2, 424, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 119 | 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 120 | 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 121 | 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 122 | 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 123 | 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 124 | 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 125 | 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 77, 126 | 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 127 | 97, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 3, 125, 3, 2, 2, 128 | 2, 5, 128, 3, 2, 2, 2, 7, 130, 3, 2, 2, 2, 9, 132, 3, 2, 2, 2, 11, 134, 129 | 3, 2, 2, 2, 13, 136, 3, 2, 2, 2, 15, 138, 3, 2, 2, 2, 17, 140, 3, 2, 2, 130 | 2, 19, 142, 3, 2, 2, 2, 21, 145, 3, 2, 2, 2, 23, 148, 3, 2, 2, 2, 25, 150, 131 | 3, 2, 2, 2, 27, 153, 3, 2, 2, 2, 29, 155, 3, 2, 2, 2, 31, 157, 3, 2, 2, 132 | 2, 33, 159, 3, 2, 2, 2, 35, 161, 3, 2, 2, 2, 37, 164, 3, 2, 2, 2, 39, 167, 133 | 3, 2, 2, 2, 41, 169, 3, 2, 2, 2, 43, 172, 3, 2, 2, 2, 45, 174, 3, 2, 2, 134 | 2, 47, 177, 3, 2, 2, 2, 49, 180, 3, 2, 2, 2, 51, 183, 3, 2, 2, 2, 53, 185, 135 | 3, 2, 2, 2, 55, 188, 3, 2, 2, 2, 57, 203, 3, 2, 2, 2, 59, 215, 3, 2, 2, 136 | 2, 61, 217, 3, 2, 2, 2, 63, 227, 3, 2, 2, 2, 65, 232, 3, 2, 2, 2, 67, 237, 137 | 3, 2, 2, 2, 69, 248, 3, 2, 2, 2, 71, 250, 3, 2, 2, 2, 73, 257, 3, 2, 2, 138 | 2, 75, 264, 3, 2, 2, 2, 77, 287, 3, 2, 2, 2, 79, 290, 3, 2, 2, 2, 81, 294, 139 | 3, 2, 2, 2, 83, 302, 3, 2, 2, 2, 85, 306, 3, 2, 2, 2, 87, 317, 3, 2, 2, 140 | 2, 89, 321, 3, 2, 2, 2, 91, 323, 3, 2, 2, 2, 93, 328, 3, 2, 2, 2, 95, 333, 141 | 3, 2, 2, 2, 97, 341, 3, 2, 2, 2, 99, 353, 3, 2, 2, 2, 101, 358, 3, 2, 2, 142 | 2, 103, 360, 3, 2, 2, 2, 105, 370, 3, 2, 2, 2, 107, 382, 3, 2, 2, 2, 109, 143 | 384, 3, 2, 2, 2, 111, 386, 3, 2, 2, 2, 113, 388, 3, 2, 2, 2, 115, 390, 144 | 3, 2, 2, 2, 117, 392, 3, 2, 2, 2, 119, 395, 3, 2, 2, 2, 121, 398, 3, 2, 145 | 2, 2, 123, 401, 3, 2, 2, 2, 125, 126, 7, 63, 2, 2, 126, 127, 7, 64, 2, 146 | 2, 127, 4, 3, 2, 2, 2, 128, 129, 7, 42, 2, 2, 129, 6, 3, 2, 2, 2, 130, 147 | 131, 7, 46, 2, 2, 131, 8, 3, 2, 2, 2, 132, 133, 7, 43, 2, 2, 133, 10, 3, 148 | 2, 2, 2, 134, 135, 7, 48, 2, 2, 135, 12, 3, 2, 2, 2, 136, 137, 7, 44, 2, 149 | 2, 137, 14, 3, 2, 2, 2, 138, 139, 7, 49, 2, 2, 139, 16, 3, 2, 2, 2, 140, 150 | 141, 7, 39, 2, 2, 141, 18, 3, 2, 2, 2, 142, 143, 7, 62, 2, 2, 143, 144, 151 | 7, 62, 2, 2, 144, 20, 3, 2, 2, 2, 145, 146, 7, 64, 2, 2, 146, 147, 7, 64, 152 | 2, 2, 147, 22, 3, 2, 2, 2, 148, 149, 7, 40, 2, 2, 149, 24, 3, 2, 2, 2, 153 | 150, 151, 7, 40, 2, 2, 151, 152, 7, 96, 2, 2, 152, 26, 3, 2, 2, 2, 153, 154 | 154, 7, 45, 2, 2, 154, 28, 3, 2, 2, 2, 155, 156, 7, 47, 2, 2, 156, 30, 155 | 3, 2, 2, 2, 157, 158, 7, 126, 2, 2, 158, 32, 3, 2, 2, 2, 159, 160, 7, 96, 156 | 2, 2, 160, 34, 3, 2, 2, 2, 161, 162, 7, 63, 2, 2, 162, 163, 7, 63, 2, 2, 157 | 163, 36, 3, 2, 2, 2, 164, 165, 7, 35, 2, 2, 165, 166, 7, 63, 2, 2, 166, 158 | 38, 3, 2, 2, 2, 167, 168, 7, 62, 2, 2, 168, 40, 3, 2, 2, 2, 169, 170, 7, 159 | 62, 2, 2, 170, 171, 7, 63, 2, 2, 171, 42, 3, 2, 2, 2, 172, 173, 7, 64, 160 | 2, 2, 173, 44, 3, 2, 2, 2, 174, 175, 7, 64, 2, 2, 175, 176, 7, 63, 2, 2, 161 | 176, 46, 3, 2, 2, 2, 177, 178, 7, 40, 2, 2, 178, 179, 7, 40, 2, 2, 179, 162 | 48, 3, 2, 2, 2, 180, 181, 7, 126, 2, 2, 181, 182, 7, 126, 2, 2, 182, 50, 163 | 3, 2, 2, 2, 183, 184, 7, 35, 2, 2, 184, 52, 3, 2, 2, 2, 185, 186, 7, 62, 164 | 2, 2, 186, 187, 7, 47, 2, 2, 187, 54, 3, 2, 2, 2, 188, 193, 5, 107, 54, 165 | 2, 189, 192, 5, 107, 54, 2, 190, 192, 5, 119, 60, 2, 191, 189, 3, 2, 2, 166 | 2, 191, 190, 3, 2, 2, 2, 192, 195, 3, 2, 2, 2, 193, 191, 3, 2, 2, 2, 193, 167 | 194, 3, 2, 2, 2, 194, 56, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 196, 197, 7, 168 | 126, 2, 2, 197, 204, 7, 126, 2, 2, 198, 199, 7, 40, 2, 2, 199, 204, 7, 169 | 40, 2, 2, 200, 204, 5, 59, 30, 2, 201, 204, 5, 61, 31, 2, 202, 204, 5, 170 | 63, 32, 2, 203, 196, 3, 2, 2, 2, 203, 198, 3, 2, 2, 2, 203, 200, 3, 2, 171 | 2, 2, 203, 201, 3, 2, 2, 2, 203, 202, 3, 2, 2, 2, 204, 58, 3, 2, 2, 2, 172 | 205, 206, 7, 63, 2, 2, 206, 216, 7, 63, 2, 2, 207, 208, 7, 35, 2, 2, 208, 173 | 216, 7, 63, 2, 2, 209, 216, 7, 62, 2, 2, 210, 211, 7, 62, 2, 2, 211, 216, 174 | 7, 63, 2, 2, 212, 216, 7, 64, 2, 2, 213, 214, 7, 64, 2, 2, 214, 216, 7, 175 | 63, 2, 2, 215, 205, 3, 2, 2, 2, 215, 207, 3, 2, 2, 2, 215, 209, 3, 2, 2, 176 | 2, 215, 210, 3, 2, 2, 2, 215, 212, 3, 2, 2, 2, 215, 213, 3, 2, 2, 2, 216, 177 | 60, 3, 2, 2, 2, 217, 218, 9, 2, 2, 2, 218, 62, 3, 2, 2, 2, 219, 228, 9, 178 | 3, 2, 2, 220, 221, 7, 62, 2, 2, 221, 228, 7, 62, 2, 2, 222, 223, 7, 64, 179 | 2, 2, 223, 228, 7, 64, 2, 2, 224, 228, 7, 40, 2, 2, 225, 226, 7, 40, 2, 180 | 2, 226, 228, 7, 96, 2, 2, 227, 219, 3, 2, 2, 2, 227, 220, 3, 2, 2, 2, 227, 181 | 222, 3, 2, 2, 2, 227, 224, 3, 2, 2, 2, 227, 225, 3, 2, 2, 2, 228, 64, 3, 182 | 2, 2, 2, 229, 233, 9, 4, 2, 2, 230, 231, 7, 62, 2, 2, 231, 233, 7, 47, 183 | 2, 2, 232, 229, 3, 2, 2, 2, 232, 230, 3, 2, 2, 2, 233, 66, 3, 2, 2, 2, 184 | 234, 238, 5, 71, 36, 2, 235, 238, 5, 73, 37, 2, 236, 238, 5, 75, 38, 2, 185 | 237, 234, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 237, 236, 3, 2, 2, 2, 238, 186 | 68, 3, 2, 2, 2, 239, 240, 7, 118, 2, 2, 240, 241, 7, 116, 2, 2, 241, 242, 187 | 7, 119, 2, 2, 242, 249, 7, 103, 2, 2, 243, 244, 7, 104, 2, 2, 244, 245, 188 | 7, 99, 2, 2, 245, 246, 7, 110, 2, 2, 246, 247, 7, 117, 2, 2, 247, 249, 189 | 7, 103, 2, 2, 248, 239, 3, 2, 2, 2, 248, 243, 3, 2, 2, 2, 249, 70, 3, 2, 190 | 2, 2, 250, 254, 9, 5, 2, 2, 251, 253, 5, 109, 55, 2, 252, 251, 3, 2, 2, 191 | 2, 253, 256, 3, 2, 2, 2, 254, 252, 3, 2, 2, 2, 254, 255, 3, 2, 2, 2, 255, 192 | 72, 3, 2, 2, 2, 256, 254, 3, 2, 2, 2, 257, 261, 7, 50, 2, 2, 258, 260, 193 | 5, 111, 56, 2, 259, 258, 3, 2, 2, 2, 260, 263, 3, 2, 2, 2, 261, 259, 3, 194 | 2, 2, 2, 261, 262, 3, 2, 2, 2, 262, 74, 3, 2, 2, 2, 263, 261, 3, 2, 2, 195 | 2, 264, 265, 7, 50, 2, 2, 265, 267, 9, 6, 2, 2, 266, 268, 5, 113, 57, 2, 196 | 267, 266, 3, 2, 2, 2, 268, 269, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 269, 197 | 270, 3, 2, 2, 2, 270, 76, 3, 2, 2, 2, 271, 272, 5, 79, 40, 2, 272, 274, 198 | 7, 48, 2, 2, 273, 275, 5, 79, 40, 2, 274, 273, 3, 2, 2, 2, 274, 275, 3, 199 | 2, 2, 2, 275, 277, 3, 2, 2, 2, 276, 278, 5, 81, 41, 2, 277, 276, 3, 2, 200 | 2, 2, 277, 278, 3, 2, 2, 2, 278, 288, 3, 2, 2, 2, 279, 280, 5, 79, 40, 201 | 2, 280, 281, 5, 81, 41, 2, 281, 288, 3, 2, 2, 2, 282, 283, 7, 48, 2, 2, 202 | 283, 285, 5, 79, 40, 2, 284, 286, 5, 81, 41, 2, 285, 284, 3, 2, 2, 2, 285, 203 | 286, 3, 2, 2, 2, 286, 288, 3, 2, 2, 2, 287, 271, 3, 2, 2, 2, 287, 279, 204 | 3, 2, 2, 2, 287, 282, 3, 2, 2, 2, 288, 78, 3, 2, 2, 2, 289, 291, 5, 109, 205 | 55, 2, 290, 289, 3, 2, 2, 2, 291, 292, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 206 | 292, 293, 3, 2, 2, 2, 293, 80, 3, 2, 2, 2, 294, 296, 9, 7, 2, 2, 295, 297, 207 | 9, 8, 2, 2, 296, 295, 3, 2, 2, 2, 296, 297, 3, 2, 2, 2, 297, 298, 3, 2, 208 | 2, 2, 298, 299, 5, 79, 40, 2, 299, 82, 3, 2, 2, 2, 300, 303, 5, 79, 40, 209 | 2, 301, 303, 5, 77, 39, 2, 302, 300, 3, 2, 2, 2, 302, 301, 3, 2, 2, 2, 210 | 303, 304, 3, 2, 2, 2, 304, 305, 7, 107, 2, 2, 305, 84, 3, 2, 2, 2, 306, 211 | 309, 7, 41, 2, 2, 307, 310, 5, 87, 44, 2, 308, 310, 5, 89, 45, 2, 309, 212 | 307, 3, 2, 2, 2, 309, 308, 3, 2, 2, 2, 310, 311, 3, 2, 2, 2, 311, 312, 213 | 7, 41, 2, 2, 312, 86, 3, 2, 2, 2, 313, 318, 5, 117, 59, 2, 314, 318, 5, 214 | 95, 48, 2, 315, 318, 5, 97, 49, 2, 316, 318, 5, 99, 50, 2, 317, 313, 3, 215 | 2, 2, 2, 317, 314, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 316, 3, 2, 2, 216 | 2, 318, 88, 3, 2, 2, 2, 319, 322, 5, 91, 46, 2, 320, 322, 5, 93, 47, 2, 217 | 321, 319, 3, 2, 2, 2, 321, 320, 3, 2, 2, 2, 322, 90, 3, 2, 2, 2, 323, 324, 218 | 7, 94, 2, 2, 324, 325, 5, 111, 56, 2, 325, 326, 5, 111, 56, 2, 326, 327, 219 | 5, 111, 56, 2, 327, 92, 3, 2, 2, 2, 328, 329, 7, 94, 2, 2, 329, 330, 7, 220 | 122, 2, 2, 330, 331, 5, 113, 57, 2, 331, 332, 5, 113, 57, 2, 332, 94, 3, 221 | 2, 2, 2, 333, 334, 7, 94, 2, 2, 334, 335, 7, 119, 2, 2, 335, 336, 3, 2, 222 | 2, 2, 336, 337, 5, 113, 57, 2, 337, 338, 5, 113, 57, 2, 338, 339, 5, 113, 223 | 57, 2, 339, 340, 5, 113, 57, 2, 340, 96, 3, 2, 2, 2, 341, 342, 7, 94, 2, 224 | 2, 342, 343, 7, 87, 2, 2, 343, 344, 3, 2, 2, 2, 344, 345, 5, 113, 57, 2, 225 | 345, 346, 5, 113, 57, 2, 346, 347, 5, 113, 57, 2, 347, 348, 5, 113, 57, 226 | 2, 348, 349, 5, 113, 57, 2, 349, 350, 5, 113, 57, 2, 350, 351, 5, 113, 227 | 57, 2, 351, 352, 5, 113, 57, 2, 352, 98, 3, 2, 2, 2, 353, 354, 7, 94, 2, 228 | 2, 354, 355, 9, 9, 2, 2, 355, 100, 3, 2, 2, 2, 356, 359, 5, 103, 52, 2, 229 | 357, 359, 5, 105, 53, 2, 358, 356, 3, 2, 2, 2, 358, 357, 3, 2, 2, 2, 359, 230 | 102, 3, 2, 2, 2, 360, 365, 7, 98, 2, 2, 361, 364, 5, 117, 59, 2, 362, 364, 231 | 5, 115, 58, 2, 363, 361, 3, 2, 2, 2, 363, 362, 3, 2, 2, 2, 364, 367, 3, 232 | 2, 2, 2, 365, 363, 3, 2, 2, 2, 365, 366, 3, 2, 2, 2, 366, 368, 3, 2, 2, 233 | 2, 367, 365, 3, 2, 2, 2, 368, 369, 7, 98, 2, 2, 369, 104, 3, 2, 2, 2, 370, 234 | 375, 7, 36, 2, 2, 371, 374, 5, 87, 44, 2, 372, 374, 5, 89, 45, 2, 373, 235 | 371, 3, 2, 2, 2, 373, 372, 3, 2, 2, 2, 374, 377, 3, 2, 2, 2, 375, 373, 236 | 3, 2, 2, 2, 375, 376, 3, 2, 2, 2, 376, 378, 3, 2, 2, 2, 377, 375, 3, 2, 237 | 2, 2, 378, 379, 7, 36, 2, 2, 379, 106, 3, 2, 2, 2, 380, 383, 5, 121, 61, 238 | 2, 381, 383, 7, 97, 2, 2, 382, 380, 3, 2, 2, 2, 382, 381, 3, 2, 2, 2, 383, 239 | 108, 3, 2, 2, 2, 384, 385, 9, 10, 2, 2, 385, 110, 3, 2, 2, 2, 386, 387, 240 | 9, 11, 2, 2, 387, 112, 3, 2, 2, 2, 388, 389, 9, 12, 2, 2, 389, 114, 3, 241 | 2, 2, 2, 390, 391, 9, 13, 2, 2, 391, 116, 3, 2, 2, 2, 392, 393, 10, 13, 242 | 2, 2, 393, 118, 3, 2, 2, 2, 394, 396, 9, 14, 2, 2, 395, 394, 3, 2, 2, 2, 243 | 396, 120, 3, 2, 2, 2, 397, 399, 9, 15, 2, 2, 398, 397, 3, 2, 2, 2, 399, 244 | 122, 3, 2, 2, 2, 400, 402, 9, 16, 2, 2, 401, 400, 3, 2, 2, 2, 402, 403, 245 | 3, 2, 2, 2, 403, 401, 3, 2, 2, 2, 403, 404, 3, 2, 2, 2, 404, 405, 3, 2, 246 | 2, 2, 405, 406, 8, 62, 2, 2, 406, 124, 3, 2, 2, 2, 33, 2, 191, 193, 203, 247 | 215, 227, 232, 237, 248, 254, 261, 269, 274, 277, 285, 287, 292, 296, 302, 248 | 309, 317, 321, 358, 363, 365, 373, 375, 382, 395, 398, 403, 3, 8, 2, 2, 249 | } 250 | 251 | var lexerDeserializer = antlr.NewATNDeserializer(nil) 252 | var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn) 253 | 254 | var lexerChannelNames = []string{ 255 | "DEFAULT_TOKEN_CHANNEL", "HIDDEN", 256 | } 257 | 258 | var lexerModeNames = []string{ 259 | "DEFAULT_MODE", 260 | } 261 | 262 | var lexerLiteralNames = []string{ 263 | "", "'=>'", "'('", "','", "')'", "'.'", "'*'", "'/'", "'%'", "'<<'", "'>>'", 264 | "'&'", "'&^'", "'+'", "'-'", "'|'", "'^'", "'=='", "'!='", "'<'", "'<='", 265 | "'>'", "'>='", "'&&'", "'||'", "'!'", "'<-'", 266 | } 267 | 268 | var lexerSymbolicNames = []string{ 269 | "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 270 | "", "", "", "", "", "", "", "", "", "IDENTIFIER", "BINARY_OP", "INT_LIT", 271 | "BOOL_LIT", "FLOAT_LIT", "IMAGINARY_LIT", "RUNE_LIT", "LITTLE_U_VALUE", 272 | "BIG_U_VALUE", "STRING_LIT", "WS", 273 | } 274 | 275 | var lexerRuleNames = []string{ 276 | "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", 277 | "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", 278 | "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", 279 | "T__25", "IDENTIFIER", "BINARY_OP", "REL_OP", "ADD_OP", "MUL_OP", "UNARY_OP", 280 | "INT_LIT", "BOOL_LIT", "DECIMAL_LIT", "OCTAL_LIT", "HEX_LIT", "FLOAT_LIT", 281 | "DECIMALS", "EXPONENT", "IMAGINARY_LIT", "RUNE_LIT", "UNICODE_VALUE", "BYTE_VALUE", 282 | "OCTAL_BYTE_VALUE", "HEX_BYTE_VALUE", "LITTLE_U_VALUE", "BIG_U_VALUE", 283 | "ESCAPED_CHAR", "STRING_LIT", "RAW_STRING_LIT", "INTERPRETED_STRING_LIT", 284 | "LETTER", "DECIMAL_DIGIT", "OCTAL_DIGIT", "HEX_DIGIT", "NEWLINE", "UNICODE_CHAR", 285 | "UNICODE_DIGIT", "UNICODE_LETTER", "WS", 286 | } 287 | 288 | type LambdaLexer struct { 289 | *antlr.BaseLexer 290 | channelNames []string 291 | modeNames []string 292 | // TODO: EOF string 293 | } 294 | 295 | var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState)) 296 | 297 | func init() { 298 | for index, ds := range lexerAtn.DecisionToState { 299 | lexerDecisionToDFA[index] = antlr.NewDFA(ds, index) 300 | } 301 | } 302 | 303 | func NewLambdaLexer(input antlr.CharStream) *LambdaLexer { 304 | 305 | l := new(LambdaLexer) 306 | 307 | l.BaseLexer = antlr.NewBaseLexer(input) 308 | l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache()) 309 | 310 | l.channelNames = lexerChannelNames 311 | l.modeNames = lexerModeNames 312 | l.RuleNames = lexerRuleNames 313 | l.LiteralNames = lexerLiteralNames 314 | l.SymbolicNames = lexerSymbolicNames 315 | l.GrammarFileName = "Lambda.g4" 316 | // TODO: l.EOF = antlr.TokenEOF 317 | 318 | return l 319 | } 320 | 321 | // LambdaLexer tokens. 322 | const ( 323 | LambdaLexerT__0 = 1 324 | LambdaLexerT__1 = 2 325 | LambdaLexerT__2 = 3 326 | LambdaLexerT__3 = 4 327 | LambdaLexerT__4 = 5 328 | LambdaLexerT__5 = 6 329 | LambdaLexerT__6 = 7 330 | LambdaLexerT__7 = 8 331 | LambdaLexerT__8 = 9 332 | LambdaLexerT__9 = 10 333 | LambdaLexerT__10 = 11 334 | LambdaLexerT__11 = 12 335 | LambdaLexerT__12 = 13 336 | LambdaLexerT__13 = 14 337 | LambdaLexerT__14 = 15 338 | LambdaLexerT__15 = 16 339 | LambdaLexerT__16 = 17 340 | LambdaLexerT__17 = 18 341 | LambdaLexerT__18 = 19 342 | LambdaLexerT__19 = 20 343 | LambdaLexerT__20 = 21 344 | LambdaLexerT__21 = 22 345 | LambdaLexerT__22 = 23 346 | LambdaLexerT__23 = 24 347 | LambdaLexerT__24 = 25 348 | LambdaLexerT__25 = 26 349 | LambdaLexerIDENTIFIER = 27 350 | LambdaLexerBINARY_OP = 28 351 | LambdaLexerINT_LIT = 29 352 | LambdaLexerBOOL_LIT = 30 353 | LambdaLexerFLOAT_LIT = 31 354 | LambdaLexerIMAGINARY_LIT = 32 355 | LambdaLexerRUNE_LIT = 33 356 | LambdaLexerLITTLE_U_VALUE = 34 357 | LambdaLexerBIG_U_VALUE = 35 358 | LambdaLexerSTRING_LIT = 36 359 | LambdaLexerWS = 37 360 | ) 361 | -------------------------------------------------------------------------------- /internal/lambda/lambda_listener.go: -------------------------------------------------------------------------------- 1 | // Generated from Lambda.g4 by ANTLR 4.7. 2 | 3 | package lambda // Lambda 4 | import "github.com/antlr/antlr4/runtime/Go/antlr" 5 | 6 | // LambdaListener is a complete listener for a parse tree produced by LambdaParser. 7 | type LambdaListener interface { 8 | antlr.ParseTreeListener 9 | 10 | // EnterLambda is called when entering the lambda production. 11 | EnterLambda(c *LambdaContext) 12 | 13 | // EnterSignature is called when entering the signature production. 14 | EnterSignature(c *SignatureContext) 15 | 16 | // EnterOperand is called when entering the operand production. 17 | EnterOperand(c *OperandContext) 18 | 19 | // EnterBasicLit is called when entering the basicLit production. 20 | EnterBasicLit(c *BasicLitContext) 21 | 22 | // EnterOperandName is called when entering the operandName production. 23 | EnterOperandName(c *OperandNameContext) 24 | 25 | // EnterPrimaryExpr is called when entering the primaryExpr production. 26 | EnterPrimaryExpr(c *PrimaryExprContext) 27 | 28 | // EnterSelector is called when entering the selector production. 29 | EnterSelector(c *SelectorContext) 30 | 31 | // EnterFirstExpr is called when entering the firstExpr production. 32 | EnterFirstExpr(c *FirstExprContext) 33 | 34 | // EnterValueExpr is called when entering the valueExpr production. 35 | EnterValueExpr(c *ValueExprContext) 36 | 37 | // EnterSecondExpr is called when entering the secondExpr production. 38 | EnterSecondExpr(c *SecondExprContext) 39 | 40 | // EnterQuoteExpr is called when entering the quoteExpr production. 41 | EnterQuoteExpr(c *QuoteExprContext) 42 | 43 | // EnterThirdExpr is called when entering the thirdExpr production. 44 | EnterThirdExpr(c *ThirdExprContext) 45 | 46 | // EnterOrExpr is called when entering the orExpr production. 47 | EnterOrExpr(c *OrExprContext) 48 | 49 | // EnterAndExpr is called when entering the andExpr production. 50 | EnterAndExpr(c *AndExprContext) 51 | 52 | // EnterUnaryExpr is called when entering the unaryExpr production. 53 | EnterUnaryExpr(c *UnaryExprContext) 54 | 55 | // ExitLambda is called when exiting the lambda production. 56 | ExitLambda(c *LambdaContext) 57 | 58 | // ExitSignature is called when exiting the signature production. 59 | ExitSignature(c *SignatureContext) 60 | 61 | // ExitOperand is called when exiting the operand production. 62 | ExitOperand(c *OperandContext) 63 | 64 | // ExitBasicLit is called when exiting the basicLit production. 65 | ExitBasicLit(c *BasicLitContext) 66 | 67 | // ExitOperandName is called when exiting the operandName production. 68 | ExitOperandName(c *OperandNameContext) 69 | 70 | // ExitPrimaryExpr is called when exiting the primaryExpr production. 71 | ExitPrimaryExpr(c *PrimaryExprContext) 72 | 73 | // ExitSelector is called when exiting the selector production. 74 | ExitSelector(c *SelectorContext) 75 | 76 | // ExitFirstExpr is called when exiting the firstExpr production. 77 | ExitFirstExpr(c *FirstExprContext) 78 | 79 | // ExitValueExpr is called when exiting the valueExpr production. 80 | ExitValueExpr(c *ValueExprContext) 81 | 82 | // ExitSecondExpr is called when exiting the secondExpr production. 83 | ExitSecondExpr(c *SecondExprContext) 84 | 85 | // ExitQuoteExpr is called when exiting the quoteExpr production. 86 | ExitQuoteExpr(c *QuoteExprContext) 87 | 88 | // ExitThirdExpr is called when exiting the thirdExpr production. 89 | ExitThirdExpr(c *ThirdExprContext) 90 | 91 | // ExitOrExpr is called when exiting the orExpr production. 92 | ExitOrExpr(c *OrExprContext) 93 | 94 | // ExitAndExpr is called when exiting the andExpr production. 95 | ExitAndExpr(c *AndExprContext) 96 | 97 | // ExitUnaryExpr is called when exiting the unaryExpr production. 98 | ExitUnaryExpr(c *UnaryExprContext) 99 | } 100 | -------------------------------------------------------------------------------- /internal/stack/stack.go: -------------------------------------------------------------------------------- 1 | package stack 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | // BoolStack implement a basic stack 8 | type BoolStack struct { 9 | data []bool 10 | sp int 11 | } 12 | 13 | // Pop pops the element atop of the stack 14 | func (s *BoolStack) Pop() bool { 15 | if s.sp < 0 { 16 | return false 17 | } 18 | r := s.data[s.sp] 19 | s.data = s.data[:s.sp] 20 | s.sp-- 21 | return r 22 | } 23 | 24 | // Push pushes an element into the top of the stack 25 | func (s *BoolStack) Push(b bool) { 26 | s.sp++ 27 | s.data = append(s.data, b) 28 | } 29 | 30 | // NewStack create a new stack object 31 | // Make sure invoking release to avoid memory leak 32 | func NewStack() (stack *BoolStack, release func()) { 33 | b := pool.Get().(*BoolStack) 34 | if b.sp > -1 { 35 | b.sp = -1 36 | b.data = b.data[:0] 37 | } 38 | return b, func() { pool.Put(b) } 39 | } 40 | 41 | var pool = sync.Pool{ 42 | New: func() interface{} { 43 | return &BoolStack{sp: -1} 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /lambda/instruct.go: -------------------------------------------------------------------------------- 1 | package lambda 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "reflect" 7 | "regexp" 8 | "strconv" 9 | "strings" 10 | 11 | grammar "github.com/caibirdme/yql/internal/lambda" 12 | ) 13 | 14 | type action uint8 15 | 16 | const ( 17 | 18 | // single operand 19 | _ action = iota 20 | iPush 21 | vPush 22 | iPop 23 | iNot // ! 24 | 25 | // binary operand 26 | iAdd // + 27 | iDec // - 28 | iMul // * 29 | iDiv // ÷ 30 | iMod // % 31 | iSal // << 32 | iSar // >> 33 | iBitAnd // & 34 | iBitAndOr // &^ 35 | iBitXor // ^ 36 | iBitOr // | 37 | iBt // > 38 | iLt // < 39 | 40 | iEq // == 41 | 42 | iOr // || 43 | iAnd // && 44 | 45 | // 19 actions 46 | ) 47 | 48 | type byteCode struct { 49 | ins action 50 | operand interface{} 51 | } 52 | 53 | type zVal interface{} 54 | 55 | type virtualMachine struct { 56 | instructions []byteCode 57 | pc int 58 | stack []zVal 59 | env map[string]interface{} 60 | params []string 61 | } 62 | 63 | func (vm *virtualMachine) mainLoop() error { 64 | length := len(vm.instructions) 65 | var err error 66 | vm.pc = 0 67 | for vm.pc < length { 68 | instruction := vm.instructions[vm.pc] 69 | err = vm.exec(instruction) 70 | if nil != err { 71 | return err 72 | } 73 | vm.pc++ 74 | } 75 | return nil 76 | } 77 | 78 | type variableType struct { 79 | varName string 80 | } 81 | 82 | func (vm *virtualMachine) exec(instruction byteCode) error { 83 | if instruction.ins == iPush { 84 | return zPush(vm, instruction.operand) 85 | } else if instruction.ins == vPush { 86 | varName, ok := instruction.operand.(string) 87 | if !ok { 88 | return errRuntimeErr 89 | } 90 | return variablePush(vm, varName) 91 | } 92 | return actionRuner[instruction.ins](vm) 93 | } 94 | 95 | type actionHandler func(*virtualMachine) error 96 | 97 | var actionRuner = [21]actionHandler{ 98 | iPop: zPop, 99 | iNot: zNot, 100 | iAdd: zAdd, 101 | iDec: zDec, 102 | iMul: zMul, 103 | iDiv: zDiv, 104 | iMod: zMod, 105 | iSal: zSal, 106 | iSar: zSar, 107 | iBitAnd: zBitAnd, 108 | iBitAndOr: nil, 109 | iBitXor: zBitXor, 110 | iBitOr: zBitOr, 111 | iEq: zEq, 112 | iBt: zBt, 113 | iLt: zLt, 114 | iOr: zOr, 115 | iAnd: zAnd, 116 | } 117 | 118 | func zBitAnd(vm *virtualMachine) error { 119 | top := len(vm.stack) - 1 120 | val, ok := vm.stack[top].(int) 121 | if !ok { 122 | return errors.New("operand of & must be an int") 123 | } 124 | dst, ok := vm.stack[top-1].(int) 125 | if !ok { 126 | return errors.New("operand of & must be an int") 127 | } 128 | vm.stack[top-1] = dst & val 129 | vm.stack = vm.stack[:top] 130 | return nil 131 | } 132 | 133 | func zBitAndOr(vm *virtualMachine) error { 134 | top := len(vm.stack) - 1 135 | val, ok := vm.stack[top].(int) 136 | if !ok { 137 | return errors.New("operand of | must be an int") 138 | } 139 | dst, ok := vm.stack[top-1].(int) 140 | if !ok { 141 | return errors.New("operand of | must be an int") 142 | } 143 | vm.stack[top-1] = dst &^ val 144 | vm.stack = vm.stack[:top] 145 | return nil 146 | } 147 | 148 | func zBitOr(vm *virtualMachine) error { 149 | top := len(vm.stack) - 1 150 | val, ok := vm.stack[top].(int) 151 | if !ok { 152 | return errors.New("operand of | must be an int") 153 | } 154 | dst, ok := vm.stack[top-1].(int) 155 | if !ok { 156 | return errors.New("operand of | must be an int") 157 | } 158 | vm.stack[top-1] = dst | val 159 | vm.stack = vm.stack[:top] 160 | return nil 161 | } 162 | 163 | func zBitXor(vm *virtualMachine) error { 164 | top := len(vm.stack) - 1 165 | val, ok := vm.stack[top].(int) 166 | if !ok { 167 | return errors.New("operand of ^ must be an int") 168 | } 169 | dst, ok := vm.stack[top-1].(int) 170 | if !ok { 171 | return errors.New("operand of ^ must be an int") 172 | } 173 | vm.stack[top-1] = dst ^ val 174 | vm.stack = vm.stack[:top] 175 | return nil 176 | } 177 | 178 | func zSal(vm *virtualMachine) error { 179 | top := len(vm.stack) - 1 180 | val, ok := vm.stack[top].(int) 181 | if !ok { 182 | return errors.New("operand of << must be an int") 183 | } 184 | dst, ok := vm.stack[top-1].(int) 185 | if !ok { 186 | return errors.New("operand of << must be an int") 187 | } 188 | vm.stack[top-1] = dst << uint(val) 189 | vm.stack = vm.stack[:top] 190 | return nil 191 | } 192 | 193 | func zSar(vm *virtualMachine) error { 194 | top := len(vm.stack) - 1 195 | val, ok := vm.stack[top].(int) 196 | if !ok { 197 | return errors.New("operand of << must be an int") 198 | } 199 | dst, ok := vm.stack[top-1].(int) 200 | if !ok { 201 | return errors.New("operand of << must be an int") 202 | } 203 | vm.stack[top-1] = dst >> uint(val) 204 | vm.stack = vm.stack[:top] 205 | return nil 206 | } 207 | 208 | func zPush(vm *virtualMachine, operand zVal) error { 209 | vm.stack = append(vm.stack, operand) 210 | return nil 211 | } 212 | 213 | func variablePush(vm *virtualMachine, varName string) error { 214 | val, ok := resolveVar(vm.env, varName) 215 | if !ok { 216 | return fmt.Errorf("%s not found", varName) 217 | } 218 | vm.stack = append(vm.stack, val) 219 | return nil 220 | } 221 | 222 | func resolveVar(env map[string]interface{}, varName string) (val interface{}, ok bool) { 223 | fields := strings.Split(varName, ".") 224 | val, ok = env[fields[0]] 225 | if !ok { 226 | return nil, false 227 | } 228 | nextVal := reflect.ValueOf(val) 229 | for nextVal.Type().Kind() == reflect.Ptr { 230 | nextVal = nextVal.Elem() 231 | } 232 | for _, fieldName := range fields[1:] { 233 | nextVal = nextVal.FieldByName(fieldName) 234 | if !nextVal.IsValid() { 235 | ok = false 236 | return 237 | } 238 | } 239 | val = nextVal.Interface() 240 | t, ok := val.(int64) 241 | if ok { 242 | return int(t), true 243 | } 244 | return val, true 245 | } 246 | 247 | func zPop(vm *virtualMachine) error { 248 | top := len(vm.stack) - 1 249 | vm.stack = vm.stack[:top] 250 | return nil 251 | } 252 | 253 | func zNot(vm *virtualMachine) error { 254 | top := len(vm.stack) - 1 255 | val := vm.stack[top] 256 | switch reflect.TypeOf(val).Kind() { 257 | case reflect.Bool: 258 | p := val.(bool) 259 | vm.stack[top] = !p 260 | return nil 261 | } 262 | return errOperandOfNotIsNotBool 263 | } 264 | 265 | func zAdd(vm *virtualMachine) error { 266 | top := len(vm.stack) - 1 267 | switch ra := vm.stack[top].(type) { 268 | case int: 269 | switch rb := vm.stack[top-1].(type) { 270 | case int: 271 | vm.stack[top-1] = ra + rb 272 | case float64: 273 | vm.stack[top-1] = float64(ra) + rb 274 | default: 275 | return errOperandOfNumericOperationIsNotIntOrFloat64 276 | } 277 | case float64: 278 | switch rb := vm.stack[top-1].(type) { 279 | case int: 280 | vm.stack[top-1] = ra + float64(rb) 281 | case float64: 282 | vm.stack[top-1] = ra + rb 283 | default: 284 | return errOperandOfNumericOperationIsNotIntOrFloat64 285 | } 286 | default: 287 | return errOperandOfNumericOperationIsNotIntOrFloat64 288 | } 289 | vm.stack = vm.stack[:top] 290 | return nil 291 | } 292 | 293 | func zDec(vm *virtualMachine) error { 294 | top := len(vm.stack) - 1 295 | switch ra := vm.stack[top].(type) { 296 | case int: 297 | switch rb := vm.stack[top-1].(type) { 298 | case int: 299 | vm.stack[top-1] = rb - ra 300 | case float64: 301 | vm.stack[top-1] = rb - float64(ra) 302 | default: 303 | return errOperandOfNumericOperationIsNotIntOrFloat64 304 | } 305 | case float64: 306 | switch rb := vm.stack[top-1].(type) { 307 | case int: 308 | vm.stack[top-1] = float64(rb) - ra 309 | case float64: 310 | vm.stack[top-1] = rb - ra 311 | default: 312 | return errOperandOfNumericOperationIsNotIntOrFloat64 313 | } 314 | default: 315 | return errOperandOfNumericOperationIsNotIntOrFloat64 316 | } 317 | vm.stack = vm.stack[:top] 318 | return nil 319 | } 320 | 321 | func zMul(vm *virtualMachine) error { 322 | top := len(vm.stack) - 1 323 | switch ra := vm.stack[top].(type) { 324 | case int: 325 | switch rb := vm.stack[top-1].(type) { 326 | case int: 327 | vm.stack[top-1] = ra * rb 328 | case float64: 329 | vm.stack[top-1] = float64(ra) * rb 330 | default: 331 | return errOperandOfNumericOperationIsNotIntOrFloat64 332 | } 333 | case float64: 334 | switch rb := vm.stack[top-1].(type) { 335 | case int: 336 | vm.stack[top-1] = ra * float64(rb) 337 | case float64: 338 | vm.stack[top-1] = ra * rb 339 | default: 340 | return errOperandOfNumericOperationIsNotIntOrFloat64 341 | } 342 | default: 343 | return errOperandOfNumericOperationIsNotIntOrFloat64 344 | } 345 | vm.stack = vm.stack[:top] 346 | return nil 347 | } 348 | 349 | func zDiv(vm *virtualMachine) error { 350 | top := len(vm.stack) - 1 351 | switch ra := vm.stack[top].(type) { 352 | case int: 353 | switch rb := vm.stack[top-1].(type) { 354 | case int: 355 | vm.stack[top-1] = rb / ra 356 | case float64: 357 | vm.stack[top-1] = rb / float64(ra) 358 | default: 359 | return errOperandOfNumericOperationIsNotIntOrFloat64 360 | } 361 | case float64: 362 | switch rb := vm.stack[top-1].(type) { 363 | case int: 364 | vm.stack[top-1] = float64(rb) / ra 365 | case float64: 366 | vm.stack[top-1] = rb / ra 367 | default: 368 | return errOperandOfNumericOperationIsNotIntOrFloat64 369 | } 370 | default: 371 | return errOperandOfNumericOperationIsNotIntOrFloat64 372 | } 373 | vm.stack = vm.stack[:top] 374 | return nil 375 | } 376 | 377 | func zEq(vm *virtualMachine) error { 378 | top := len(vm.stack) - 1 379 | vm.stack[top-1] = vm.stack[top-1] == vm.stack[top] 380 | vm.stack = vm.stack[:top] 381 | return nil 382 | } 383 | 384 | func zBt(vm *virtualMachine) error { 385 | top := len(vm.stack) - 1 386 | switch ra := vm.stack[top].(type) { 387 | case int: 388 | switch rb := vm.stack[top-1].(type) { 389 | case int: 390 | vm.stack[top-1] = rb > ra 391 | case float64: 392 | vm.stack[top-1] = rb > float64(ra) 393 | default: 394 | return errOperandOfNumericOperationIsNotIntOrFloat64 395 | } 396 | case float64: 397 | switch rb := vm.stack[top-1].(type) { 398 | case int: 399 | vm.stack[top-1] = float64(rb) > ra 400 | case float64: 401 | vm.stack[top-1] = rb > ra 402 | default: 403 | return errOperandOfNumericOperationIsNotIntOrFloat64 404 | } 405 | default: 406 | return errOperandOfNumericOperationIsNotIntOrFloat64 407 | } 408 | vm.stack = vm.stack[:top] 409 | return nil 410 | } 411 | 412 | func zLt(vm *virtualMachine) error { 413 | top := len(vm.stack) - 1 414 | switch ra := vm.stack[top].(type) { 415 | case int: 416 | switch rb := vm.stack[top-1].(type) { 417 | case int: 418 | vm.stack[top-1] = rb < ra 419 | case float64: 420 | vm.stack[top-1] = rb < float64(ra) 421 | default: 422 | return errOperandOfNumericOperationIsNotIntOrFloat64 423 | } 424 | case float64: 425 | switch rb := vm.stack[top-1].(type) { 426 | case int: 427 | vm.stack[top-1] = float64(rb) < ra 428 | case float64: 429 | vm.stack[top-1] = rb < ra 430 | default: 431 | return errOperandOfNumericOperationIsNotIntOrFloat64 432 | } 433 | default: 434 | return errOperandOfNumericOperationIsNotIntOrFloat64 435 | } 436 | vm.stack = vm.stack[:top] 437 | return nil 438 | } 439 | 440 | func zOr(vm *virtualMachine) error { 441 | top := len(vm.stack) - 1 442 | val := vm.stack[top] 443 | switch reflect.TypeOf(val).Kind() { 444 | case reflect.Bool: 445 | p1 := val.(bool) 446 | p2 := vm.stack[top-1].(bool) 447 | vm.stack[top-1] = p1 || p2 448 | vm.stack = vm.stack[:top] 449 | return nil 450 | } 451 | return errOperandOfOrIsNotBool 452 | } 453 | 454 | func zAnd(vm *virtualMachine) error { 455 | top := len(vm.stack) - 1 456 | val := vm.stack[top] 457 | switch reflect.TypeOf(val).Kind() { 458 | case reflect.Bool: 459 | p1 := val.(bool) 460 | p2 := vm.stack[top-1].(bool) 461 | vm.stack[top-1] = p1 && p2 462 | vm.stack = vm.stack[:top] 463 | return nil 464 | } 465 | return errOperandOfAndIsNotBool 466 | } 467 | 468 | func zMod(vm *virtualMachine) error { 469 | top := len(vm.stack) - 1 470 | val := vm.stack[top] 471 | switch reflect.TypeOf(val).Kind() { 472 | case reflect.Int: 473 | p1 := val.(int) 474 | p2 := vm.stack[top-1].(int) 475 | vm.stack[top-1] = p2 % p1 476 | default: 477 | return errOperandOfModIsNotInt 478 | } 479 | vm.stack = vm.stack[:top] 480 | return nil 481 | } 482 | 483 | var ( 484 | errOperandOfNotIsNotBool = errors.New("Operand Of Not IsNot Bool") 485 | errOperandOfAndIsNotBool = errors.New("Operand Of And IsNot Bool") 486 | errOperandOfOrIsNotBool = errors.New("Operand Of Or IsNot Bool") 487 | errOperandOfNumericOperationIsNotIntOrFloat64 = errors.New("Operand Of Numeric Operation IsNot Int Or Float64") 488 | errOperandOfModIsNotInt = errors.New("Operand Of Mod IsNot Int") 489 | ) 490 | 491 | type byteCodeListener struct { 492 | *grammar.BaseLambdaListener 493 | stack []byteCode 494 | params []string 495 | } 496 | 497 | func (l *byteCodeListener) ExitSignature(ctx *grammar.SignatureContext) { 498 | text := ctx.GetText() 499 | if text[0] == '(' { 500 | text = text[1:] 501 | } 502 | t := len(text) - 1 503 | if text[t] == ')' { 504 | text = text[:t] 505 | } 506 | for _, s := range strings.Split(text, ",") { 507 | l.params = append(l.params, strings.Trim(s, " ")) 508 | } 509 | } 510 | 511 | func (l *byteCodeListener) ExitOrExpr(ctx *grammar.OrExprContext) { 512 | l.stack = append(l.stack, byteCode{ 513 | ins: iOr, 514 | }) 515 | } 516 | 517 | func (l *byteCodeListener) ExitAndExpr(ctx *grammar.AndExprContext) { 518 | l.stack = append(l.stack, byteCode{ 519 | ins: iAnd, 520 | }) 521 | } 522 | 523 | func (l *byteCodeListener) ExitFirstExpr(ctx *grammar.FirstExprContext) { 524 | code := byteCode{} 525 | op := ctx.GetOp().GetText() 526 | switch op { 527 | case "*": 528 | code.ins = iMul 529 | case "/": 530 | code.ins = iDiv 531 | case "%": 532 | code.ins = iMod 533 | case "<<": 534 | code.ins = iSal 535 | case ">>": 536 | code.ins = iSar 537 | case "&": 538 | code.ins = iBitAnd 539 | case "&^": 540 | code.ins = iBitAndOr 541 | } 542 | l.stack = append(l.stack, code) 543 | } 544 | 545 | func (l *byteCodeListener) ExitSecondExpr(ctx *grammar.SecondExprContext) { 546 | code := byteCode{} 547 | op := ctx.GetOp().GetText() 548 | switch op { 549 | case "+": 550 | code.ins = iAdd 551 | case "-": 552 | code.ins = iDec 553 | case "|": 554 | code.ins = iBitOr 555 | case "^": 556 | code.ins = iBitXor 557 | 558 | } 559 | l.stack = append(l.stack, code) 560 | } 561 | 562 | func (l *byteCodeListener) ExitThirdExpr(ctx *grammar.ThirdExprContext) { 563 | op := ctx.GetOp().GetText() 564 | switch op { 565 | case "==": 566 | l.stack = append(l.stack, byteCode{ins: iEq}) 567 | case "!=": 568 | l.stack = append(l.stack, byteCode{ins: iEq}, byteCode{ins: iNot}) 569 | case "<": 570 | l.stack = append(l.stack, byteCode{ins: iLt}) 571 | case "<=": 572 | l.stack = append(l.stack, byteCode{ins: iBt}, byteCode{ins: iNot}) 573 | case ">": 574 | l.stack = append(l.stack, byteCode{ins: iBt}) 575 | case ">=": 576 | l.stack = append(l.stack, byteCode{ins: iLt}, byteCode{ins: iNot}) 577 | } 578 | } 579 | 580 | func (l *byteCodeListener) ExitValueExpr(ctx *grammar.ValueExprContext) { 581 | code := byteCode{ 582 | ins: iPush, 583 | } 584 | text := ctx.GetText() 585 | switch { 586 | case isIntLit(text): 587 | t, _ := strconv.ParseInt(text, 10, 64) 588 | code.operand = int(t) 589 | case isFloatLit(text): 590 | t, _ := strconv.ParseFloat(text, 64) 591 | code.operand = t 592 | case isStringLit(text): 593 | if text[0] == '`' { 594 | code.operand = strings.Trim(text, "`") 595 | } else { 596 | code.operand = strings.Trim(text, `"`) 597 | } 598 | case isBoolLit(text): 599 | t, _ := strconv.ParseBool(text) 600 | code.operand = t 601 | default: 602 | l.stack = append(l.stack, byteCode{ 603 | ins: vPush, 604 | operand: text, 605 | }) 606 | return 607 | } 608 | l.stack = append(l.stack, code) 609 | } 610 | 611 | var ( 612 | reINT = regexp.MustCompile(`^\d+$`) 613 | reFLOAT = regexp.MustCompile(`^\d+\.?\d*$`) 614 | reSTRING = regexp.MustCompile("^(`[^`]*`|\".*\")$") 615 | ) 616 | 617 | func isIntLit(text string) bool { 618 | return reINT.Match([]byte(text)) 619 | } 620 | 621 | func isFloatLit(text string) bool { 622 | return reFLOAT.Match([]byte(text)) 623 | } 624 | 625 | func isStringLit(text string) bool { 626 | return reSTRING.Match([]byte(text)) 627 | } 628 | 629 | func isBoolLit(text string) bool { 630 | return text == "true" || text == "false" 631 | } 632 | -------------------------------------------------------------------------------- /lambda/lambda.go: -------------------------------------------------------------------------------- 1 | package lambda 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "reflect" 7 | 8 | "github.com/antlr/antlr4/runtime/Go/antlr" 9 | grammar "github.com/caibirdme/yql/internal/lambda" 10 | ) 11 | 12 | type bailLexer struct { 13 | *grammar.LambdaLexer 14 | } 15 | 16 | // Override default Recover and do nothing 17 | // lexer can quit when any error occur 18 | func (l *bailLexer) Recover(r antlr.RecognitionException) { 19 | panic(r) 20 | } 21 | 22 | var ( 23 | bailErrStrategy = antlr.NewBailErrorStrategy() 24 | ) 25 | 26 | // Filter creates a new slice with all elements that 27 | // pass the test implemented by the provided function 28 | func Filter(funcStmt string) *MState { 29 | root, err := getTreeRoot(funcStmt) 30 | if nil != err { 31 | return newErrMState(err) 32 | } 33 | returnType, err := typeCheck(root) 34 | if nil != err { 35 | return newErrMState(err) 36 | } 37 | if returnType&(1<>1) 66 | for i := 0; i < length; i++ { 67 | vm.env = map[string]interface{}{ 68 | vm.params[0]: targetData.Index(i).Interface(), 69 | } 70 | for j := 1; j < len(vm.params); j++ { 71 | vm.env[vm.params[j]] = params[j] 72 | } 73 | vm.stack = vm.stack[:0] 74 | err := vm.mainLoop() 75 | if nil != err { 76 | return &result{err: err} 77 | } 78 | if len(vm.stack) < 1 { 79 | return &result{err: errRuntimeErr} 80 | } 81 | val := vm.stack[0] 82 | if reflect.TypeOf(val).Kind() != reflect.Bool { 83 | return &result{err: errResultTypeErr} 84 | } 85 | b := val.(bool) 86 | if b { 87 | res = reflect.Append(res, targetData.Index(i)) 88 | } 89 | } 90 | return &result{ 91 | data: res.Interface(), 92 | err: nil, 93 | } 94 | } 95 | 96 | var ( 97 | errRuntimeErr = errors.New("runtime error") 98 | errResultTypeErr = errors.New("result type error") 99 | ) 100 | 101 | // Syntax-Directed Translation 102 | func sdt(root antlr.Tree) (code []byteCode, params []string, err error) { 103 | walker := &byteCodeListener{ 104 | stack: make([]byteCode, 0, 5), 105 | } 106 | defer func() { 107 | if r := recover(); nil != r { 108 | err = fmt.Errorf("%+v", r) 109 | } 110 | }() 111 | antlr.ParseTreeWalkerDefault.Walk(walker, root) 112 | return walker.stack, walker.params, nil 113 | } 114 | 115 | func getTreeRoot(funcStmt string) (tree grammar.ILambdaContext, err error) { 116 | defer func() { 117 | if r := recover(); nil != r { 118 | err = fmt.Errorf("%+v", r) 119 | } 120 | }() 121 | inputStream := antlr.NewInputStream(funcStmt) 122 | lexer := &bailLexer{grammar.NewLambdaLexer(inputStream)} 123 | stream := antlr.NewCommonTokenStream(lexer, 0) 124 | parser := grammar.NewLambdaParser(stream) 125 | parser.RemoveErrorListeners() 126 | parser.SetErrorHandler(bailErrStrategy) 127 | tree = parser.Lambda() 128 | return tree, err 129 | } 130 | 131 | // Map creates a new slice with the results of calling 132 | // a provided function on every element in the calling slice 133 | func Map(funcStmt string) *MState { 134 | root, err := getTreeRoot(funcStmt) 135 | if nil != err { 136 | return newErrMState(err) 137 | } 138 | _, err = typeCheck(root) 139 | if nil != err { 140 | return newErrMState(err) 141 | } 142 | codeSegment, params, err := sdt(root) 143 | if nil != err { 144 | return newErrMState(err) 145 | } 146 | return &MState{ 147 | code: codeSegment, 148 | params: params, 149 | cb: mapRunner, 150 | } 151 | } 152 | 153 | var ( 154 | errZeroParams = &result{err: errors.New("params shouldn't be empty")} 155 | errTargetNotSlice = &result{err: errors.New("the first params should be a slice")} 156 | errEmptySlice = &result{err: errors.New("slice is empty")} 157 | ) 158 | 159 | func mapRunner(vm *virtualMachine, params ...interface{}) Result { 160 | l := len(params) 161 | if 0 == l { 162 | return errZeroParams 163 | } 164 | targetType := reflect.TypeOf(params[0]) 165 | if targetType.Kind() != reflect.Slice { 166 | return errTargetNotSlice 167 | } 168 | targetData := reflect.ValueOf(params[0]) 169 | length := targetData.Len() 170 | if 0 == length { 171 | return errEmptySlice 172 | } 173 | elementType := targetType.Elem() 174 | if elementType.Kind() == reflect.Struct { 175 | return nil 176 | } 177 | res := reflect.MakeSlice(reflect.SliceOf(elementType), 0, length) 178 | for i := 0; i < length; i++ { 179 | vm.env = map[string]interface{}{ 180 | vm.params[0]: targetData.Index(i).Interface(), 181 | } 182 | for j := 1; j < len(vm.params); j++ { 183 | vm.env[vm.params[j]] = params[j] 184 | } 185 | vm.stack = vm.stack[:0] 186 | err := vm.mainLoop() 187 | if nil != err { 188 | return &result{err: err} 189 | } 190 | if len(vm.stack) < 1 { 191 | return &result{data: nil, err: errRuntimeErr} 192 | } 193 | val := vm.stack[0] 194 | if reflect.TypeOf(val) != elementType { 195 | return &result{data: nil, err: errResultTypeErr} 196 | } 197 | res = reflect.Append(res, reflect.ValueOf(val)) 198 | } 199 | return &result{ 200 | data: res.Interface(), 201 | err: nil, 202 | } 203 | } 204 | 205 | type Result interface { 206 | Interface() (interface{}, error) 207 | } 208 | 209 | // Result store the result for a call 210 | type result struct { 211 | data interface{} 212 | err error 213 | } 214 | 215 | func (r *result) Interface() (interface{}, error) { 216 | return r.data, r.err 217 | } 218 | 219 | // MState is a middle state 220 | // It records the call stack and generates responding bytecode 221 | type MState struct { 222 | code []byteCode 223 | params []string 224 | err error 225 | cb func(*virtualMachine, ...interface{}) Result 226 | next *MState 227 | } 228 | 229 | func (m *MState) Filter(funcStmt string) *MState { 230 | if m.err != nil { 231 | return m 232 | } 233 | t := m 234 | for t.next != nil { 235 | t = t.next 236 | } 237 | newMState := Filter(funcStmt) 238 | if newMState.err != nil { 239 | return newMState 240 | } 241 | t.next = newMState 242 | return m 243 | } 244 | 245 | func (m *MState) Map(funcStmt string) *MState { 246 | if m.err != nil { 247 | return m 248 | } 249 | t := m 250 | for t.next != nil { 251 | t = t.next 252 | } 253 | newMState := Map(funcStmt) 254 | if newMState.err != nil { 255 | return newMState 256 | } 257 | t.next = newMState 258 | return m 259 | } 260 | 261 | // Call creates the context and exec the function 262 | func (m *MState) Call(params ...interface{}) Result { 263 | if m.err != nil { 264 | return &result{data: nil, err: m.err} 265 | } 266 | t := m 267 | var r Result 268 | for t != nil { 269 | vm := &virtualMachine{ 270 | instructions: t.code, 271 | params: t.params, 272 | } 273 | r = t.cb(vm, params...) 274 | newR, err := r.Interface() 275 | if nil != err { 276 | return r 277 | } 278 | params[0] = newR 279 | t = t.next 280 | } 281 | return r 282 | } 283 | 284 | func newErrMState(err error) *MState { 285 | return &MState{ 286 | err: err, 287 | } 288 | } 289 | 290 | func typeCheck(root antlr.Tree) (acceptableType uint, err error) { 291 | walker := &typeCheckListener{ 292 | stack: make([]uint, 0, 4), 293 | } 294 | defer func() { 295 | if r := recover(); nil != r { 296 | err = fmt.Errorf("%s %+v", errTypeMisMatch, r) 297 | } 298 | }() 299 | antlr.ParseTreeWalkerDefault.Walk(walker, root) 300 | if len(walker.stack) > 0 { 301 | return walker.stack[0], nil 302 | } 303 | return 0, errors.New("stack calc error") 304 | } 305 | 306 | var ( 307 | errTypeMisMatch = errors.New("type mismatch") 308 | ) 309 | 310 | type typeCheckListener struct { 311 | *grammar.BaseLambdaListener 312 | stack []uint 313 | halt bool 314 | } 315 | 316 | func (l *typeCheckListener) ExitOrExpr(ctx *grammar.OrExprContext) { 317 | top := len(l.stack) - 1 318 | t := l.stack[top] & l.stack[top-1] 319 | if t == 0 { 320 | l.halt = true 321 | panic(l.halt) 322 | } 323 | t &= 1 << reflect.Bool 324 | if t == 0 { 325 | l.halt = true 326 | panic(l.halt) 327 | } 328 | l.stack[top-1] = t 329 | l.stack = l.stack[:top] 330 | } 331 | 332 | func (l *typeCheckListener) ExitAndExpr(ctx *grammar.AndExprContext) { 333 | top := len(l.stack) - 1 334 | t := l.stack[top] & l.stack[top-1] 335 | if t == 0 { 336 | l.halt = true 337 | panic(l.halt) 338 | } 339 | t &= 1 << reflect.Bool 340 | if t == 0 { 341 | l.halt = true 342 | panic(l.halt) 343 | } 344 | l.stack[top-1] = t 345 | l.stack = l.stack[:top] 346 | } 347 | 348 | func (l *typeCheckListener) ExitFisrtExpr(ctx *grammar.FirstExprContext) { 349 | top := len(l.stack) - 1 350 | t := l.stack[top] & l.stack[top-1] 351 | if t == 0 { 352 | l.halt = true 353 | panic(l.halt) 354 | } 355 | var availableType uint 356 | availableType = 1 << reflect.Int 357 | op := ctx.GetOp().GetText() 358 | switch op { 359 | case "*", "/": 360 | availableType |= 1 << reflect.Float64 361 | } 362 | t &= availableType 363 | if t == 0 { 364 | l.halt = true 365 | panic(true) 366 | } 367 | l.stack[top-1] = t 368 | l.stack = l.stack[:top] 369 | } 370 | 371 | func (l *typeCheckListener) ExitSecondExpr(ctx *grammar.SecondExprContext) { 372 | top := len(l.stack) - 1 373 | t := l.stack[top] & l.stack[top-1] 374 | if t == 0 { 375 | l.halt = true 376 | panic(l.halt) 377 | } 378 | var availableType uint 379 | availableType = 1 << reflect.Int 380 | op := ctx.GetOp().GetText() 381 | switch op { 382 | case "+", "-": 383 | availableType |= 1 << reflect.Float64 384 | } 385 | t &= availableType 386 | if t == 0 { 387 | l.halt = true 388 | panic(true) 389 | } 390 | l.stack[top-1] = t 391 | l.stack = l.stack[:top] 392 | } 393 | 394 | func (l *typeCheckListener) ExitThirdExpr(ctx *grammar.ThirdExprContext) { 395 | top := len(l.stack) - 1 396 | t := l.stack[top] & l.stack[top-1] 397 | if t == 0 { 398 | l.halt = true 399 | panic(l.halt) 400 | } 401 | l.stack[top-1] = 1 << reflect.Bool 402 | l.stack = l.stack[:top] 403 | } 404 | 405 | func (l *typeCheckListener) ExitBasicLit(ctx *grammar.BasicLitContext) { 406 | var t uint 407 | switch { 408 | case ctx.INT_LIT() != nil: 409 | t = 1< p % 2 == 1`, 17 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 18 | expect: []int{1, 3, 5, 7}, 19 | }, 20 | { 21 | expr: `(v) => (v&1) == 1`, 22 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 23 | expect: []int{1, 3, 5, 7}, 24 | }, 25 | { 26 | expr: `(v) => v&1 == 0`, 27 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 28 | expect: []int{2, 4, 6}, 29 | }, 30 | { 31 | expr: `(v) => v+v<= 6 `, 32 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 33 | expect: []int{1, 2, 3}, 34 | }, 35 | { 36 | expr: `(v) => (v<<2)>>1 == 8`, 37 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 38 | expect: []int{4}, 39 | }, 40 | { 41 | expr: `(v) => v%2 == 0`, 42 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 43 | expect: []int{2, 4, 6}, 44 | }, 45 | { 46 | expr: `(v) => v > 5`, 47 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 48 | expect: []int{6, 7}, 49 | }, 50 | { 51 | expr: `(v) => v > 5+1`, 52 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 53 | expect: []int{7}, 54 | }, 55 | { 56 | expr: `(v) => v*2 == v+3`, 57 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 58 | expect: []int{3}, 59 | }, 60 | { 61 | expr: `(v) => v > 1+2+3/(0+1)`, 62 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 63 | expect: []int{7}, 64 | }, 65 | { 66 | expr: `(v) => v <= 1+2+3/(0+1)`, 67 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 68 | expect: []int{1, 2, 3, 4, 5, 6}, 69 | }, 70 | } 71 | ass := assert.New(t) 72 | for _, tc := range testData { 73 | mstate := Filter(tc.expr) 74 | ass.NoError(mstate.err, "%s", tc.expr) 75 | r := mstate.Call(tc.dst) 76 | inf, err := r.Interface() 77 | ass.NoError(err, "%s", tc.expr) 78 | ans, ok := inf.([]int) 79 | ass.True(ok) 80 | ass.Equal(tc.expect, ans, "expr=%s", tc.expr) 81 | } 82 | } 83 | 84 | func TestFilter_Float64(t *testing.T) { 85 | var testData = []struct { 86 | expr string 87 | dst []float64 88 | expect []float64 89 | }{ 90 | { 91 | expr: `(v) => v*2 == v+3`, 92 | dst: []float64{1, 2, 3, 4, 5, 6, 7}, 93 | expect: []float64{3}, 94 | }, 95 | { 96 | expr: `(v) => v*2 >= 5`, 97 | dst: []float64{1, 2, 3, 4, 5, 6, 7}, 98 | expect: []float64{3, 4, 5, 6, 7}, 99 | }, 100 | { 101 | expr: `(v) => v*2 >= 5+1+1`, 102 | dst: []float64{1, 2, 3, 4, 5, 6, 7}, 103 | expect: []float64{4, 5, 6, 7}, 104 | }, 105 | { 106 | expr: `(v) => v*2 >= 5+1+1*((2+1*10000)*0+1)`, 107 | dst: []float64{1, 2, 3, 4, 5, 6, 7}, 108 | expect: []float64{4, 5, 6, 7}, 109 | }, 110 | } 111 | ass := assert.New(t) 112 | for _, tc := range testData { 113 | mstate := Filter(tc.expr) 114 | ass.NoError(mstate.err, "%s", tc.expr) 115 | r := mstate.Call(tc.dst) 116 | inf, err := r.Interface() 117 | ass.NoError(err, "%s", tc.expr) 118 | ans, ok := inf.([]float64) 119 | ass.True(ok) 120 | ass.Equal(tc.expect, ans, "expr=%s", tc.expr) 121 | } 122 | } 123 | 124 | type Student struct { 125 | Age int 126 | Name string 127 | } 128 | 129 | func TestFilter_Struct(t *testing.T) { 130 | var students = []Student{ 131 | Student{ 132 | Name: "deen", 133 | Age: 24, 134 | }, 135 | Student{ 136 | Name: "bob", 137 | Age: 22, 138 | }, 139 | Student{ 140 | Name: "alice", 141 | Age: 23, 142 | }, 143 | Student{ 144 | Name: "tom", 145 | Age: 25, 146 | }, 147 | Student{ 148 | Name: "jerry", 149 | Age: 20, 150 | }, 151 | } 152 | var testData = []struct { 153 | expr string 154 | expect []int 155 | }{ 156 | { 157 | expr: `(v) => v.Age+2 > 24+1`, 158 | expect: []int{0, 3}, 159 | }, 160 | { 161 | expr: `(v) => v.Age >= 23`, 162 | expect: []int{0, 2, 3}, 163 | }, 164 | { 165 | expr: `(v) => v.Age < 23`, 166 | expect: []int{1, 4}, 167 | }, 168 | { 169 | expr: `(v) => v.Age < 23 || v.Name == "tom"`, 170 | expect: []int{1, 3, 4}, 171 | }, 172 | } 173 | ass := assert.New(t) 174 | for _, tc := range testData { 175 | mstate := Filter(tc.expr) 176 | ass.NoError(mstate.err, "%s", tc.expr) 177 | r := mstate.Call(students) 178 | inf, err := r.Interface() 179 | ass.NoError(err, "%s", tc.expr) 180 | ans, ok := inf.([]Student) 181 | ass.True(ok) 182 | var expectArr []Student 183 | for _, idx := range tc.expect { 184 | expectArr = append(expectArr, students[idx]) 185 | } 186 | ass.Equal(expectArr, ans, "expr=%s", tc.expr) 187 | } 188 | } 189 | 190 | func TestFilter_Pointer(t *testing.T) { 191 | var students = []*Student{ 192 | &Student{ 193 | Name: "deen", 194 | Age: 24, 195 | }, 196 | &Student{ 197 | Name: "bob", 198 | Age: 22, 199 | }, 200 | &Student{ 201 | Name: "alice", 202 | Age: 23, 203 | }, 204 | &Student{ 205 | Name: "tom", 206 | Age: 25, 207 | }, 208 | &Student{ 209 | Name: "jerry", 210 | Age: 20, 211 | }, 212 | } 213 | var testData = []struct { 214 | expr string 215 | expect []int 216 | }{ 217 | { 218 | expr: `(v) => v.Age+2 > 24+1`, 219 | expect: []int{0, 3}, 220 | }, 221 | { 222 | expr: `(v) => v.Age >= 23`, 223 | expect: []int{0, 2, 3}, 224 | }, 225 | { 226 | expr: `(v) => v.Age < 23`, 227 | expect: []int{1, 4}, 228 | }, 229 | } 230 | ass := assert.New(t) 231 | for _, tc := range testData { 232 | mstate := Filter(tc.expr) 233 | ass.NoError(mstate.err, "%s", tc.expr) 234 | r := mstate.Call(students) 235 | inf, err := r.Interface() 236 | ass.NoError(err, "%s", tc.expr) 237 | ans, ok := inf.([]*Student) 238 | ass.True(ok) 239 | var expectArr []*Student 240 | for _, idx := range tc.expect { 241 | expectArr = append(expectArr, students[idx]) 242 | } 243 | ass.Equal(expectArr, ans, "expr=%s", tc.expr) 244 | } 245 | } 246 | 247 | func TestMap_Int(t *testing.T) { 248 | var testData = []struct { 249 | expr string 250 | dst []int 251 | expect []int 252 | }{ 253 | { 254 | expr: `(p) => p +1`, 255 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 256 | expect: []int{2, 3, 4, 5, 6, 7, 8}, 257 | }, 258 | { 259 | expr: `(v) => v & 1`, 260 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 261 | expect: []int{1, 0, 1, 0, 1, 0, 1}, 262 | }, 263 | { 264 | expr: `(v) => v | 1`, 265 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 266 | expect: []int{1, 3, 3, 5, 5, 7, 7}, 267 | }, 268 | { 269 | expr: `(v) => (v - 1)*3`, 270 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 271 | expect: []int{0, 3, 6, 9, 12, 15, 18}, 272 | }, 273 | } 274 | ass := assert.New(t) 275 | for _, tc := range testData { 276 | mstate := Map(tc.expr) 277 | ass.NoError(mstate.err, "%s", tc.expr) 278 | r := mstate.Call(tc.dst) 279 | inf, err := r.Interface() 280 | ass.NoError(err, "%s", tc.expr) 281 | ans, ok := inf.([]int) 282 | ass.True(ok) 283 | ass.Equal(tc.expect, ans, "expr=%s", tc.expr) 284 | } 285 | } 286 | 287 | func TestChainable(t *testing.T) { 288 | var testData = []struct { 289 | m string 290 | f string 291 | dst []int 292 | expect []int 293 | }{ 294 | { 295 | m: `(p) => p +1`, 296 | f: `(v) => v&1==1`, 297 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 298 | expect: []int{2, 4, 6, 8}, 299 | }, 300 | { 301 | m: `(v) => v << 2`, 302 | f: `(v) => v > 3 && v <= 7`, 303 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 304 | expect: []int{16, 20, 24, 28}, 305 | }, 306 | { 307 | m: `(v) => (v - 1)*3`, 308 | f: `(v) => v<4`, 309 | dst: []int{1, 2, 3, 4, 5, 6, 7}, 310 | expect: []int{0, 3, 6}, 311 | }, 312 | } 313 | ass := assert.New(t) 314 | for _, tc := range testData { 315 | mstate := Filter(tc.f).Map(tc.m) 316 | ass.NoError(mstate.err, "filter:%s\r\nmap:%s\r\n", tc.f, tc.m) 317 | r := mstate.Call(tc.dst) 318 | inf, err := r.Interface() 319 | ass.NoError(err) 320 | ass.NoError(mstate.err, "filter:%s\r\nmap:%s\r\n", tc.f, tc.m) 321 | ans, ok := inf.([]int) 322 | ass.True(ok) 323 | ass.Equal(tc.expect, ans, "filter:%s\r\nmap:%s\r\n", tc.f, tc.m) 324 | } 325 | } 326 | 327 | func TestThreeChain(t *testing.T) { 328 | scores := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 329 | // syntax error 330 | r := Filter(`(v) => v % 2 == 0`).Map(`v => v*v`).Call(scores) 331 | s, err := r.Interface() 332 | ass := assert.New(t) 333 | ass.Error(err) 334 | dst := []int{1, 2, 3, 4, 5, 6, 7} 335 | r = Filter(`(v) => v > 3 && v <= 7`).Map(`(v) => v << 2`).Filter(`(v) => v % 8 == 0`).Call(dst) 336 | s, err = r.Interface() 337 | ass.NoError(err) 338 | ass.Equal([]int{16, 24}, s) 339 | } 340 | -------------------------------------------------------------------------------- /yql.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "strconv" 7 | 8 | "github.com/antlr/antlr4/runtime/Go/antlr" 9 | "github.com/caibirdme/yql/internal/grammar" 10 | "github.com/caibirdme/yql/internal/stack" 11 | ) 12 | 13 | type boolStack interface { 14 | Push(bool) 15 | Pop() bool 16 | } 17 | 18 | type yqlListener struct { 19 | *grammar.BaseYqlListener 20 | stack boolStack 21 | data map[string]interface{} 22 | fieldName string 23 | funcs []string 24 | notFoundErr error 25 | } 26 | 27 | func (l *yqlListener) ExitBooleanExpr(ctx *grammar.BooleanExprContext) { 28 | if l.notFoundErr != nil { 29 | return 30 | } 31 | operator := ctx.GetOp().GetText() 32 | fieldName := l.fieldName 33 | actualValue, ok := l.data[fieldName] 34 | if !ok { 35 | l.notFoundErr = fmt.Errorf("%s not provided", fieldName) 36 | return 37 | } 38 | var err error 39 | actualValue, err = funcRuner(actualValue, l.funcs) 40 | if err != nil { 41 | l.notFoundErr = err 42 | return 43 | } 44 | allValue := ctx.AllValue() 45 | valueArr := make([]string, 0, len(allValue)) 46 | for _, v := range allValue { 47 | valueArr = append(valueArr, v.GetText()) 48 | } 49 | res := compare(actualValue, valueArr, operator) 50 | l.stack.Push(res) 51 | } 52 | 53 | func (l *yqlListener) ExitLeftexpr(ctx *grammar.LeftexprContext) { 54 | l.fieldName = ctx.FIELDNAME().GetText() 55 | funcs := ctx.AllFUNC() 56 | l.funcs = l.funcs[:0] 57 | if 0 == len(funcs) { 58 | return 59 | } 60 | for _, f := range funcs { 61 | l.funcs = append(l.funcs, f.GetText()) 62 | } 63 | } 64 | 65 | func (l *yqlListener) ExitOrExpr(ctx *grammar.OrExprContext) { 66 | if l.notFoundErr != nil { 67 | return 68 | } 69 | q1 := l.stack.Pop() 70 | q2 := l.stack.Pop() 71 | l.stack.Push(q1 || q2) 72 | } 73 | 74 | func (l *yqlListener) ExitAndExpr(ctx *grammar.AndExprContext) { 75 | if l.notFoundErr != nil { 76 | return 77 | } 78 | q1 := l.stack.Pop() 79 | q2 := l.stack.Pop() 80 | l.stack.Push(q1 && q2) 81 | } 82 | 83 | type bailLexer struct { 84 | *grammar.YqlLexer 85 | } 86 | 87 | // Override default Recover and do nothing 88 | // lexer can quit when any error occur 89 | func (l *bailLexer) Recover(r antlr.RecognitionException) { 90 | panic(r) 91 | } 92 | 93 | var ( 94 | bailErrStrategy = antlr.NewBailErrorStrategy() 95 | ) 96 | 97 | func match(rawYQL string, data map[string]interface{}) (ok bool, err error) { 98 | if 0 == len(data) { 99 | return false, nil 100 | } 101 | defer func() { 102 | if r := recover(); nil != r { 103 | ok = false 104 | err = fmt.Errorf("%v", r) 105 | } 106 | }() 107 | inputStream := antlr.NewInputStream(rawYQL) 108 | lexer := &bailLexer{grammar.NewYqlLexer(inputStream)} 109 | stream := antlr.NewCommonTokenStream(lexer, 0) 110 | parser := grammar.NewYqlParser(stream) 111 | parser.BuildParseTrees = true 112 | parser.RemoveErrorListeners() 113 | parser.SetErrorHandler(bailErrStrategy) 114 | tree := parser.Query() 115 | s, release := stack.NewStack() 116 | defer release() 117 | l := &yqlListener{stack: s, funcs: make([]string, 0, 1)} 118 | l.data = data 119 | antlr.ParseTreeWalkerDefault.Walk(l, tree) 120 | if l.notFoundErr != nil { 121 | return false, l.notFoundErr 122 | } 123 | return l.stack.Pop(), nil 124 | } 125 | 126 | // Ruler caches an AST 127 | type cachedAST struct { 128 | query grammar.IQueryContext 129 | } 130 | 131 | // Ruler represents an AST structure and could do the match according to input data 132 | type Ruler interface { 133 | Match(map[string]interface{}) (bool, error) 134 | } 135 | 136 | // Match do the comparison according to the input data 137 | func (ast cachedAST) Match(data map[string]interface{}) (bool, error) { 138 | if 0 == len(data) { 139 | return false, nil 140 | } 141 | s, release := stack.NewStack() 142 | defer release() 143 | l := &yqlListener{stack: s, funcs: make([]string, 0, 1)} 144 | l.data = data 145 | antlr.ParseTreeWalkerDefault.Walk(l, ast.query) 146 | if l.notFoundErr != nil { 147 | return false, l.notFoundErr 148 | } 149 | return l.stack.Pop(), nil 150 | } 151 | 152 | // Rule analyze a rule and store the AST 153 | // it returns error when receives illegal yql expression 154 | // It's more faster than using Match directly 155 | func Rule(rawYQL string) (ruler Ruler, err error) { 156 | ast := cachedAST{} 157 | defer func() { 158 | if r := recover(); nil != r { 159 | err = fmt.Errorf("%v", r) 160 | ruler = ast 161 | } 162 | }() 163 | inputStream := antlr.NewInputStream(rawYQL) 164 | lexer := &bailLexer{grammar.NewYqlLexer(inputStream)} 165 | stream := antlr.NewCommonTokenStream(lexer, 0) 166 | parser := grammar.NewYqlParser(stream) 167 | parser.BuildParseTrees = true 168 | parser.RemoveErrorListeners() 169 | parser.SetErrorHandler(bailErrStrategy) 170 | ast.query = parser.Query() 171 | return ast, nil 172 | } 173 | 174 | // Match interprete the rawYQL and execute it with the provided data 175 | // error will be returned if rawYQL contains illegal syntax 176 | func Match(rawYQL string, data map[string]interface{}) (bool, error) { 177 | return match(rawYQL, data) 178 | } 179 | 180 | func compare(actualValue interface{}, expectValue []string, op string) bool { 181 | if len(expectValue) > 1 { 182 | return compareSet(actualValue, expectValue, op) 183 | } 184 | if reflect.TypeOf(actualValue).Kind() == reflect.Slice { 185 | return compareSet(actualValue, expectValue, op) 186 | } 187 | e := removeQuote(expectValue[0]) 188 | switch actual := actualValue.(type) { 189 | case int: 190 | expect, err := strconv.ParseInt(e, 10, 64) 191 | if nil != err { 192 | return false 193 | } 194 | return cmpInt(int64(actual), expect, op) 195 | case int64: 196 | expect, err := strconv.ParseInt(e, 10, 64) 197 | if nil != err { 198 | return false 199 | } 200 | return cmpInt(actual, expect, op) 201 | case float64: 202 | expect, err := strconv.ParseFloat(e, 64) 203 | if nil != err { 204 | return false 205 | } 206 | return cmpFloat(actual, expect, op) 207 | case string: 208 | return cmpStr(actual, e, op) 209 | case bool: 210 | expect, err := strconv.ParseBool(e) 211 | if nil != err { 212 | return false 213 | } 214 | return cmpBool(actual, expect, op) 215 | default: 216 | return false 217 | } 218 | } 219 | 220 | func removeQuote(str string) string { 221 | l := 0 222 | r := len(str) 223 | if str[0] == '\'' { 224 | l++ 225 | } 226 | if str[r-1] == '\'' { 227 | r-- 228 | } 229 | return str[l:r] 230 | } 231 | -------------------------------------------------------------------------------- /yql_test.go: -------------------------------------------------------------------------------- 1 | package yql 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestHandleSyntaxErr(t *testing.T) { 11 | var testData = []string{ 12 | "asdasdasd", 13 | "((a=1", 14 | "((a='foo'", 15 | "((a='foo')", 16 | "a=foo", 17 | "a in (foo,bar)", 18 | "a in (foo)", 19 | "a ∩ (foo)", 20 | "a != foo", 21 | } 22 | data := map[string]interface{}{ 23 | "a": "foo", 24 | } 25 | ass := assert.New(t) 26 | for _, tc := range testData { 27 | ok, err := Match(tc, data) 28 | ass.False(ok) 29 | ass.Error(err) 30 | } 31 | } 32 | 33 | func TestMatch_Int(t *testing.T) { 34 | var testData = []struct { 35 | rawYql string 36 | data map[string]interface{} 37 | out bool 38 | }{ 39 | { 40 | rawYql: `a=10`, 41 | data: map[string]interface{}{ 42 | "a": 9, 43 | }, 44 | out: false, 45 | }, 46 | { 47 | rawYql: `a=10`, 48 | data: map[string]interface{}{ 49 | "a": 10, 50 | }, 51 | out: true, 52 | }, 53 | { 54 | rawYql: `a>10`, 55 | data: map[string]interface{}{ 56 | "a": 10, 57 | }, 58 | out: false, 59 | }, 60 | { 61 | rawYql: `a>10`, 62 | data: map[string]interface{}{ 63 | "a": 11, 64 | }, 65 | out: true, 66 | }, 67 | { 68 | rawYql: `a>=10`, 69 | data: map[string]interface{}{ 70 | "a": 10, 71 | }, 72 | out: true, 73 | }, 74 | { 75 | rawYql: `a>=10`, 76 | data: map[string]interface{}{ 77 | "a": 11, 78 | }, 79 | out: true, 80 | }, 81 | { 82 | rawYql: `a>=10`, 83 | data: map[string]interface{}{ 84 | "a": 1, 85 | }, 86 | out: false, 87 | }, 88 | { 89 | rawYql: `a<10`, 90 | data: map[string]interface{}{ 91 | "a": 1, 92 | }, 93 | out: true, 94 | }, 95 | { 96 | rawYql: `a<10`, 97 | data: map[string]interface{}{ 98 | "a": 10, 99 | }, 100 | out: false, 101 | }, 102 | { 103 | rawYql: `a<10`, 104 | data: map[string]interface{}{ 105 | "a": 11, 106 | }, 107 | out: false, 108 | }, 109 | } 110 | ass := assert.New(t) 111 | for _, tc := range testData { 112 | ok, err := Match(tc.rawYql, tc.data) 113 | ass.NoError(err) 114 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 115 | } 116 | } 117 | 118 | func TestMatch_Int64(t *testing.T) { 119 | var testData = []struct { 120 | rawYql string 121 | data map[string]interface{} 122 | out bool 123 | }{ 124 | { 125 | rawYql: `a=10`, 126 | data: map[string]interface{}{ 127 | "a": int64(9), 128 | }, 129 | out: false, 130 | }, 131 | { 132 | rawYql: `a=10`, 133 | data: map[string]interface{}{ 134 | "a": int64(10), 135 | }, 136 | out: true, 137 | }, 138 | { 139 | rawYql: `a>10`, 140 | data: map[string]interface{}{ 141 | "a": int64(10), 142 | }, 143 | out: false, 144 | }, 145 | { 146 | rawYql: `a>10`, 147 | data: map[string]interface{}{ 148 | "a": int64(11), 149 | }, 150 | out: true, 151 | }, 152 | { 153 | rawYql: `a>=10`, 154 | data: map[string]interface{}{ 155 | "a": int64(10), 156 | }, 157 | out: true, 158 | }, 159 | { 160 | rawYql: `a>=10`, 161 | data: map[string]interface{}{ 162 | "a": int64(11), 163 | }, 164 | out: true, 165 | }, 166 | { 167 | rawYql: `a>=10`, 168 | data: map[string]interface{}{ 169 | "a": int64(1), 170 | }, 171 | out: false, 172 | }, 173 | { 174 | rawYql: `a<10`, 175 | data: map[string]interface{}{ 176 | "a": int64(1), 177 | }, 178 | out: true, 179 | }, 180 | { 181 | rawYql: `a<10`, 182 | data: map[string]interface{}{ 183 | "a": int64(10), 184 | }, 185 | out: false, 186 | }, 187 | { 188 | rawYql: `a<10`, 189 | data: map[string]interface{}{ 190 | "a": int64(11), 191 | }, 192 | out: false, 193 | }, 194 | } 195 | ass := assert.New(t) 196 | for _, tc := range testData { 197 | ok, err := Match(tc.rawYql, tc.data) 198 | ass.NoError(err) 199 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 200 | } 201 | } 202 | 203 | func TestMatch_String(t *testing.T) { 204 | var testData = []struct { 205 | rawYql string 206 | data map[string]interface{} 207 | out bool 208 | }{ 209 | { 210 | rawYql: `a=10`, 211 | data: map[string]interface{}{ 212 | "a": "10", 213 | }, 214 | out: true, 215 | }, 216 | { 217 | rawYql: `a=10`, 218 | data: map[string]interface{}{ 219 | "a": "010", 220 | }, 221 | out: false, 222 | }, 223 | { 224 | rawYql: `a=10`, 225 | data: map[string]interface{}{ 226 | "a": "", 227 | }, 228 | out: false, 229 | }, 230 | { 231 | rawYql: `a>1`, 232 | data: map[string]interface{}{ 233 | "a": "1", 234 | }, 235 | out: false, 236 | }, 237 | { 238 | rawYql: `a>1`, 239 | data: map[string]interface{}{ 240 | "a": "2", 241 | }, 242 | out: true, 243 | }, 244 | { 245 | rawYql: `a>=1`, 246 | data: map[string]interface{}{ 247 | "a": "1", 248 | }, 249 | out: true, 250 | }, 251 | { 252 | rawYql: `a>=1`, 253 | data: map[string]interface{}{ 254 | "a": "2", 255 | }, 256 | out: true, 257 | }, 258 | { 259 | rawYql: `a>=1`, 260 | data: map[string]interface{}{ 261 | "a": "", 262 | }, 263 | out: false, 264 | }, 265 | { 266 | rawYql: `a>20`, 267 | data: map[string]interface{}{ 268 | "a": "21", 269 | }, 270 | out: true, 271 | }, 272 | { 273 | rawYql: `a>20`, 274 | data: map[string]interface{}{ 275 | "a": "3", 276 | }, 277 | out: true, 278 | }, 279 | { 280 | rawYql: `a>20`, 281 | data: map[string]interface{}{ 282 | "a": "1", 283 | }, 284 | out: false, 285 | }, 286 | { 287 | rawYql: `a!=20`, 288 | data: map[string]interface{}{ 289 | "a": "3", 290 | }, 291 | out: true, 292 | }, 293 | { 294 | rawYql: `a!=20`, 295 | data: map[string]interface{}{ 296 | "a": "20", 297 | }, 298 | out: false, 299 | }, 300 | } 301 | ass := assert.New(t) 302 | for _, tc := range testData { 303 | ok, err := Match(tc.rawYql, tc.data) 304 | ass.NoError(err) 305 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 306 | } 307 | } 308 | 309 | func TestMatch__Float(t *testing.T) { 310 | var testData = []struct { 311 | rawYql string 312 | data map[string]interface{} 313 | out bool 314 | }{ 315 | { 316 | rawYql: `a=10`, 317 | data: map[string]interface{}{ 318 | "a": float64(10), 319 | }, 320 | out: true, 321 | }, 322 | { 323 | rawYql: `a=10`, 324 | data: map[string]interface{}{ 325 | "a": float64(10 - epsilon*0.1), 326 | }, 327 | out: true, 328 | }, 329 | { 330 | rawYql: `a!=10`, 331 | data: map[string]interface{}{ 332 | "a": float64(10), 333 | }, 334 | out: false, 335 | }, 336 | { 337 | rawYql: `a>10`, 338 | data: map[string]interface{}{ 339 | "a": float64(10), 340 | }, 341 | out: false, 342 | }, 343 | { 344 | rawYql: `a>10`, 345 | data: map[string]interface{}{ 346 | "a": float64(10.000000001), 347 | }, 348 | out: true, 349 | }, 350 | { 351 | rawYql: `a<10`, 352 | data: map[string]interface{}{ 353 | "a": float64(10 - epsilon*0.1), 354 | }, 355 | out: true, 356 | }, 357 | { 358 | rawYql: `a>=10`, 359 | data: map[string]interface{}{ 360 | "a": float64(10.0), 361 | }, 362 | out: true, 363 | }, 364 | { 365 | rawYql: `a>=10`, 366 | data: map[string]interface{}{ 367 | "a": float64(9.0), 368 | }, 369 | out: false, 370 | }, 371 | { 372 | rawYql: `a<=10`, 373 | data: map[string]interface{}{ 374 | "a": float64(10.0), 375 | }, 376 | out: true, 377 | }, 378 | { 379 | rawYql: `a<=10`, 380 | data: map[string]interface{}{ 381 | "a": float64(9.0), 382 | }, 383 | out: true, 384 | }, 385 | { 386 | rawYql: `a<=10`, 387 | data: map[string]interface{}{ 388 | "a": float64(11.0), 389 | }, 390 | out: false, 391 | }, 392 | } 393 | ass := assert.New(t) 394 | for _, tc := range testData { 395 | ok, _ := Match(tc.rawYql, tc.data) 396 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 397 | } 398 | } 399 | 400 | func TestMatch_Boolean(t *testing.T) { 401 | // comparison between booleans only support =,!= 402 | var testData = []struct { 403 | rawYql string 404 | data map[string]interface{} 405 | out bool 406 | }{ 407 | { 408 | rawYql: `a=true`, 409 | data: map[string]interface{}{ 410 | "a": true, 411 | }, 412 | out: true, 413 | }, 414 | { 415 | rawYql: `a=true`, 416 | data: map[string]interface{}{ 417 | "a": false, 418 | }, 419 | out: false, 420 | }, 421 | { 422 | rawYql: `a=false`, 423 | data: map[string]interface{}{ 424 | "a": true, 425 | }, 426 | out: false, 427 | }, 428 | { 429 | rawYql: `a=false`, 430 | data: map[string]interface{}{ 431 | "a": false, 432 | }, 433 | out: true, 434 | }, 435 | { 436 | rawYql: `a!=false`, 437 | data: map[string]interface{}{ 438 | "a": true, 439 | }, 440 | out: true, 441 | }, 442 | { 443 | rawYql: `a>false`, 444 | data: map[string]interface{}{ 445 | "a": true, 446 | }, 447 | out: false, 448 | }, 449 | { 450 | rawYql: `a<=false`, 451 | data: map[string]interface{}{ 452 | "a": true, 453 | }, 454 | out: false, 455 | }, 456 | } 457 | ass := assert.New(t) 458 | for _, tc := range testData { 459 | ok, err := Match(tc.rawYql, tc.data) 460 | ass.NoError(err) 461 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 462 | } 463 | } 464 | 465 | func TestMatch_In(t *testing.T) { 466 | var testData = []struct { 467 | rawYql string 468 | data map[string]interface{} 469 | out bool 470 | }{ 471 | { 472 | rawYql: `a in ('swim')`, 473 | data: map[string]interface{}{ 474 | "a": "swim", 475 | }, 476 | out: true, 477 | }, 478 | { 479 | rawYql: `a in ('soccer')`, 480 | data: map[string]interface{}{ 481 | "a": "swim", 482 | }, 483 | out: false, 484 | }, 485 | { 486 | rawYql: `a !in ('swim')`, 487 | data: map[string]interface{}{ 488 | "a": "swim", 489 | }, 490 | out: false, 491 | }, 492 | { 493 | rawYql: `a !in ('soccer')`, 494 | data: map[string]interface{}{ 495 | "a": "swim", 496 | }, 497 | out: true, 498 | }, 499 | { 500 | rawYql: `a !in (1,2,3)`, 501 | data: map[string]interface{}{ 502 | "a": 1, 503 | }, 504 | out: false, 505 | }, 506 | { 507 | rawYql: `a in (1,2,3)`, 508 | data: map[string]interface{}{ 509 | "a": 3, 510 | }, 511 | out: true, 512 | }, 513 | { 514 | rawYql: `a in (1,5,9)`, 515 | data: map[string]interface{}{ 516 | "a": 5, 517 | }, 518 | out: true, 519 | }, 520 | { 521 | rawYql: `a !in (1,2, 10, 5)`, 522 | data: map[string]interface{}{ 523 | "a": int64(9), 524 | }, 525 | out: true, 526 | }, 527 | { 528 | rawYql: `a !in (1,2, 10, 5)`, 529 | data: map[string]interface{}{ 530 | "a": 9, 531 | }, 532 | out: true, 533 | }, 534 | { 535 | rawYql: `a in (1,2, 10, 5)`, 536 | data: map[string]interface{}{ 537 | "a": 10, 538 | }, 539 | out: true, 540 | }, 541 | { 542 | rawYql: `a in (1,2, 10, 5)`, 543 | data: map[string]interface{}{ 544 | "a": []int{10, 2}, 545 | }, 546 | out: true, 547 | }, 548 | { 549 | rawYql: `a in (1,2, 10, 5)`, 550 | data: map[string]interface{}{ 551 | "a": []string{"1", "5"}, 552 | }, 553 | out: true, 554 | }, 555 | { 556 | rawYql: `a !in (1,2, 10, 5)`, 557 | data: map[string]interface{}{ 558 | "a": []string{"1", "5"}, 559 | }, 560 | out: false, 561 | }, 562 | { 563 | rawYql: `a !in (1,2, 10, 5)`, 564 | data: map[string]interface{}{ 565 | "a": "1", 566 | }, 567 | out: false, 568 | }, 569 | { 570 | rawYql: `a !in (1,2, 10, 5)`, 571 | data: map[string]interface{}{ 572 | "a": []string{"1", "5", "3"}, 573 | }, 574 | out: true, 575 | }, 576 | { 577 | rawYql: `a in (1,2, 10, 5)`, 578 | data: map[string]interface{}{ 579 | "a": []int64{1, 5}, 580 | }, 581 | out: true, 582 | }, 583 | { 584 | rawYql: `a in (1,2, 10.000, 5.000)`, 585 | data: map[string]interface{}{ 586 | "a": []float64{2.000000000000001, 5.000000000000000002}, 587 | }, 588 | out: true, 589 | }, 590 | { 591 | rawYql: `a in (1,2,3, 10.00000000001)`, 592 | data: map[string]interface{}{ 593 | "a": float64(10.0), 594 | }, 595 | out: true, 596 | }, 597 | { 598 | rawYql: `a !in (1,2,3, 10.00001)`, 599 | data: map[string]interface{}{ 600 | "a": float64(10.0), 601 | }, 602 | out: true, 603 | }, 604 | { 605 | rawYql: `a in (1,2, 10)`, 606 | data: map[string]interface{}{ 607 | "a": []int64{2, 3}, 608 | }, 609 | out: false, 610 | }, 611 | { 612 | rawYql: `a in (1,2,3, 10)`, 613 | data: map[string]interface{}{ 614 | "a": int64(10), 615 | }, 616 | out: true, 617 | }, 618 | { 619 | rawYql: `a in (1,2,3, 10)`, 620 | data: map[string]interface{}{ 621 | "a": []int64{2, 3}, 622 | }, 623 | out: true, 624 | }, 625 | { 626 | rawYql: `a in (1,2, 10)`, 627 | data: map[string]interface{}{ 628 | "a": []int64{2, 3}, 629 | }, 630 | out: false, 631 | }, 632 | { 633 | rawYql: `a in (1,2, 10, 5)`, 634 | data: map[string]interface{}{ 635 | "a": []float64{2, 5}, 636 | }, 637 | out: true, 638 | }, 639 | { 640 | rawYql: `a in (1,2, 10, 5)`, 641 | data: map[string]interface{}{ 642 | "a": []float64{1, 10, 2, 5}, 643 | }, 644 | out: true, 645 | }, 646 | { 647 | rawYql: `a in (1,2, 10, 5)`, 648 | data: map[string]interface{}{ 649 | "a": []float64{1, 10, 2, 5, 3}, 650 | }, 651 | out: false, 652 | }, 653 | { 654 | rawYql: `a in (1,2, 10, 5)`, 655 | data: map[string]interface{}{ 656 | "a": []string{"1", "5"}, 657 | }, 658 | out: true, 659 | }, 660 | } 661 | ass := assert.New(t) 662 | for _, tc := range testData { 663 | ok, _ := Match(tc.rawYql, tc.data) 664 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 665 | } 666 | } 667 | 668 | func TestMatch_And(t *testing.T) { 669 | var testData = []struct { 670 | rawYql string 671 | data map[string]interface{} 672 | out bool 673 | }{ 674 | { 675 | rawYql: `a=10 and b>'2' and c<9 and d!=2`, 676 | data: map[string]interface{}{ 677 | "a": int64(10), 678 | "b": int64(3), 679 | "c": int64(-1), 680 | "d": int64(2), 681 | }, 682 | out: false, 683 | }, 684 | { 685 | rawYql: `a=10 and b>'2' and c<9 and d!=2`, 686 | data: map[string]interface{}{ 687 | "a": int64(10), 688 | "b": int64(3), 689 | "c": int64(-1), 690 | }, 691 | out: false, 692 | }, 693 | { 694 | rawYql: `a=10 and b>'2'`, 695 | data: map[string]interface{}{ 696 | "a": int64(10), 697 | "b": int64(3), 698 | }, 699 | out: true, 700 | }, 701 | { 702 | rawYql: `a=10 and b>'2'`, 703 | data: map[string]interface{}{ 704 | "a": int64(10), 705 | "b": int64(2), 706 | }, 707 | out: false, 708 | }, 709 | { 710 | rawYql: `a=10 and b>'2'`, 711 | data: map[string]interface{}{ 712 | "a": int64(10), 713 | "b": int64(3), 714 | }, 715 | out: true, 716 | }, 717 | { 718 | rawYql: `a=10 and b>'2' and c<9`, 719 | data: map[string]interface{}{ 720 | "a": int64(10), 721 | "b": int64(3), 722 | "c": int64(-1), 723 | }, 724 | out: true, 725 | }, 726 | { 727 | rawYql: `a=10 and b>'2' and c<9 and d!=2`, 728 | data: map[string]interface{}{ 729 | "a": int64(10), 730 | "b": int64(3), 731 | "c": int64(-1), 732 | "d": int64(0), 733 | }, 734 | out: true, 735 | }, 736 | } 737 | ass := assert.New(t) 738 | for _, tc := range testData { 739 | ok, _ := Match(tc.rawYql, tc.data) 740 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 741 | } 742 | } 743 | 744 | func TestMatch_Or(t *testing.T) { 745 | var testData = []struct { 746 | rawYql string 747 | data map[string]interface{} 748 | out bool 749 | }{ 750 | { 751 | rawYql: `a=10 or b>'2'`, 752 | data: map[string]interface{}{ 753 | "a": int64(10), 754 | "b": int64(1), 755 | }, 756 | out: true, 757 | }, 758 | { 759 | rawYql: `a=10 or b>'2'`, 760 | data: map[string]interface{}{ 761 | "a": int64(9), 762 | "b": int64(2), 763 | }, 764 | out: false, 765 | }, 766 | { 767 | rawYql: `a=10 or b>'2'`, 768 | data: map[string]interface{}{ 769 | "a": int64(10), 770 | "b": int64(3), 771 | }, 772 | out: true, 773 | }, 774 | { 775 | rawYql: `a=10 or b>'2' or c<9`, 776 | data: map[string]interface{}{ 777 | "a": int64(1), 778 | "b": int64(3), 779 | "c": int64(100), 780 | }, 781 | out: true, 782 | }, 783 | { 784 | rawYql: `a=10 or b>'2' or c<9 or d!=2`, 785 | data: map[string]interface{}{ 786 | "a": int64(1), 787 | "b": int64(2), 788 | "c": int64(10), 789 | "d": int64(0), 790 | }, 791 | out: true, 792 | }, 793 | { 794 | rawYql: `a=10 or b>'2' or c<9 or d!=2`, 795 | data: map[string]interface{}{ 796 | "a": int64(1), 797 | "b": int64(1), 798 | "c": int64(10), 799 | "d": int64(2), 800 | }, 801 | out: false, 802 | }, 803 | } 804 | ass := assert.New(t) 805 | for _, tc := range testData { 806 | ok, err := Match(tc.rawYql, tc.data) 807 | ass.NoError(err) 808 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 809 | } 810 | } 811 | 812 | func TestMatch_Or_And(t *testing.T) { 813 | var testData = []struct { 814 | rawYql string 815 | data map[string]interface{} 816 | out bool 817 | }{ 818 | { 819 | rawYql: `a=9 or c=1 and b!='1'`, 820 | data: map[string]interface{}{ 821 | "a": int64(10), 822 | "b": int64(1), 823 | "c": int64(1), 824 | }, 825 | out: false, 826 | }, 827 | { 828 | rawYql: `a=10 and b>'2' or c=1`, 829 | data: map[string]interface{}{ 830 | "a": int64(10), 831 | "b": int64(1), 832 | "c": int64(1), 833 | }, 834 | out: true, 835 | }, 836 | { 837 | rawYql: `a=10 or c=1 and b!='1'`, 838 | data: map[string]interface{}{ 839 | "a": int64(10), 840 | "b": int64(1), 841 | "c": int64(1), 842 | }, 843 | out: true, 844 | }, 845 | { 846 | rawYql: `a=10 and (c=1 or b!='1')`, 847 | data: map[string]interface{}{ 848 | "a": int64(10), 849 | "b": int64(1), 850 | "c": int64(1), 851 | }, 852 | out: true, 853 | }, 854 | { 855 | rawYql: `a=10 and (c=1 or b!='1') and d='123'`, 856 | data: map[string]interface{}{ 857 | "a": int64(10), 858 | "b": int64(1), 859 | "c": int64(1), 860 | "d": "123", 861 | }, 862 | out: true, 863 | }, 864 | } 865 | ass := assert.New(t) 866 | for _, tc := range testData { 867 | ok, err := Match(tc.rawYql, tc.data) 868 | ass.NoError(err) 869 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 870 | } 871 | } 872 | 873 | func TestMatch_Inter(t *testing.T) { 874 | var testData = []struct { 875 | rawYql string 876 | data map[string]interface{} 877 | out bool 878 | }{ 879 | { 880 | rawYql: `letter ∩ ('a','b','c','d','e')`, 881 | data: map[string]interface{}{ 882 | "letter": []string{"a", "e"}, 883 | }, 884 | out: true, 885 | }, 886 | { 887 | rawYql: `letter !∩ (1,2,3)`, 888 | data: map[string]interface{}{ 889 | "letter": []float64{0.5, 3.01}, 890 | }, 891 | out: true, 892 | }, 893 | { 894 | rawYql: `letter ∩ ('a', 'b','c','d', 'e')`, 895 | data: map[string]interface{}{ 896 | "letter": []string{"a", "e", "f"}, 897 | }, 898 | out: true, 899 | }, 900 | { 901 | rawYql: `letter ∩ ('a','b','c', 'd', 'e')`, 902 | data: map[string]interface{}{ 903 | "letter": []string{"f"}, 904 | }, 905 | out: false, 906 | }, 907 | { 908 | rawYql: `letter ∩ ('a','b','c','d')`, 909 | data: map[string]interface{}{ 910 | "letter": "c", 911 | }, 912 | out: true, 913 | }, 914 | { 915 | rawYql: `letter ∩ (1,2,3)`, 916 | data: map[string]interface{}{ 917 | "letter": []float64{2.0, 3.0}, 918 | }, 919 | out: true, 920 | }, 921 | { 922 | rawYql: `letter ∩ (1,2,3)`, 923 | data: map[string]interface{}{ 924 | "letter": []int64{2, 5}, 925 | }, 926 | out: true, 927 | }, 928 | { 929 | rawYql: `letter !∩ (1,2,3)`, 930 | data: map[string]interface{}{ 931 | "letter": []int64{4, 5}, 932 | }, 933 | out: true, 934 | }, 935 | } 936 | ass := assert.New(t) 937 | for _, tc := range testData { 938 | ok, err := Match(tc.rawYql, tc.data) 939 | ass.NoError(err) 940 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 941 | } 942 | } 943 | 944 | func TestMatch(t *testing.T) { 945 | var testData = []struct { 946 | rawYql string 947 | data map[string]interface{} 948 | out bool 949 | }{ 950 | { 951 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other') and score>=95 and rank !in ('b','c','d')`, 952 | data: map[string]interface{}{ 953 | "age": int64(24), 954 | "sex": "boy", 955 | "score": int64(95), 956 | "rank": "s", 957 | }, 958 | out: true, 959 | }, 960 | { 961 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other')`, 962 | data: map[string]interface{}{ 963 | "age": int64(24), 964 | "sex": "other", 965 | }, 966 | out: true, 967 | }, 968 | { 969 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other')`, 970 | data: map[string]interface{}{ 971 | "age": int64(24), 972 | "sex": "boy", 973 | }, 974 | out: true, 975 | }, 976 | { 977 | rawYql: `age>23 and (sex in ('boy','girl') or some!=5) and words='hello world'`, 978 | data: map[string]interface{}{ 979 | "age": int64(211), 980 | "sex": "boy", 981 | "some": int64(6), 982 | "words": "hello world", 983 | }, 984 | out: true, 985 | }, 986 | { 987 | rawYql: `age>23 and (sex in ('boy','girl') or some!=5) and words='hello world'`, 988 | data: map[string]interface{}{ 989 | "age": int64(21), 990 | "sex": "boy", 991 | "some": int64(6), 992 | "words": "hello world", 993 | }, 994 | out: false, 995 | }, 996 | { 997 | rawYql: `tag in (1,3,5) and status!=0`, 998 | data: map[string]interface{}{ 999 | "tag": []int64{1, 5}, 1000 | "status": int64(3), 1001 | }, 1002 | out: true, 1003 | }, 1004 | } 1005 | ass := assert.New(t) 1006 | for _, tc := range testData { 1007 | ok, err := Match(tc.rawYql, tc.data) 1008 | ass.NoError(err) 1009 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 1010 | } 1011 | } 1012 | 1013 | func TestRule_Match(t *testing.T) { 1014 | var testData = []struct { 1015 | rawYql string 1016 | data map[string]interface{} 1017 | out bool 1018 | }{ 1019 | { 1020 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other') and score>=95 and rank !in ('b','c','d')`, 1021 | data: map[string]interface{}{ 1022 | "age": int64(24), 1023 | "sex": "boy", 1024 | "score": int64(95), 1025 | "rank": "s", 1026 | }, 1027 | out: true, 1028 | }, 1029 | { 1030 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other')`, 1031 | data: map[string]interface{}{ 1032 | "age": int64(24), 1033 | "sex": "other", 1034 | }, 1035 | out: true, 1036 | }, 1037 | { 1038 | rawYql: `age>23 and (sex in ('boy','girl') or sex='other')`, 1039 | data: map[string]interface{}{ 1040 | "age": int64(24), 1041 | "sex": "boy", 1042 | }, 1043 | out: true, 1044 | }, 1045 | { 1046 | rawYql: `age>23 and (sex in ('boy','girl') or some!=5) and words='hello world'`, 1047 | data: map[string]interface{}{ 1048 | "age": int64(211), 1049 | "sex": "boy", 1050 | "some": int64(6), 1051 | "words": "hello world", 1052 | }, 1053 | out: true, 1054 | }, 1055 | { 1056 | rawYql: `age>23 and (sex in ('boy','girl') or some!=5) and words='hello world'`, 1057 | data: map[string]interface{}{ 1058 | "age": int64(21), 1059 | "sex": "boy", 1060 | "some": int64(6), 1061 | "words": "hello world", 1062 | }, 1063 | out: false, 1064 | }, 1065 | { 1066 | rawYql: `tag in (1,3,5) and status!=0`, 1067 | data: map[string]interface{}{ 1068 | "tag": []int64{1, 5}, 1069 | "status": int64(3), 1070 | }, 1071 | out: true, 1072 | }, 1073 | } 1074 | ass := assert.New(t) 1075 | for _, tc := range testData { 1076 | ruler, err := Rule(tc.rawYql) 1077 | ass.NoError(err) 1078 | ok, err := ruler.Match(tc.data) 1079 | ass.NoError(err) 1080 | ass.Equal(tc.out, ok, "rawYql=%s||data=%+v", tc.rawYql, tc.data) 1081 | } 1082 | } 1083 | 1084 | func TestRule_Match_Multi(t *testing.T) { 1085 | var testData = []struct { 1086 | data map[string]interface{} 1087 | out bool 1088 | }{ 1089 | { 1090 | data: map[string]interface{}{ 1091 | "age": int64(24), 1092 | "sex": "boy", 1093 | "score": int64(95), 1094 | "rank": "s", 1095 | }, 1096 | out: true, 1097 | }, 1098 | { 1099 | data: map[string]interface{}{ 1100 | "age": int64(23), 1101 | "sex": "boy", 1102 | "score": int64(95), 1103 | "rank": "s", 1104 | }, 1105 | out: false, 1106 | }, 1107 | { 1108 | data: map[string]interface{}{ 1109 | "age": int64(24), 1110 | "sex": "boy", 1111 | "score": int64(95), 1112 | "rank": "", 1113 | }, 1114 | out: true, 1115 | }, 1116 | { 1117 | data: map[string]interface{}{ 1118 | "age": int64(24), 1119 | "sex": "boy", 1120 | "score": int64(95), 1121 | "rank": "a", 1122 | }, 1123 | out: true, 1124 | }, 1125 | { 1126 | data: map[string]interface{}{ 1127 | "age": int64(23), 1128 | "sex": "boy", 1129 | "score": int64(92), 1130 | "rank": "s", 1131 | }, 1132 | out: false, 1133 | }, 1134 | { 1135 | data: map[string]interface{}{ 1136 | "age": int64(23), 1137 | "sex": "other", 1138 | "score": int64(97), 1139 | "rank": "s", 1140 | }, 1141 | out: false, 1142 | }, 1143 | } 1144 | ass := assert.New(t) 1145 | ruler, err := Rule(`age>23 and (sex in ('boy','girl') or sex='other') and score>=95 and rank !in ('b','c','d')`) 1146 | if !ass.NoError(err) { 1147 | t.FailNow() 1148 | } 1149 | for _, tc := range testData { 1150 | ok, err := ruler.Match(tc.data) 1151 | ass.NoError(err) 1152 | ass.Equal(tc.out, ok, "data=%+v", tc.data) 1153 | } 1154 | } 1155 | 1156 | func Test_Compare_Slice_And_One_Element(t *testing.T) { 1157 | should := require.New(t) 1158 | var testData = []struct { 1159 | rawYql string 1160 | data map[string]interface{} 1161 | out bool 1162 | }{ 1163 | { 1164 | rawYql: `letter ∩ ('a')`, 1165 | data: map[string]interface{}{ 1166 | "letter": []string{"a", "b", "c"}, 1167 | }, 1168 | out: true, 1169 | }, 1170 | { 1171 | rawYql: `letter ∩ ('a', 'b')`, 1172 | data: map[string]interface{}{ 1173 | "letter": []string{"a", "b", "c"}, 1174 | }, 1175 | out: true, 1176 | }, 1177 | { 1178 | rawYql: `letter ∩ ('d')`, 1179 | data: map[string]interface{}{ 1180 | "letter": []string{"a", "b", "c"}, 1181 | }, 1182 | out: false, 1183 | }, 1184 | { 1185 | rawYql: `letter in ('a')`, 1186 | data: map[string]interface{}{ 1187 | "letter": []string{"a", "b", "c"}, 1188 | }, 1189 | out: false, 1190 | }, 1191 | } 1192 | for _, tc := range testData { 1193 | actual, err := Match(tc.rawYql, tc.data) 1194 | should.NoError(err) 1195 | should.Equal(tc.out, actual) 1196 | } 1197 | } 1198 | --------------------------------------------------------------------------------