github.com/CiscoM31/godata@v1.0.10/search_parser.go (about) 1 package godata 2 3 import "context" 4 5 type SearchTokenType int 6 7 func (s SearchTokenType) Value() int { 8 return (int)(s) 9 } 10 11 const ( 12 SearchTokenLiteral SearchTokenType = iota 13 SearchTokenOpenParen 14 SearchTokenCloseParen 15 SearchTokenOp 16 SearchTokenWhitespace 17 ) 18 19 var GlobalSearchTokenizer = SearchTokenizer() 20 var GlobalSearchParser = SearchParser() 21 22 // Convert an input string from the $filter part of the URL into a parse 23 // tree that can be used by providers to create a response. 24 func ParseSearchString(ctx context.Context, filter string) (*GoDataSearchQuery, error) { 25 tokens, err := GlobalSearchTokenizer.Tokenize(ctx, filter) 26 if err != nil { 27 return nil, err 28 } 29 postfix, err := GlobalSearchParser.InfixToPostfix(ctx, tokens) 30 if err != nil { 31 return nil, err 32 } 33 tree, err := GlobalSearchParser.PostfixToTree(ctx, postfix) 34 if err != nil { 35 return nil, err 36 } 37 return &GoDataSearchQuery{tree, filter}, nil 38 } 39 40 // Create a tokenizer capable of tokenizing filter statements 41 func SearchTokenizer() *Tokenizer { 42 t := Tokenizer{} 43 t.Add("^\\\"[^\\\"]+\\\"", SearchTokenLiteral) 44 t.Add("^\\(", SearchTokenOpenParen) 45 t.Add("^\\)", SearchTokenCloseParen) 46 t.Add("^(OR|AND|NOT)", SearchTokenOp) 47 t.Add("^[\\w]+", SearchTokenLiteral) 48 t.Ignore("^ ", SearchTokenWhitespace) 49 50 return &t 51 } 52 53 func SearchParser() *Parser { 54 parser := EmptyParser() 55 parser.DefineOperator("NOT", 1, OpAssociationNone, 3) 56 parser.DefineOperator("AND", 2, OpAssociationLeft, 2) 57 parser.DefineOperator("OR", 2, OpAssociationLeft, 1) 58 return parser 59 }