github.com/bytedance/go-tagexpr@v2.7.5-0.20210114074101-de5b8743ad85+incompatible/expr.go (about) 1 // Copyright 2019 Bytedance Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tagexpr 16 17 import ( 18 "fmt" 19 ) 20 21 // Expr expression 22 type Expr struct { 23 expr ExprNode 24 } 25 26 // parseExpr parses the expression. 27 func parseExpr(expr string) (*Expr, error) { 28 e := newGroupExprNode() 29 p := &Expr{ 30 expr: e, 31 } 32 s := expr 33 _, err := p.parseExprNode(&s, e) 34 if err != nil { 35 return nil, fmt.Errorf("%q (syntax error): %s", expr, err.Error()) 36 } 37 sortPriority(e.RightOperand()) 38 err = p.checkSyntax() 39 if err != nil { 40 return nil, err 41 } 42 return p, nil 43 } 44 45 // run calculates the value of expression. 46 func (p *Expr) run(field string, tagExpr *TagExpr) interface{} { 47 return p.expr.Run(field, tagExpr) 48 } 49 50 func (p *Expr) parseOperand(expr *string) (e ExprNode) { 51 for _, fn := range funcList { 52 if e = fn(p, expr); e != nil { 53 return e 54 } 55 } 56 if e = readStringExprNode(expr); e != nil { 57 return e 58 } 59 if e = readDigitalExprNode(expr); e != nil { 60 return e 61 } 62 if e = readBoolExprNode(expr); e != nil { 63 return e 64 } 65 if e = readNilExprNode(expr); e != nil { 66 return e 67 } 68 return nil 69 } 70 71 func (*Expr) parseOperator(expr *string) (e ExprNode) { 72 s := *expr 73 if len(s) < 2 { 74 return nil 75 } 76 defer func() { 77 if e != nil && *expr == s { 78 *expr = (*expr)[2:] 79 } 80 }() 81 a := s[:2] 82 switch a { 83 // case "<<": 84 // case ">>": 85 // case "&^": 86 case "||": 87 return newOrExprNode() 88 case "&&": 89 return newAndExprNode() 90 case "==": 91 return newEqualExprNode() 92 case ">=": 93 return newGreaterEqualExprNode() 94 case "<=": 95 return newLessEqualExprNode() 96 case "!=": 97 return newNotEqualExprNode() 98 } 99 defer func() { 100 if e != nil { 101 *expr = (*expr)[1:] 102 } 103 }() 104 switch a[0] { 105 // case '&': 106 // case '|': 107 // case '^': 108 case '+': 109 return newAdditionExprNode() 110 case '-': 111 return newSubtractionExprNode() 112 case '*': 113 return newMultiplicationExprNode() 114 case '/': 115 return newDivisionExprNode() 116 case '%': 117 return newRemainderExprNode() 118 case '<': 119 return newLessExprNode() 120 case '>': 121 return newGreaterExprNode() 122 } 123 return nil 124 } 125 126 func (p *Expr) parseExprNode(expr *string, e ExprNode) (ExprNode, error) { 127 trimLeftSpace(expr) 128 if *expr == "" { 129 return nil, nil 130 } 131 operand := p.readSelectorExprNode(expr) 132 if operand == nil { 133 var subExprNode *string 134 operand, subExprNode = readGroupExprNode(expr) 135 if operand != nil { 136 _, err := p.parseExprNode(subExprNode, operand) 137 if err != nil { 138 return nil, err 139 } 140 } else { 141 operand = p.parseOperand(expr) 142 } 143 } 144 if operand == nil { 145 return nil, fmt.Errorf("parsing pos: %q", *expr) 146 } 147 148 trimLeftSpace(expr) 149 operator := p.parseOperator(expr) 150 if operator == nil { 151 e.SetRightOperand(operand) 152 operand.SetParent(e) 153 return operand, nil 154 } 155 if _, ok := e.(*groupExprNode); ok { 156 operator.SetLeftOperand(operand) 157 operand.SetParent(operator) 158 e.SetRightOperand(operator) 159 operator.SetParent(e) 160 } else { 161 e.SetRightOperand(operand) 162 operand.SetParent(e) 163 operator.SetLeftOperand(e) 164 operator.SetParent(e.Parent()) 165 operator.Parent().SetRightOperand(operator) 166 e.SetParent(operator) 167 } 168 return p.parseExprNode(expr, operator) 169 } 170 171 func (p *Expr) checkSyntax() error { 172 173 return nil 174 } 175 176 /** 177 * Priority: 178 * () ! bool float64 string nil 179 * * / % 180 * + - 181 * < <= > >= 182 * == != 183 * && 184 * || 185 **/ 186 187 func sortPriority(e ExprNode) { 188 for subSortPriority(e) { 189 } 190 } 191 192 func subSortPriority(e ExprNode) bool { 193 if e == nil { 194 return false 195 } 196 leftChanged := subSortPriority(e.LeftOperand()) 197 rightChanged := subSortPriority(e.RightOperand()) 198 if getPriority(e) > getPriority(e.LeftOperand()) { 199 leftOperandToParent(e) 200 return true 201 } 202 return leftChanged || rightChanged 203 } 204 205 func getPriority(e ExprNode) (i int) { 206 // defer func() { 207 // fmt.Printf("expr:%T %d\n", e, i) 208 // }() 209 switch e.(type) { 210 default: // () ! bool float64 string nil 211 return 7 212 case *multiplicationExprNode, *divisionExprNode, *remainderExprNode: // * / % 213 return 6 214 case *additionExprNode, *subtractionExprNode: // + - 215 return 5 216 case *lessExprNode, *lessEqualExprNode, *greaterExprNode, *greaterEqualExprNode: // < <= > >= 217 return 4 218 case *equalExprNode, *notEqualExprNode: // == != 219 return 3 220 case *andExprNode: // && 221 return 2 222 case *orExprNode: // || 223 return 1 224 } 225 } 226 227 func leftOperandToParent(e ExprNode) { 228 le := e.LeftOperand() 229 if le == nil { 230 return 231 } 232 e.SetLeftOperand(le.RightOperand()) 233 le.SetRightOperand(e) 234 p := e.Parent() 235 // if p == nil { 236 // return 237 // } 238 if p.LeftOperand() == e { 239 p.SetLeftOperand(le) 240 } else { 241 p.SetRightOperand(le) 242 } 243 le.SetParent(p) 244 e.SetParent(le) 245 } 246 247 // ExprNode expression interface 248 type ExprNode interface { 249 SetParent(ExprNode) 250 Parent() ExprNode 251 LeftOperand() ExprNode 252 RightOperand() ExprNode 253 SetLeftOperand(ExprNode) 254 SetRightOperand(ExprNode) 255 Run(string, *TagExpr) interface{} 256 } 257 258 var _ ExprNode = new(exprBackground) 259 260 type exprBackground struct { 261 parent ExprNode 262 leftOperand ExprNode 263 rightOperand ExprNode 264 } 265 266 func (eb *exprBackground) SetParent(e ExprNode) { 267 eb.parent = e 268 } 269 270 func (eb *exprBackground) Parent() ExprNode { 271 return eb.parent 272 } 273 274 func (eb *exprBackground) LeftOperand() ExprNode { 275 return eb.leftOperand 276 } 277 278 func (eb *exprBackground) RightOperand() ExprNode { 279 return eb.rightOperand 280 } 281 282 func (eb *exprBackground) SetLeftOperand(left ExprNode) { 283 eb.leftOperand = left 284 } 285 286 func (eb *exprBackground) SetRightOperand(right ExprNode) { 287 eb.rightOperand = right 288 } 289 290 func (*exprBackground) Run(string, *TagExpr) interface{} { return nil }