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  }