You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
358 lines
6.7 KiB
Go
358 lines
6.7 KiB
Go
2 years ago
|
package token
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/zeromicro/go-zero/tools/goctl/pkg/parser/api/placeholder"
|
||
|
"github.com/zeromicro/go-zero/tools/goctl/util"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
Syntax = "syntax"
|
||
|
Info = "info"
|
||
|
Service = "service"
|
||
|
Returns = "returns"
|
||
|
Any = "any"
|
||
|
TypeKeyword = "type"
|
||
|
MapKeyword = "map"
|
||
|
ImportKeyword = "import"
|
||
|
)
|
||
|
|
||
|
// Type is the type of token.
|
||
|
type Type int
|
||
|
|
||
|
// EofToken is the end of file token.
|
||
|
var EofToken = Token{Type: EOF}
|
||
|
|
||
|
// ErrorToken is the error token.
|
||
|
var ErrorToken = Token{Type: error}
|
||
|
|
||
|
// Token is the token of a rune.
|
||
|
type Token struct {
|
||
|
Type Type
|
||
|
Text string
|
||
|
Position Position
|
||
|
}
|
||
|
|
||
|
// Fork forks token for a given Type.
|
||
|
func (t Token) Fork(tp Type) Token {
|
||
|
return Token{
|
||
|
Type: tp,
|
||
|
Text: t.Text,
|
||
|
Position: t.Position,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// IsEmptyString returns true if the token is empty string.
|
||
|
func (t Token) IsEmptyString() bool {
|
||
|
if t.Type != STRING && t.Type != RAW_STRING {
|
||
|
return false
|
||
|
}
|
||
|
text := util.TrimWhiteSpace(t.Text)
|
||
|
return text == `""` || text == "``"
|
||
|
}
|
||
|
|
||
|
// IsComment returns true if the token is comment.
|
||
|
func (t Token) IsComment() bool {
|
||
|
return t.IsType(COMMENT)
|
||
|
}
|
||
|
|
||
|
// IsDocument returns true if the token is document.
|
||
|
func (t Token) IsDocument() bool {
|
||
|
return t.IsType(DOCUMENT)
|
||
|
}
|
||
|
|
||
|
// IsType returns true if the token is the given type.
|
||
|
func (t Token) IsType(tp Type) bool {
|
||
|
return t.Type == tp
|
||
|
}
|
||
|
|
||
|
// Line returns the line number of the token.
|
||
|
func (t Token) Line() int {
|
||
|
return t.Position.Line
|
||
|
}
|
||
|
|
||
|
// String returns the string of the token.
|
||
|
func (t Token) String() string {
|
||
|
if t == ErrorToken {
|
||
|
return t.Type.String()
|
||
|
}
|
||
|
return fmt.Sprintf("%s %s %s", t.Position.String(), t.Type.String(), t.Text)
|
||
|
}
|
||
|
|
||
|
// Valid returns true if the token is valid.
|
||
|
func (t Token) Valid() bool {
|
||
|
return t.Type != token_bg
|
||
|
}
|
||
|
|
||
|
// IsKeyword returns true if the token is keyword.
|
||
|
func (t Token) IsKeyword() bool {
|
||
|
return golang_keyword_beg < t.Type && t.Type < golang_keyword_end
|
||
|
}
|
||
|
|
||
|
// IsBaseType returns true if the token is base type.
|
||
|
func (t Token) IsBaseType() bool {
|
||
|
_, ok := baseDataType[t.Text]
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
// IsHttpMethod returns true if the token is http method.
|
||
|
func (t Token) IsHttpMethod() bool {
|
||
|
_, ok := httpMethod[t.Text]
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
// Is returns true if the token text is one of the given list.
|
||
|
func (t Token) Is(text ...string) bool {
|
||
|
for _, v := range text {
|
||
|
if t.Text == v {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
token_bg Type = iota
|
||
|
error
|
||
|
ILLEGAL
|
||
|
EOF
|
||
|
COMMENT
|
||
|
DOCUMENT
|
||
|
|
||
|
literal_beg
|
||
|
IDENT // main
|
||
|
INT // 123
|
||
|
DURATION // 3s,3ms
|
||
|
STRING // "abc"
|
||
|
RAW_STRING // `abc`
|
||
|
PATH // `abc`
|
||
|
KEY // `abc:`
|
||
|
literal_end
|
||
|
|
||
|
operator_beg
|
||
|
SUB // -
|
||
|
MUL // *
|
||
|
QUO // /
|
||
|
ASSIGN // =
|
||
|
|
||
|
LPAREN // (
|
||
|
LBRACK // [
|
||
|
LBRACE // {
|
||
|
COMMA // ,
|
||
|
DOT // .
|
||
|
|
||
|
RPAREN // )
|
||
|
RBRACE // }
|
||
|
RBRACK // ]
|
||
|
SEMICOLON // ;
|
||
|
COLON // :
|
||
|
ELLIPSIS
|
||
|
operator_end
|
||
|
|
||
|
golang_keyword_beg
|
||
|
BREAK
|
||
|
CASE
|
||
|
CHAN
|
||
|
CONST
|
||
|
CONTINUE
|
||
|
|
||
|
DEFAULT
|
||
|
DEFER
|
||
|
ELSE
|
||
|
FALLTHROUGH
|
||
|
FOR
|
||
|
|
||
|
FUNC
|
||
|
GO
|
||
|
GOTO
|
||
|
IF
|
||
|
IMPORT
|
||
|
|
||
|
INTERFACE
|
||
|
MAP
|
||
|
PACKAGE
|
||
|
RANGE
|
||
|
RETURN
|
||
|
|
||
|
SELECT
|
||
|
STRUCT
|
||
|
SWITCH
|
||
|
TYPE
|
||
|
VAR
|
||
|
golang_keyword_end
|
||
|
|
||
|
api_keyword_bg
|
||
|
AT_DOC
|
||
|
AT_HANDLER
|
||
|
AT_SERVER
|
||
|
ANY
|
||
|
|
||
|
api_keyword_end
|
||
|
token_end
|
||
|
)
|
||
|
|
||
|
// String returns the string of the token type.
|
||
|
func (t Type) String() string {
|
||
|
if t >= token_bg && t < token_end {
|
||
|
return tokens[t]
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
var tokens = [...]string{
|
||
|
ILLEGAL: "ILLEGAL",
|
||
|
|
||
|
EOF: "EOF",
|
||
|
COMMENT: "COMMENT",
|
||
|
DOCUMENT: "DOCUMENT",
|
||
|
|
||
|
IDENT: "IDENT",
|
||
|
INT: "INT",
|
||
|
DURATION: "DURATION",
|
||
|
STRING: "STRING",
|
||
|
RAW_STRING: "RAW_STRING",
|
||
|
PATH: "PATH",
|
||
|
KEY: "KEY",
|
||
|
|
||
|
SUB: "-",
|
||
|
MUL: "*",
|
||
|
QUO: "/",
|
||
|
ASSIGN: "=",
|
||
|
|
||
|
LPAREN: "(",
|
||
|
LBRACK: "[",
|
||
|
LBRACE: "{",
|
||
|
COMMA: ",",
|
||
|
DOT: ".",
|
||
|
|
||
|
RPAREN: ")",
|
||
|
RBRACK: "]",
|
||
|
RBRACE: "}",
|
||
|
SEMICOLON: ";",
|
||
|
COLON: ":",
|
||
|
ELLIPSIS: "...",
|
||
|
|
||
|
BREAK: "break",
|
||
|
CASE: "case",
|
||
|
CHAN: "chan",
|
||
|
CONST: "const",
|
||
|
CONTINUE: "continue",
|
||
|
|
||
|
DEFAULT: "default",
|
||
|
DEFER: "defer",
|
||
|
ELSE: "else",
|
||
|
FALLTHROUGH: "fallthrough",
|
||
|
FOR: "for",
|
||
|
|
||
|
FUNC: "func",
|
||
|
GO: "go",
|
||
|
GOTO: "goto",
|
||
|
IF: "if",
|
||
|
IMPORT: "import",
|
||
|
|
||
|
INTERFACE: "interface",
|
||
|
MAP: "map",
|
||
|
PACKAGE: "package",
|
||
|
RANGE: "range",
|
||
|
RETURN: "return",
|
||
|
|
||
|
SELECT: "select",
|
||
|
STRUCT: "struct",
|
||
|
SWITCH: "switch",
|
||
|
TYPE: "type",
|
||
|
VAR: "var",
|
||
|
|
||
|
AT_DOC: "@doc",
|
||
|
AT_HANDLER: "@handler",
|
||
|
AT_SERVER: "@server",
|
||
|
ANY: "interface{}",
|
||
|
}
|
||
|
|
||
|
// HttpMethods returns the http methods.
|
||
|
var HttpMethods = []interface{}{"get", "head", "post", "put", "patch", "delete", "connect", "options", "trace"}
|
||
|
|
||
|
var httpMethod = map[string]placeholder.Type{
|
||
|
"get": placeholder.PlaceHolder,
|
||
|
"head": placeholder.PlaceHolder,
|
||
|
"post": placeholder.PlaceHolder,
|
||
|
"put": placeholder.PlaceHolder,
|
||
|
"patch": placeholder.PlaceHolder,
|
||
|
"delete": placeholder.PlaceHolder,
|
||
|
"connect": placeholder.PlaceHolder,
|
||
|
"options": placeholder.PlaceHolder,
|
||
|
"trace": placeholder.PlaceHolder,
|
||
|
}
|
||
|
|
||
|
var keywords = map[string]Type{
|
||
|
// golang_keyword_bg
|
||
|
"break": BREAK,
|
||
|
"case": CASE,
|
||
|
"chan": CHAN,
|
||
|
"const": CONST,
|
||
|
"continue": CONTINUE,
|
||
|
|
||
|
"default": DEFAULT,
|
||
|
"defer": DEFER,
|
||
|
"else": ELSE,
|
||
|
"fallthrough": FALLTHROUGH,
|
||
|
"for": FOR,
|
||
|
|
||
|
"func": FUNC,
|
||
|
"go": GO,
|
||
|
"goto": GOTO,
|
||
|
"if": IF,
|
||
|
"import": IMPORT,
|
||
|
|
||
|
"interface": INTERFACE,
|
||
|
"map": MAP,
|
||
|
"package": PACKAGE,
|
||
|
"range": RANGE,
|
||
|
"return": RETURN,
|
||
|
|
||
|
"select": SELECT,
|
||
|
"struct": STRUCT,
|
||
|
"switch": SWITCH,
|
||
|
"type": TYPE,
|
||
|
"var": VAR,
|
||
|
// golang_keyword_end
|
||
|
}
|
||
|
|
||
|
var baseDataType = map[string]placeholder.Type{
|
||
|
"bool": placeholder.PlaceHolder,
|
||
|
"uint8": placeholder.PlaceHolder,
|
||
|
"uint16": placeholder.PlaceHolder,
|
||
|
"uint32": placeholder.PlaceHolder,
|
||
|
"uint64": placeholder.PlaceHolder,
|
||
|
"int8": placeholder.PlaceHolder,
|
||
|
"int16": placeholder.PlaceHolder,
|
||
|
"int32": placeholder.PlaceHolder,
|
||
|
"int64": placeholder.PlaceHolder,
|
||
|
"float32": placeholder.PlaceHolder,
|
||
|
"float64": placeholder.PlaceHolder,
|
||
|
"complex64": placeholder.PlaceHolder,
|
||
|
"complex128": placeholder.PlaceHolder,
|
||
|
"string": placeholder.PlaceHolder,
|
||
|
"int": placeholder.PlaceHolder,
|
||
|
"uint": placeholder.PlaceHolder,
|
||
|
"uintptr": placeholder.PlaceHolder,
|
||
|
"byte": placeholder.PlaceHolder,
|
||
|
"rune": placeholder.PlaceHolder,
|
||
|
"any": placeholder.PlaceHolder,
|
||
|
}
|
||
|
|
||
|
// LookupKeyword returns the keyword type if the given ident is keyword.
|
||
|
func LookupKeyword(ident string) (Type, bool) {
|
||
|
tp, ok := keywords[ident]
|
||
|
return tp, ok
|
||
|
}
|
||
|
|
||
|
// NewIllegalToken returns a new illegal token.
|
||
|
func NewIllegalToken(b rune, pos Position) Token {
|
||
|
return Token{
|
||
|
Type: ILLEGAL,
|
||
|
Text: string(b),
|
||
|
Position: pos,
|
||
|
}
|
||
|
}
|