作者 yangfu

feat: ast expr version 1

@@ -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 {
  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 }