|
|
|
@ -22,7 +22,7 @@ import (
|
|
|
|
|
|
|
|
|
|
// item represents a token or text string returned from the scanner.
|
|
|
|
|
type item struct { |
|
|
|
|
typ itemType // The type of this item.
|
|
|
|
|
typ ItemType // The type of this item.
|
|
|
|
|
pos Pos // The starting position, in bytes, of this item in the input string.
|
|
|
|
|
val string // The value of this item.
|
|
|
|
|
} |
|
|
|
@ -50,25 +50,25 @@ func (i item) String() string {
|
|
|
|
|
|
|
|
|
|
// isOperator returns true if the item corresponds to a arithmetic or set operator.
|
|
|
|
|
// Returns false otherwise.
|
|
|
|
|
func (i itemType) isOperator() bool { return i > operatorsStart && i < operatorsEnd } |
|
|
|
|
func (i ItemType) isOperator() bool { return i > operatorsStart && i < operatorsEnd } |
|
|
|
|
|
|
|
|
|
// isAggregator returns true if the item belongs to the aggregator functions.
|
|
|
|
|
// Returns false otherwise
|
|
|
|
|
func (i itemType) isAggregator() bool { return i > aggregatorsStart && i < aggregatorsEnd } |
|
|
|
|
func (i ItemType) isAggregator() bool { return i > aggregatorsStart && i < aggregatorsEnd } |
|
|
|
|
|
|
|
|
|
// isAggregator returns true if the item is an aggregator that takes a parameter.
|
|
|
|
|
// Returns false otherwise
|
|
|
|
|
func (i itemType) isAggregatorWithParam() bool { |
|
|
|
|
func (i ItemType) isAggregatorWithParam() bool { |
|
|
|
|
return i == itemTopK || i == itemBottomK || i == itemCountValues || i == itemQuantile |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// isKeyword returns true if the item corresponds to a keyword.
|
|
|
|
|
// Returns false otherwise.
|
|
|
|
|
func (i itemType) isKeyword() bool { return i > keywordsStart && i < keywordsEnd } |
|
|
|
|
func (i ItemType) isKeyword() bool { return i > keywordsStart && i < keywordsEnd } |
|
|
|
|
|
|
|
|
|
// isCompairsonOperator returns true if the item corresponds to a comparison operator.
|
|
|
|
|
// Returns false otherwise.
|
|
|
|
|
func (i itemType) isComparisonOperator() bool { |
|
|
|
|
func (i ItemType) isComparisonOperator() bool { |
|
|
|
|
switch i { |
|
|
|
|
case itemEQL, itemNEQ, itemLTE, itemLSS, itemGTE, itemGTR: |
|
|
|
|
return true |
|
|
|
@ -78,7 +78,7 @@ func (i itemType) isComparisonOperator() bool {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// isSetOperator returns whether the item corresponds to a set operator.
|
|
|
|
|
func (i itemType) isSetOperator() bool { |
|
|
|
|
func (i ItemType) isSetOperator() bool { |
|
|
|
|
switch i { |
|
|
|
|
case itemLAND, itemLOR, itemLUnless: |
|
|
|
|
return true |
|
|
|
@ -92,7 +92,7 @@ const LowestPrec = 0 // Non-operators.
|
|
|
|
|
// Precedence returns the operator precedence of the binary
|
|
|
|
|
// operator op. If op is not a binary operator, the result
|
|
|
|
|
// is LowestPrec.
|
|
|
|
|
func (i itemType) precedence() int { |
|
|
|
|
func (i ItemType) precedence() int { |
|
|
|
|
switch i { |
|
|
|
|
case itemLOR: |
|
|
|
|
return 1 |
|
|
|
@ -111,7 +111,7 @@ func (i itemType) precedence() int {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (i itemType) isRightAssociative() bool { |
|
|
|
|
func (i ItemType) isRightAssociative() bool { |
|
|
|
|
switch i { |
|
|
|
|
case itemPOW: |
|
|
|
|
return true |
|
|
|
@ -121,10 +121,10 @@ func (i itemType) isRightAssociative() bool {
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type itemType int |
|
|
|
|
type ItemType int |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
itemError itemType = iota // Error occurred, value is error message
|
|
|
|
|
itemError ItemType = iota // Error occurred, value is error message
|
|
|
|
|
itemEOF |
|
|
|
|
itemComment |
|
|
|
|
itemIdentifier |
|
|
|
@ -198,7 +198,7 @@ const (
|
|
|
|
|
keywordsEnd |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var key = map[string]itemType{ |
|
|
|
|
var key = map[string]ItemType{ |
|
|
|
|
// Operators.
|
|
|
|
|
"and": itemLAND, |
|
|
|
|
"or": itemLOR, |
|
|
|
@ -235,7 +235,7 @@ var key = map[string]itemType{
|
|
|
|
|
|
|
|
|
|
// These are the default string representations for common items. It does not
|
|
|
|
|
// imply that those are the only character sequences that can be lexed to such an item.
|
|
|
|
|
var itemTypeStr = map[itemType]string{ |
|
|
|
|
var itemTypeStr = map[ItemType]string{ |
|
|
|
|
itemLeftParen: "(", |
|
|
|
|
itemRightParen: ")", |
|
|
|
|
itemLeftBrace: "{", |
|
|
|
@ -274,7 +274,7 @@ func init() {
|
|
|
|
|
key["nan"] = itemNumber |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (i itemType) String() string { |
|
|
|
|
func (i ItemType) String() string { |
|
|
|
|
if s, ok := itemTypeStr[i]; ok { |
|
|
|
|
return s |
|
|
|
|
} |
|
|
|
@ -291,7 +291,7 @@ func (i item) desc() string {
|
|
|
|
|
return fmt.Sprintf("%s %s", i.typ.desc(), i) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (i itemType) desc() string { |
|
|
|
|
func (i ItemType) desc() string { |
|
|
|
|
switch i { |
|
|
|
|
case itemError: |
|
|
|
|
return "error" |
|
|
|
@ -366,7 +366,7 @@ func (l *lexer) backup() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// emit passes an item back to the client.
|
|
|
|
|
func (l *lexer) emit(t itemType) { |
|
|
|
|
func (l *lexer) emit(t ItemType) { |
|
|
|
|
l.items <- item{t, l.start, l.input[l.start:l.pos]} |
|
|
|
|
l.start = l.pos |
|
|
|
|
} |
|
|
|
|