| 123 | } |
| 124 | |
| 125 | func (p *Parser) parseExpression() (Node, error) { |
| 126 | exp := &Expression{ |
| 127 | Field: "", |
| 128 | Comparator: "", |
| 129 | Value: "", |
| 130 | } |
| 131 | |
| 132 | isValueEmpty := false |
| 133 | // This code relies on being Field -> Comparator -> Value in order. |
| 134 | tok, lit := p.scan() |
| 135 | for tok != EOF { |
| 136 | switch { |
| 137 | // Open bracket means we found an operation that needs parsing. |
| 138 | case tok == OPEN_BRACKET: |
| 139 | return p.parseOperation() |
| 140 | // Ignore whitespace unless we have completed the expression. |
| 141 | case tok == WS: |
| 142 | if exp.Field != "" && exp.Comparator != "" && (exp.Value != "" || isValueEmpty) { |
| 143 | // Got to the end of the expression so quit |
| 144 | return exp, nil |
| 145 | } |
| 146 | // Looking for the Field name. |
| 147 | case exp.Field == "": |
| 148 | if tok != STRING { |
| 149 | return nil, fmt.Errorf("expected Field, got %v", tok) |
| 150 | } |
| 151 | exp.Field = lit |
| 152 | // Looking for the Comparator. |
| 153 | case exp.Comparator == "": |
| 154 | if !isTokenComparator(tok) { |
| 155 | return nil, fmt.Errorf("expected Comparator, got %v", tok) |
| 156 | } |
| 157 | exp.Comparator = lit |
| 158 | // Looking for the Value |
| 159 | case exp.Value == "": |
| 160 | if tok != STRING { |
| 161 | // If we didn't have an empty string in the value field - return an error. |
| 162 | if isValueEmpty { |
| 163 | break |
| 164 | } else { |
| 165 | return nil, fmt.Errorf("expected Value, got %v", tok) |
| 166 | } |
| 167 | } |
| 168 | if lit == "" { |
| 169 | isValueEmpty = true |
| 170 | } |
| 171 | exp.Value = lit |
| 172 | } |
| 173 | tok, lit = p.scan() |
| 174 | } |
| 175 | if exp.Field != "" && exp.Comparator == "" { |
| 176 | return nil, errors.New("found no comparator when expected") |
| 177 | } |
| 178 | return exp, nil |
| 179 | } |
| 180 | |
| 181 | // scan returns the next token from the underlying scanner. |
| 182 | // If a token has been unscanned then read that instead. |