surrealpatch/sql/token.go

418 lines
6.9 KiB
Go
Raw Normal View History

2016-02-26 17:27:07 +00:00
// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sql
// Token defines a lexical token
type Token int
const (
// special
ILLEGAL Token = iota
EOF
WS
// literals
literalsBeg
2016-09-07 15:44:23 +00:00
DATE // 1970-01-01
TIME // 1970-01-01T00:00:00+00:00
PATH // person->like->person
JSON // {"test":true}
IDENT // something
THING // @class:id
STRING // "something"
REGION // "a multiline \n string"
NUMBER // 123456
DOUBLE // 123.456
REGEX // /.*/
ARRAY // [0,1,2]
DURATION // 13h
PARAM // $1
2016-02-26 17:27:07 +00:00
DOT // .
COMMA // ,
2016-09-06 13:30:59 +00:00
QMARK // ?
2016-02-26 17:27:07 +00:00
LPAREN // (
RPAREN // )
LBRACK // [
RBRACK // ]
COLON // :
SEMICOLON // ;
literalsEnd
// operators
operatorBeg
ADD // +
SUB // -
MUL // *
DIV // /
INC // +=
DEC // -=
EQ // =
2016-09-06 13:30:59 +00:00
EEQ // ==
EXC // !
2016-02-26 17:27:07 +00:00
NEQ // !=
2016-09-06 13:30:59 +00:00
NEE // !==
ANY // ?=
2016-02-26 17:27:07 +00:00
LT // <
LTE // <=
GT // >
GTE // >=
2016-09-06 13:30:59 +00:00
SIN // ∋
SNI // ∌
INS // ∈
NIS // ∉
2016-02-26 17:27:07 +00:00
2016-07-04 10:37:37 +00:00
OEDGE // ->
IEDGE // <-
BEDGE // <->
2016-02-26 17:27:07 +00:00
operatorEnd
// literals
keywordsBeg
2016-07-04 10:37:37 +00:00
ACCEPT
2016-05-23 12:32:02 +00:00
AFTER
2016-02-26 17:27:07 +00:00
ALL
2016-09-06 13:30:59 +00:00
ALLCONTAINEDIN
2016-02-26 17:27:07 +00:00
AND
AS
ASC
AT
2016-05-23 12:32:02 +00:00
BEFORE
2016-09-06 13:30:59 +00:00
BEGIN
2016-05-23 12:32:02 +00:00
BOTH
2016-02-26 17:27:07 +00:00
BY
2016-09-06 13:30:59 +00:00
CANCEL
2016-05-23 12:32:02 +00:00
CODE
2016-02-26 17:27:07 +00:00
COLUMNS
2016-09-06 13:30:59 +00:00
COMMIT
CONTAINS
CONTAINSALL
CONTAINSNONE
CONTAINSSOME
2016-05-23 12:32:02 +00:00
CONTENT
2016-02-26 17:27:07 +00:00
CREATE
2016-09-06 13:30:59 +00:00
CUSTOM
2016-05-23 12:32:02 +00:00
DATABASE
DEFAULT
2016-02-26 17:27:07 +00:00
DEFINE
DELETE
DESC
2016-05-23 12:32:02 +00:00
DIFF
2016-02-26 17:27:07 +00:00
DISTINCT
EMPTY
2016-07-04 10:37:37 +00:00
ENUM
EXPUNGE
2016-02-26 17:27:07 +00:00
FALSE
2016-05-23 12:32:02 +00:00
FIELD
2016-09-06 13:30:59 +00:00
FOR
2016-02-26 17:27:07 +00:00
FROM
GROUP
2016-07-04 10:37:37 +00:00
HISTORY
2016-05-23 12:32:02 +00:00
ID
2016-10-14 21:06:05 +00:00
IF
2016-02-26 17:27:07 +00:00
IN
INDEX
2016-09-19 10:08:44 +00:00
INFO
2016-02-26 17:27:07 +00:00
INSERT
INTO
2016-09-06 13:30:59 +00:00
IS
LET
2016-02-26 17:27:07 +00:00
LIMIT
2016-05-23 12:32:02 +00:00
MANDATORY
2016-09-06 13:30:59 +00:00
MATCH
2016-05-23 12:32:02 +00:00
MAX
MERGE
MIN
2016-09-06 13:30:59 +00:00
MISSING
2016-02-26 17:27:07 +00:00
MODIFY
2016-09-06 13:30:59 +00:00
MULTI
2016-05-23 12:32:02 +00:00
NAMESPACE
NONE
2016-09-06 13:30:59 +00:00
NONECONTAINEDIN
NOT
2016-05-23 12:32:02 +00:00
NOTNULL
NOW
2016-02-26 17:27:07 +00:00
NULL
OFFSET
ON
OR
ORDER
2016-05-23 12:32:02 +00:00
READONLY
2016-07-04 10:37:37 +00:00
REJECT
2016-02-26 17:27:07 +00:00
RELATE
REMOVE
2016-05-23 12:32:02 +00:00
RETURN
2016-09-06 13:30:59 +00:00
ROLLBACK
RULES
SCHEMAFULL
SCHEMALESS
2016-02-26 17:27:07 +00:00
SELECT
SET
2016-09-06 13:30:59 +00:00
SOMECONTAINEDIN
2016-02-26 17:27:07 +00:00
START
2016-05-23 12:32:02 +00:00
TABLE
2016-02-26 17:27:07 +00:00
TO
2016-09-06 13:30:59 +00:00
TRANSACTION
2016-02-26 17:27:07 +00:00
TRUE
2016-05-23 12:32:02 +00:00
TYPE
2016-02-26 17:27:07 +00:00
UNIQUE
UPDATE
UPSERT
2016-05-23 12:32:02 +00:00
USE
2016-09-06 13:30:59 +00:00
VALIDATE
2016-02-26 17:27:07 +00:00
VERSION
2016-09-20 23:36:37 +00:00
VIEW
2016-05-23 12:32:02 +00:00
VOID
2016-02-26 17:27:07 +00:00
WHERE
keywordsEnd
)
var tokens = [...]string{
ILLEGAL: "ILLEGAL",
EOF: "EOF",
WS: "WS",
// literals
2016-09-07 15:44:23 +00:00
DATE: "DATE",
TIME: "TIME",
PATH: "PATH",
JSON: "JSON",
IDENT: "IDENT",
THING: "THING",
STRING: "STRING",
REGION: "REGION",
NUMBER: "NUMBER",
DOUBLE: "DOUBLE",
REGEX: "REGEX",
ARRAY: "ARRAY",
DURATION: "DURATION",
PARAM: "PARAM",
2016-02-26 17:27:07 +00:00
DOT: ".",
COMMA: ",",
2016-09-06 13:30:59 +00:00
QMARK: "?",
2016-02-26 17:27:07 +00:00
LPAREN: "(",
RPAREN: ")",
LBRACK: "[",
RBRACK: "]",
COLON: ":",
SEMICOLON: ";",
// operators
ADD: "+",
SUB: "-",
MUL: "*",
DIV: "/",
INC: "+=",
DEC: "-=",
EQ: "=",
2016-09-06 13:30:59 +00:00
EEQ: "==",
EXC: "!",
2016-02-26 17:27:07 +00:00
NEQ: "!=",
2016-09-06 13:30:59 +00:00
NEE: "!==",
ANY: "?=",
2016-02-26 17:27:07 +00:00
LT: "<",
LTE: "<=",
GT: ">",
GTE: ">=",
2016-09-06 13:30:59 +00:00
SIN: "∋",
SNI: "∌",
INS: "∈",
NIS: "∉",
OEDGE: "->",
IEDGE: "<-",
BEDGE: "<->",
2016-02-26 17:27:07 +00:00
// keywords
2016-09-06 13:30:59 +00:00
ACCEPT: "ACCEPT",
AFTER: "AFTER",
ALL: "ALL",
ALLCONTAINEDIN: "ALLCONTAINEDIN",
AND: "AND",
AS: "AS",
ASC: "ASC",
AT: "AT",
BEFORE: "BEFORE",
BEGIN: "BEGIN",
BOTH: "BOTH",
BY: "BY",
CANCEL: "CANCEL",
CODE: "CODE",
COLUMNS: "COLUMNS",
COMMIT: "COMMIT",
CONTAINS: "CONTAINS",
CONTAINSALL: "CONTAINSALL",
CONTAINSNONE: "CONTAINSNONE",
CONTAINSSOME: "CONTAINSSOME",
CONTENT: "CONTENT",
CREATE: "CREATE",
CUSTOM: "CUSTOM",
DATABASE: "DATABASE",
DEFAULT: "DEFAULT",
DEFINE: "DEFINE",
DELETE: "DELETE",
DESC: "DESC",
DIFF: "DIFF",
DISTINCT: "DISTINCT",
EMPTY: "EMPTY",
ENUM: "ENUM",
EXPUNGE: "EXPUNGE",
FALSE: "FALSE",
FIELD: "FIELD",
FOR: "FOR",
FROM: "FROM",
GROUP: "GROUP",
HISTORY: "HISTORY",
ID: "ID",
2016-10-14 21:06:05 +00:00
IF: "IF",
2016-09-06 13:30:59 +00:00
IN: "IN",
INDEX: "INDEX",
2016-09-19 10:08:44 +00:00
INFO: "INFO",
2016-09-06 13:30:59 +00:00
INSERT: "INSERT",
INTO: "INTO",
IS: "IS",
LET: "LET",
LIMIT: "LIMIT",
MANDATORY: "MANDATORY",
MATCH: "MATCH",
MAX: "MAX",
MERGE: "MERGE",
MIN: "MIN",
MISSING: "MISSING",
MODIFY: "MODIFY",
MULTI: "MULTI",
NAMESPACE: "NAMESPACE",
NONE: "NONE",
NONECONTAINEDIN: "NONECONTAINEDIN",
NOT: "NOT",
NOTNULL: "NOTNULL",
NOW: "NOW",
NULL: "NULL",
ON: "ON",
OR: "OR",
ORDER: "ORDER",
READONLY: "READONLY",
REJECT: "REJECT",
RELATE: "RELATE",
REMOVE: "REMOVE",
RETURN: "RETURN",
ROLLBACK: "ROLLBACK",
RULES: "RULES",
SCHEMAFULL: "SCHEMAFULL",
SCHEMALESS: "SCHEMALESS",
2016-09-06 13:30:59 +00:00
SELECT: "SELECT",
SET: "SET",
SOMECONTAINEDIN: "SOMECONTAINEDIN",
START: "START",
TABLE: "TABLE",
TO: "TO",
TRANSACTION: "TRANSACTION",
TRUE: "TRUE",
TYPE: "TYPE",
UNIQUE: "UNIQUE",
UPDATE: "UPDATE",
UPSERT: "UPSERT",
USE: "USE",
VALIDATE: "VALIDATE",
VERSION: "VERSION",
2016-09-20 23:36:37 +00:00
VIEW: "VIEW",
2016-09-06 13:30:59 +00:00
VOID: "VOID",
WHERE: "WHERE",
2016-02-26 17:27:07 +00:00
}
var literals map[string]Token
var operator map[string]Token
var keywords map[string]Token
func init() {
literals = make(map[string]Token)
for tok := literalsBeg + 1; tok < literalsEnd; tok++ {
literals[tokens[tok]] = tok
}
operator = make(map[string]Token)
for tok := operatorBeg + 1; tok < operatorEnd; tok++ {
operator[tokens[tok]] = tok
}
keywords = make(map[string]Token)
for tok := keywordsBeg + 1; tok < keywordsEnd; tok++ {
keywords[tokens[tok]] = tok
}
}
func lookup(lookups []Token) (literals []string) {
for _, token := range lookups {
literals = append(literals, token.String())
}
return
}
func (tok Token) precedence() int {
switch tok {
case OR:
return 1
case AND:
return 2
2016-09-06 13:30:59 +00:00
case EQ, NEQ, EEQ, NEE,
LT, LTE, GT, GTE,
ANY, SIN, SNI, INS, NIS,
CONTAINSALL, CONTAINSNONE, CONTAINSSOME,
ALLCONTAINEDIN, NONECONTAINEDIN, SOMECONTAINEDIN:
2016-02-26 17:27:07 +00:00
return 3
case ADD, SUB:
return 4
case MUL, DIV:
return 5
}
return 0
}
func (tok Token) String() string {
if tok >= 0 && tok < Token(len(tokens)) {
return tokens[tok]
}
return ""
}
func (tok Token) isLiteral() bool { return tok > literalsBeg && tok < literalsEnd }
func (tok Token) isKeyword() bool { return tok > keywordsBeg && tok < keywordsEnd }
func (tok Token) isOperator() bool { return tok > operatorBeg && tok < operatorEnd }