// Package token defines the lexical elements of a River config and utilities1// surrounding their position.2package token34// Token is an individual River lexical token.5type Token int67// List of all lexical tokens and examples that represent them.8//9// LITERAL is used by token/builder to represent literal strings for writing10// tokens, but never used for reading (so scanner never returns a11// token.LITERAL).12const (13ILLEGAL Token = iota // Invalid token.14LITERAL // Literal text.15EOF // End-of-file.16COMMENT // // Hello, world!1718literalBeg19IDENT // foobar20NUMBER // 123421FLOAT // 1234.022STRING // "foobar"23literalEnd2425keywordBeg26BOOL // true27NULL // null28keywordEnd2930operatorBeg31OR // ||32AND // &&33NOT // !3435ASSIGN // =3637EQ // ==38NEQ // !=39LT // <40LTE // <=41GT // >42GTE // >=4344ADD // +45SUB // -46MUL // *47DIV // /48MOD // %49POW // ^5051LCURLY // {52RCURLY // }53LPAREN // (54RPAREN // )55LBRACK // [56RBRACK // ]57COMMA // ,58DOT // .59operatorEnd6061TERMINATOR // \n62)6364var tokenNames = [...]string{65ILLEGAL: "ILLEGAL",66LITERAL: "LITERAL",67EOF: "EOF",68COMMENT: "COMMENT",6970IDENT: "IDENT",71NUMBER: "NUMBER",72FLOAT: "FLOAT",73STRING: "STRING",74BOOL: "BOOL",75NULL: "NULL",7677OR: "||",78AND: "&&",79NOT: "!",8081ASSIGN: "=",82EQ: "==",83NEQ: "!=",84LT: "<",85LTE: "<=",86GT: ">",87GTE: ">=",8889ADD: "+",90SUB: "-",91MUL: "*",92DIV: "/",93MOD: "%",94POW: "^",9596LCURLY: "{",97RCURLY: "}",98LPAREN: "(",99RPAREN: ")",100LBRACK: "[",101RBRACK: "]",102COMMA: ",",103DOT: ".",104105TERMINATOR: "TERMINATOR",106}107108// Lookup maps a string to its keyword token or IDENT if it's not a keyword.109func Lookup(ident string) Token {110switch ident {111case "true", "false":112return BOOL113case "null":114return NULL115default:116return IDENT117}118}119120// String returns the string representation corresponding to the token.121func (t Token) String() string {122if int(t) >= len(tokenNames) {123return "ILLEGAL"124}125126name := tokenNames[t]127if name == "" {128return "ILLEGAL"129}130return name131}132133// GoString returns the %#v format of t.134func (t Token) GoString() string { return t.String() }135136// IsKeyword returns true if the token corresponds to a keyword.137func (t Token) IsKeyword() bool { return t > keywordBeg && t < keywordEnd }138139// IsLiteral returns true if the token corresponds to a literal token or140// identifier.141func (t Token) IsLiteral() bool { return t > literalBeg && t < literalEnd }142143// IsOperator returns true if the token corresponds to an operator or144// delimiter.145func (t Token) IsOperator() bool { return t > operatorBeg && t < operatorEnd }146147// BinaryPrecedence returns the operator precedence of the binary operator t.148// If t is not a binary operator, the result is LowestPrecedence.149func (t Token) BinaryPrecedence() int {150switch t {151case OR:152return 1153case AND:154return 2155case EQ, NEQ, LT, LTE, GT, GTE:156return 3157case ADD, SUB:158return 4159case MUL, DIV, MOD:160return 5161case POW:162return 6163}164165return LowestPrecedence166}167168// Levels of precedence for operator tokens.169const (170LowestPrecedence = 0 // non-operators171UnaryPrecedence = 7172HighestPrecedence = 8173)174175176