正在显示
5 个修改的文件
包含
100 行增加
和
30 行删除
@@ -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,8 +19,9 @@ type ExprAST interface { | @@ -18,8 +19,9 @@ type ExprAST interface { | ||
18 | } | 19 | } |
19 | 20 | ||
20 | type NumberExprAST struct { | 21 | type NumberExprAST struct { |
21 | - Val float64 | ||
22 | - Str string | 22 | + ExprType string `json:"exprType"` |
23 | + Val float64 | ||
24 | + Str string | ||
23 | } | 25 | } |
24 | 26 | ||
25 | type ValueExprAST struct { | 27 | type ValueExprAST struct { |
@@ -42,10 +44,10 @@ type BinaryExprAST struct { | @@ -42,10 +44,10 @@ type BinaryExprAST struct { | ||
42 | } | 44 | } |
43 | 45 | ||
44 | type FunCallerExprAST struct { | 46 | type FunCallerExprAST struct { |
45 | - ArrayFlag bool `json:"arrayFlag"` | ||
46 | - ExprType string `json:"exprType"` | ||
47 | - Name string `json:"name"` | ||
48 | - Args []ExprAST `json:"args"` | 47 | + //ArrayFlag bool `json:"arrayFlag"` |
48 | + ExprType string `json:"exprType"` | ||
49 | + Name string `json:"name"` | ||
50 | + Args []ExprAST `json:"args"` | ||
49 | } | 51 | } |
50 | 52 | ||
51 | func (n NumberExprAST) toStr() string { | 53 | func (n NumberExprAST) toStr() string { |
@@ -86,9 +88,9 @@ func (n FunCallerExprAST) toStr() string { | @@ -86,9 +88,9 @@ func (n FunCallerExprAST) toStr() string { | ||
86 | } | 88 | } |
87 | 89 | ||
88 | type CloneFunCallerExprAST struct { | 90 | type CloneFunCallerExprAST struct { |
89 | - ArrayFlag bool `json:"arrayFlag"` | ||
90 | - Name string `json:"name"` | ||
91 | - Arg []json.RawMessage `json:"args"` | 91 | + //ArrayFlag bool `json:"arrayFlag"` |
92 | + Name string `json:"name"` | ||
93 | + Arg []json.RawMessage `json:"args"` | ||
92 | } | 94 | } |
93 | 95 | ||
94 | type CloneBinaryExprAST struct { | 96 | type CloneBinaryExprAST struct { |
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 | } |
-
请 注册 或 登录 后发表评论