正在显示
5 个修改的文件
包含
93 行增加
和
23 行删除
| @@ -86,7 +86,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | @@ -86,7 +86,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | ||
| 86 | // call func | 86 | // call func |
| 87 | if a.currTok.Tok == "(" { | 87 | if a.currTok.Tok == "(" { |
| 88 | f := FunCallerExprAST{} | 88 | f := FunCallerExprAST{} |
| 89 | - if _, ok := defFunc[name]; !ok { | 89 | + if _, ok := defFunc[strings.ToLower(name)]; !ok { |
| 90 | a.Err = errors.New( | 90 | a.Err = errors.New( |
| 91 | fmt.Sprintf("function `%s` is undefined\n%s", | 91 | fmt.Sprintf("function `%s` is undefined\n%s", |
| 92 | name, | 92 | name, |
| @@ -107,7 +107,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | @@ -107,7 +107,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | ||
| 107 | exprs = append(exprs, a.ParseExpression()) | 107 | exprs = append(exprs, a.ParseExpression()) |
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | - def := defFunc[name] | 110 | + def := defFunc[strings.ToLower(name)] |
| 111 | if def.argc >= 0 && len(exprs) != def.argc { | 111 | if def.argc >= 0 && len(exprs) != def.argc { |
| 112 | a.Err = errors.New( | 112 | a.Err = errors.New( |
| 113 | fmt.Sprintf("wrong way calling function `%s`, parameters want %d but get %d\n%s", | 113 | fmt.Sprintf("wrong way calling function `%s`, parameters want %d but get %d\n%s", |
| @@ -117,8 +117,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | @@ -117,8 +117,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | ||
| 117 | ErrPos(a.source, a.currTok.Offset))) | 117 | ErrPos(a.source, a.currTok.Offset))) |
| 118 | } | 118 | } |
| 119 | a.getNextToken() | 119 | a.getNextToken() |
| 120 | - f.Name = name | ||
| 121 | - f.Args = exprs | 120 | + f = NewFunCallerExprAST(name, exprs...) |
| 122 | return f | 121 | return f |
| 123 | } | 122 | } |
| 124 | // call const | 123 | // call const |
| @@ -129,9 +128,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | @@ -129,9 +128,7 @@ func (a *AST) parseFunCallerOrConst() ExprAST { | ||
| 129 | } | 128 | } |
| 130 | } else { | 129 | } else { |
| 131 | if strings.Contains(name, ".") { | 130 | if strings.Contains(name, ".") { |
| 132 | - return FieldExprAST{ | ||
| 133 | - Str: name, | ||
| 134 | - } | 131 | + return NewFieldExprAST(name) |
| 135 | } | 132 | } |
| 136 | a.Err = errors.New( | 133 | a.Err = errors.New( |
| 137 | fmt.Sprintf("const `%s` is undefined\n%s", | 134 | fmt.Sprintf("const `%s` is undefined\n%s", |
| @@ -148,9 +145,7 @@ func (a *AST) parsePrimary() ExprAST { | @@ -148,9 +145,7 @@ func (a *AST) parsePrimary() ExprAST { | ||
| 148 | case Literal: | 145 | case Literal: |
| 149 | return a.parseNumber() | 146 | return a.parseNumber() |
| 150 | case StringArgs: | 147 | case StringArgs: |
| 151 | - e := ValueExprAST{ | ||
| 152 | - Str: a.currTok.Tok, | ||
| 153 | - } | 148 | + e := NewValueExprAST(a.currTok.Tok) |
| 154 | a.getNextToken() | 149 | a.getNextToken() |
| 155 | return e | 150 | return e |
| 156 | case Operator: | 151 | case Operator: |
| @@ -182,11 +177,7 @@ func (a *AST) parsePrimary() ExprAST { | @@ -182,11 +177,7 @@ func (a *AST) parsePrimary() ExprAST { | ||
| 182 | ErrPos(a.source, a.currTok.Offset))) | 177 | ErrPos(a.source, a.currTok.Offset))) |
| 183 | return nil | 178 | return nil |
| 184 | } | 179 | } |
| 185 | - bin := BinaryExprAST{ | ||
| 186 | - Op: "-", | ||
| 187 | - Lhs: NumberExprAST{}, | ||
| 188 | - Rhs: a.parsePrimary(), | ||
| 189 | - } | 180 | + bin := NewBinaryExprAST("-", NumberExprAST{}, a.parsePrimary()) |
| 190 | return bin | 181 | return bin |
| 191 | } else { | 182 | } else { |
| 192 | return a.parseNumber() | 183 | return a.parseNumber() |
| @@ -226,10 +217,6 @@ func (a *AST) parseBinOpRHS(execPrec int, lhs ExprAST) ExprAST { | @@ -226,10 +217,6 @@ func (a *AST) parseBinOpRHS(execPrec int, lhs ExprAST) ExprAST { | ||
| 226 | return nil | 217 | return nil |
| 227 | } | 218 | } |
| 228 | } | 219 | } |
| 229 | - lhs = BinaryExprAST{ | ||
| 230 | - Op: binOp, | ||
| 231 | - Lhs: lhs, | ||
| 232 | - Rhs: rhs, | ||
| 233 | - } | 220 | + lhs = NewBinaryExprAST(binOp, lhs, rhs) |
| 234 | } | 221 | } |
| 235 | } | 222 | } |
| @@ -11,6 +11,7 @@ const ( | @@ -11,6 +11,7 @@ const ( | ||
| 11 | TypeBinaryExprAST = "BinaryExprAST" | 11 | TypeBinaryExprAST = "BinaryExprAST" |
| 12 | TypeFieldExprAST = "FieldExprAST" | 12 | TypeFieldExprAST = "FieldExprAST" |
| 13 | TypeValueExprAST = "ValueExprAST" | 13 | TypeValueExprAST = "ValueExprAST" |
| 14 | + TypeNumberExprAST = "NumberExprAST" | ||
| 14 | ) | 15 | ) |
| 15 | 16 | ||
| 16 | type ExprAST interface { | 17 | type ExprAST interface { |
| @@ -18,6 +19,7 @@ type ExprAST interface { | @@ -18,6 +19,7 @@ type ExprAST interface { | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | type NumberExprAST struct { | 21 | type NumberExprAST struct { |
| 22 | + ExprType string `json:"exprType"` | ||
| 21 | Val float64 | 23 | Val float64 |
| 22 | Str string | 24 | Str string |
| 23 | } | 25 | } |
| @@ -42,7 +44,7 @@ type BinaryExprAST struct { | @@ -42,7 +44,7 @@ type BinaryExprAST struct { | ||
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | type FunCallerExprAST struct { | 46 | type FunCallerExprAST struct { |
| 45 | - ArrayFlag bool `json:"arrayFlag"` | 47 | + //ArrayFlag bool `json:"arrayFlag"` |
| 46 | ExprType string `json:"exprType"` | 48 | ExprType string `json:"exprType"` |
| 47 | Name string `json:"name"` | 49 | Name string `json:"name"` |
| 48 | Args []ExprAST `json:"args"` | 50 | Args []ExprAST `json:"args"` |
| @@ -86,7 +88,7 @@ func (n FunCallerExprAST) toStr() string { | @@ -86,7 +88,7 @@ func (n FunCallerExprAST) toStr() string { | ||
| 86 | } | 88 | } |
| 87 | 89 | ||
| 88 | type CloneFunCallerExprAST struct { | 90 | type CloneFunCallerExprAST struct { |
| 89 | - ArrayFlag bool `json:"arrayFlag"` | 91 | + //ArrayFlag bool `json:"arrayFlag"` |
| 90 | Name string `json:"name"` | 92 | Name string `json:"name"` |
| 91 | Arg []json.RawMessage `json:"args"` | 93 | Arg []json.RawMessage `json:"args"` |
| 92 | } | 94 | } |
pkg/domain/astexpr/ast_expr_builder.go
0 → 100644
| 1 | +package astexpr | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain" | ||
| 5 | + "strconv" | ||
| 6 | + "strings" | ||
| 7 | +) | ||
| 8 | + | ||
| 9 | +func NewNumberExprAST(val string) NumberExprAST { | ||
| 10 | + num, _ := strconv.ParseFloat(val, 64) | ||
| 11 | + return NumberExprAST{ | ||
| 12 | + ExprType: TypeNumberExprAST, | ||
| 13 | + Val: num, | ||
| 14 | + Str: val, | ||
| 15 | + } | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func NewValueExprAST(val string) ValueExprAST { | ||
| 19 | + return ValueExprAST{ | ||
| 20 | + ExprType: TypeValueExprAST, | ||
| 21 | + Val: val, | ||
| 22 | + Str: val, | ||
| 23 | + } | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +func NewFieldExprAST(val string) FieldExprAST { | ||
| 27 | + words := strings.Split(val, ".") | ||
| 28 | + table := words[0] | ||
| 29 | + filed := words[0] | ||
| 30 | + if len(words) > 0 { | ||
| 31 | + filed = words[1] | ||
| 32 | + } | ||
| 33 | + return FieldExprAST{ | ||
| 34 | + ExprType: TypeFieldExprAST, | ||
| 35 | + Str: val, | ||
| 36 | + Field: &domain.TableField{ | ||
| 37 | + FieldName: filed, | ||
| 38 | + TableName: table, | ||
| 39 | + }, | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +func NewBinaryExprAST(op string, lhs ExprAST, rhs ExprAST) BinaryExprAST { | ||
| 44 | + return BinaryExprAST{ | ||
| 45 | + ExprType: TypeBinaryExprAST, | ||
| 46 | + Op: op, | ||
| 47 | + Lhs: lhs, | ||
| 48 | + Rhs: rhs, | ||
| 49 | + } | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +func NewFunCallerExprAST(name string, args ...ExprAST) FunCallerExprAST { | ||
| 53 | + return FunCallerExprAST{ | ||
| 54 | + ExprType: TypeFunCallerExprAST, | ||
| 55 | + Name: name, | ||
| 56 | + Args: args, | ||
| 57 | + } | ||
| 58 | +} |
| @@ -94,3 +94,26 @@ func TestAstExprUnmarshalJSON(t *testing.T) { | @@ -94,3 +94,26 @@ func TestAstExprUnmarshalJSON(t *testing.T) { | ||
| 94 | assert.Equal(t, input.data, v) | 94 | assert.Equal(t, input.data, v) |
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | + | ||
| 98 | +func TestAstExprParse(t *testing.T) { | ||
| 99 | + funs := []struct { | ||
| 100 | + Name string | ||
| 101 | + Exp []string | ||
| 102 | + }{ | ||
| 103 | + { | ||
| 104 | + "多级嵌套", | ||
| 105 | + []string{`COUNTIF(销售明细.业绩,"<=1000")-COUNTIF(销售明细.业绩,"<=100")`}, | ||
| 106 | + }, | ||
| 107 | + } | ||
| 108 | + for _, f := range funs { | ||
| 109 | + for _, exp := range f.Exp { | ||
| 110 | + r, err := Parse(exp) | ||
| 111 | + if err != nil { | ||
| 112 | + t.Error(err) | ||
| 113 | + } | ||
| 114 | + if r != 0 { | ||
| 115 | + | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | +} |
| @@ -138,7 +138,7 @@ func (p *Parser) nextTok() *Token { | @@ -138,7 +138,7 @@ func (p *Parser) nextTok() *Token { | ||
| 138 | } | 138 | } |
| 139 | tok.Offset = start | 139 | tok.Offset = start |
| 140 | case '"': | 140 | case '"': |
| 141 | - for (p.isDigitNum(p.ch) || p.isChar(p.ch)) && p.nextCh() == nil { | 141 | + for (p.isDigitNum(p.ch) || p.isChar(p.ch) || p.isCompareWordChar(p.ch)) && p.nextCh() == nil { |
| 142 | if p.ch == '"' { | 142 | if p.ch == '"' { |
| 143 | break | 143 | break |
| 144 | } | 144 | } |
-
请 注册 或 登录 后发表评论