Files
chaisql/internal/sql/scanner/token.go
2022-05-12 23:12:39 +04:00

390 lines
6.7 KiB
Go

package scanner
import (
"strings"
)
// Token is a lexical token of the Genji SQL language.
type Token int
// These are a comprehensive list of Genji SQL language tokens.
const (
// ILLEGAL Token, EOF, WS are Special Genji SQL tokens.
ILLEGAL Token = iota
EOF
WS
COMMENT
// IDENT and the following are Genji SQL literal tokens.
IDENT // main
NAMEDPARAM // $param
POSITIONALPARAM // ?
NUMBER // 12345.67
INTEGER // 12345
STRING // "abc"
BADSTRING // "abc
BADESCAPE // \q
TRUE // true
FALSE // false
NULL // NULL
REGEX // Regular expressions
BADREGEX // `.*
ELLIPSIS // ...
literalEnd
operatorBeg
// ADD and the following are Genji SQL Operators
ADD // +
SUB // -
MUL // *
DIV // /
MOD // %
BITWISEAND // &
BITWISEOR // |
BITWISEXOR // ^
AND // AND
OR // OR
EQ // =
NEQ // !=
EQREGEX // =~
NEQREGEX // !~
LT // <
LTE // <=
GT // >
GTE // >=
IN // IN
NIN // NOT IN
IS // IS
ISN // IS NOT
LIKE // LIKE
NLIKE // NOT LIKE
CONCAT // ||
BETWEEN // BETWEEN
operatorEnd
LPAREN // (
RPAREN // )
LBRACKET // {
RBRACKET // }
LSBRACKET // [
RSBRACKET // ]
COMMA // ,
COLON // :
DOUBLECOLON // ::
SEMICOLON // ;
DOT // .
keywordBeg
// ALL and the following are Genji SQL Keywords
ADD_KEYWORD
ALL
ALTER
AS
ASC
BEGIN
BY
CACHE
CAST
CHECK
COMMIT
CONFLICT
CONSTRAINT
CREATE
CYCLE
DEFAULT
DELETE
DESC
DISTINCT
DO
DROP
EXISTS
EXPLAIN
FIELD
FOR
FROM
GROUP
IF
IGNORE
INCREMENT
INDEX
INSERT
INTO
KEY
LIMIT
MAXVALUE
MINVALUE
NEXT
NO
NOT
NOTHING
OFFSET
ON
ONLY
ORDER
PRECISION
PRIMARY
READ
REINDEX
RENAME
REPLACE
RETURNING
ROLLBACK
SELECT
SEQUENCE
SET
START
TABLE
TO
TRANSACTION
UNION
UNIQUE
UNSET
UPDATE
VALUE
VALUES
WITH
WHERE
WRITE
// Types
TYPEANY
TYPEARRAY
TYPEBIGINT
TYPEBLOB
TYPEBOOL
TYPEBOOLEAN
TYPEBYTES
TYPECHARACTER
TYPEDOCUMENT
TYPEDOUBLE
TYPEINT
TYPEINT2
TYPEINT8
TYPEINTEGER
TYPEMEDIUMINT
TYPESMALLINT
TYPETEXT
TYPETINYINT
TYPEREAL
TYPEVARCHAR
keywordEnd
)
var tokens = [...]string{
ILLEGAL: "ILLEGAL",
EOF: "EOF",
WS: "WS",
IDENT: "IDENT",
POSITIONALPARAM: "?",
NUMBER: "NUMBER",
STRING: "STRING",
BADSTRING: "BADSTRING",
BADESCAPE: "BADESCAPE",
TRUE: "TRUE",
FALSE: "FALSE",
REGEX: "REGEX",
NULL: "NULL",
ADD: "+",
SUB: "-",
MUL: "*",
DIV: "/",
MOD: "%",
BITWISEAND: "&",
BITWISEOR: "|",
BITWISEXOR: "^",
BETWEEN: "BETWEEN",
AND: "AND",
OR: "OR",
EQ: "=",
NEQ: "!=",
EQREGEX: "=~",
NEQREGEX: "!~",
LT: "<",
LTE: "<=",
GT: ">",
GTE: ">=",
IN: "IN",
IS: "IS",
LIKE: "LIKE",
LPAREN: "(",
RPAREN: ")",
LBRACKET: "{",
RBRACKET: "}",
LSBRACKET: "[",
RSBRACKET: "]",
COMMA: ",",
COLON: ":",
DOUBLECOLON: "::",
SEMICOLON: ";",
DOT: ".",
ADD_KEYWORD: "ADD",
ALL: "ALL",
ALTER: "ALTER",
AS: "AS",
ASC: "ASC",
BEGIN: "BEGIN",
BY: "BY",
CACHE: "CACHE",
CAST: "CAST",
CHECK: "CHECK",
COMMIT: "COMMIT",
CONFLICT: "CONFLICT",
CONSTRAINT: "CONSTRAINT",
CREATE: "CREATE",
CYCLE: "CYCLE",
DO: "DO",
DEFAULT: "DEFAULT",
DELETE: "DELETE",
DESC: "DESC",
DISTINCT: "DISTINCT",
DROP: "DROP",
EXISTS: "EXISTS",
EXPLAIN: "EXPLAIN",
GROUP: "GROUP",
KEY: "KEY",
FIELD: "FIELD",
FOR: "FOR",
FROM: "FROM",
IF: "IF",
IGNORE: "IGNORE",
INCREMENT: "INCREMENT",
INDEX: "INDEX",
INSERT: "INSERT",
INTO: "INTO",
LIMIT: "LIMIT",
MAXVALUE: "MAXVALUE",
MINVALUE: "MINVALUE",
NEXT: "NEXT",
NO: "NO",
NOT: "NOT",
NOTHING: "NOTHING",
OFFSET: "OFFSET",
ON: "ON",
ONLY: "ONLY",
ORDER: "ORDER",
PRECISION: "PRECISION",
PRIMARY: "PRIMARY",
READ: "READ",
REINDEX: "REINDEX",
RENAME: "RENAME",
RETURNING: "RETURNING",
REPLACE: "REPLACE",
ROLLBACK: "ROLLBACK",
START: "START",
SELECT: "SELECT",
SET: "SET",
SEQUENCE: "SEQUENCE",
TABLE: "TABLE",
TO: "TO",
TRANSACTION: "TRANSACTION",
UNION: "UNION",
UNIQUE: "UNIQUE",
UNSET: "UNSET",
UPDATE: "UPDATE",
VALUE: "VALUE",
VALUES: "VALUES",
WITH: "WITH",
WHERE: "WHERE",
WRITE: "WRITE",
TYPEANY: "ANY",
TYPEARRAY: "ARRAY",
TYPEBIGINT: "BIGINT",
TYPEBLOB: "BLOB",
TYPEBOOL: "BOOL",
TYPEBOOLEAN: "BOOLEAN",
TYPEBYTES: "BYTES",
TYPECHARACTER: "CHARACTER",
TYPEDOCUMENT: "DOCUMENT",
TYPEDOUBLE: "DOUBLE",
TYPEINT: "INT",
TYPEINT2: "INT2",
TYPEINT8: "INT8",
TYPEINTEGER: "INTEGER",
TYPEMEDIUMINT: "MEDIUMINT",
TYPESMALLINT: "SMALLINT",
TYPETEXT: "TEXT",
TYPETINYINT: "TINYINT",
TYPEREAL: "REAL",
TYPEVARCHAR: "VARCHAR",
}
var keywords map[string]Token
// String returns the string representation of the token.
func (tok Token) String() string {
if tok >= 0 && tok < Token(len(tokens)) {
return tokens[tok]
}
return ""
}
// Precedence returns the operator precedence of the binary operator token.
func (tok Token) Precedence() int {
switch tok {
case OR:
return 1
case AND:
return 2
case NOT:
return 3
case EQ, NEQ, IS, ISN, IN, NIN, LIKE, NLIKE, EQREGEX, NEQREGEX, BETWEEN:
return 4
case LT, LTE, GT, GTE:
return 5
case BITWISEOR, BITWISEXOR, BITWISEAND:
return 6
case ADD, SUB:
return 7
case MUL, DIV, MOD:
return 8
case CONCAT:
return 9
}
return 0
}
// IsOperator returns true for operator tokens.
func (tok Token) IsOperator() bool { return tok > operatorBeg && tok < operatorEnd }
// Tokstr returns a literal if provided, otherwise returns the token string.
func Tokstr(tok Token, lit string) string {
if lit != "" {
return lit
}
return tok.String()
}
// lookup returns the token associated with a given string.
func lookup(ident string) Token {
if tok, ok := keywords[strings.ToLower(ident)]; ok {
return tok
}
return IDENT
}
// Pos specifies the line and character position of a token.
// The Char and Line are both zero-based indexes.
type Pos struct {
Line int
Char int
}
// AllKeywords returns all defined tokens corresponding to keywords.
func AllKeywords() []Token {
tokens := make([]Token, 0, len(keywords))
for _, tok := range keywords {
tokens = append(tokens, tok)
}
return tokens
}