token.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. package lexer
  2. import "fmt"
  3. type TokenType int
  4. const (
  5. // Special tokens
  6. TokenEOF TokenType = iota
  7. TokenError
  8. TokenComment
  9. // Literals
  10. TokenIdent // identifiers
  11. TokenNumber // integers and floats
  12. TokenString // 'string literals'
  13. TokenBlob // X'hex' blob literals
  14. // Operators
  15. TokenPlus // +
  16. TokenMinus // -
  17. TokenStar // *
  18. TokenSlash // /
  19. TokenPercent // %
  20. TokenConcat // ||
  21. TokenArrow // ->
  22. TokenArrowText // ->>
  23. TokenEq // =
  24. TokenNeq // <> or !=
  25. TokenLt // <
  26. TokenLte // <=
  27. TokenGt // >
  28. TokenGte // >=
  29. TokenBitAnd // &
  30. TokenBitOr // |
  31. TokenBitNot // ~
  32. TokenShiftLeft // <<
  33. TokenShiftRight // >>
  34. // Punctuation
  35. TokenLParen // (
  36. TokenRParen // )
  37. TokenComma // ,
  38. TokenSemicolon // ;
  39. TokenDot // .
  40. // SQL Keywords - DML
  41. TokenSELECT
  42. TokenFROM
  43. TokenWHERE
  44. TokenAND
  45. TokenOR
  46. TokenNOT
  47. TokenAS
  48. TokenDISTINCT
  49. TokenALL
  50. TokenRETURNING
  51. TokenINSERT
  52. TokenINTO
  53. TokenVALUES
  54. TokenUPDATE
  55. TokenSET
  56. TokenDELETE
  57. // SQL Keywords - DDL
  58. TokenCREATE
  59. TokenDROP
  60. TokenALTER
  61. TokenTABLE
  62. TokenINDEX
  63. TokenVIEW
  64. TokenDATABASE
  65. TokenSCHEMA
  66. TokenADD
  67. TokenCOLUMN
  68. TokenRENAME
  69. TokenTO
  70. // SQL Keywords - Constraints
  71. TokenPRIMARY
  72. TokenKEY
  73. TokenFOREIGN
  74. TokenREFERENCES
  75. TokenUNIQUE
  76. TokenCHECK
  77. TokenCONSTRAINT
  78. TokenDEFAULT
  79. TokenAUTOINCREMENT
  80. // SQL Keywords - Clauses
  81. TokenORDER
  82. TokenBY
  83. TokenASC
  84. TokenDESC
  85. TokenLIMIT
  86. TokenOFFSET
  87. TokenGROUP
  88. TokenHAVING
  89. // SQL Keywords - Joins
  90. TokenJOIN
  91. TokenINNER
  92. TokenLEFT
  93. TokenRIGHT
  94. TokenFULL
  95. TokenOUTER
  96. TokenCROSS
  97. TokenNATURAL
  98. TokenON
  99. TokenUSING
  100. // SQL Keywords - Set operations
  101. TokenUNION
  102. TokenINTERSECT
  103. TokenEXCEPT
  104. // SQL Keywords - Predicates
  105. TokenIN
  106. TokenBETWEEN
  107. TokenLIKE
  108. TokenGLOB
  109. TokenESCAPE
  110. TokenIS
  111. TokenNULL
  112. TokenEXISTS
  113. // SQL Keywords - CASE
  114. TokenCASE
  115. TokenWHEN
  116. TokenTHEN
  117. TokenELSE
  118. TokenEND
  119. // SQL Keywords - Other
  120. TokenCAST
  121. TokenCOALESCE
  122. TokenNULLIF
  123. TokenIF
  124. // Boolean literals
  125. TokenTRUE
  126. TokenFALSE
  127. // Data types
  128. TokenINTEGER
  129. TokenINT
  130. TokenTINYINT
  131. TokenSMALLINT
  132. TokenMEDIUMINT
  133. TokenBIGINT
  134. TokenREAL
  135. TokenFLOAT
  136. TokenDOUBLE
  137. TokenNUMERIC
  138. TokenDECIMAL
  139. TokenTEXT
  140. TokenVARCHAR
  141. TokenCHAR
  142. TokenCHARACTER
  143. TokenCLOB
  144. TokenNCHAR
  145. TokenNVARCHAR
  146. TokenBLOB
  147. TokenBOOLEAN
  148. TokenDATE
  149. TokenTIME
  150. TokenTIMESTAMP
  151. TokenDATETIME
  152. TokenJSON
  153. TokenJSONB
  154. // Transaction keywords
  155. TokenBEGIN
  156. TokenCOMMIT
  157. TokenROLLBACK
  158. TokenTRANSACTION
  159. TokenSAVEPOINT
  160. TokenRELEASE
  161. // SQLite specific
  162. TokenPRAGMA
  163. TokenEXPLAIN
  164. TokenQUERY
  165. TokenPLAN
  166. TokenATTACH
  167. TokenDETACH
  168. TokenVACUUM
  169. TokenANALYZE
  170. TokenREINDEX
  171. // Conflict resolution
  172. TokenREPLACE
  173. TokenIGNORE
  174. TokenFAIL
  175. TokenABORT
  176. TokenCONFLICT
  177. TokenDO
  178. TokenNOTHING
  179. )
  180. var keywords = map[string]TokenType{
  181. // DML
  182. "SELECT": TokenSELECT,
  183. "FROM": TokenFROM,
  184. "WHERE": TokenWHERE,
  185. "AND": TokenAND,
  186. "OR": TokenOR,
  187. "NOT": TokenNOT,
  188. "AS": TokenAS,
  189. "DISTINCT": TokenDISTINCT,
  190. "ALL": TokenALL,
  191. // RETURNING is a keyword so it is not mistaken for a table/column alias in
  192. // INSERT ... SELECT ... RETURNING.
  193. "RETURNING": TokenRETURNING,
  194. "INSERT": TokenINSERT,
  195. "INTO": TokenINTO,
  196. "VALUES": TokenVALUES,
  197. "UPDATE": TokenUPDATE,
  198. "SET": TokenSET,
  199. "DELETE": TokenDELETE,
  200. // DDL
  201. "CREATE": TokenCREATE,
  202. "DROP": TokenDROP,
  203. "ALTER": TokenALTER,
  204. "TABLE": TokenTABLE,
  205. "INDEX": TokenINDEX,
  206. "VIEW": TokenVIEW,
  207. "DATABASE": TokenDATABASE,
  208. "SCHEMA": TokenSCHEMA,
  209. "ADD": TokenADD,
  210. "COLUMN": TokenCOLUMN,
  211. "RENAME": TokenRENAME,
  212. "TO": TokenTO,
  213. // Constraints
  214. "PRIMARY": TokenPRIMARY,
  215. "KEY": TokenKEY,
  216. "FOREIGN": TokenFOREIGN,
  217. "REFERENCES": TokenREFERENCES,
  218. "UNIQUE": TokenUNIQUE,
  219. "CHECK": TokenCHECK,
  220. "CONSTRAINT": TokenCONSTRAINT,
  221. "DEFAULT": TokenDEFAULT,
  222. "AUTOINCREMENT": TokenAUTOINCREMENT,
  223. // Clauses
  224. "ORDER": TokenORDER,
  225. "BY": TokenBY,
  226. "ASC": TokenASC,
  227. "DESC": TokenDESC,
  228. "LIMIT": TokenLIMIT,
  229. "OFFSET": TokenOFFSET,
  230. "GROUP": TokenGROUP,
  231. "HAVING": TokenHAVING,
  232. // Joins
  233. "JOIN": TokenJOIN,
  234. "INNER": TokenINNER,
  235. "LEFT": TokenLEFT,
  236. "RIGHT": TokenRIGHT,
  237. "FULL": TokenFULL,
  238. "OUTER": TokenOUTER,
  239. "CROSS": TokenCROSS,
  240. "NATURAL": TokenNATURAL,
  241. "ON": TokenON,
  242. "USING": TokenUSING,
  243. // Set operations
  244. "UNION": TokenUNION,
  245. "INTERSECT": TokenINTERSECT,
  246. "EXCEPT": TokenEXCEPT,
  247. // Predicates
  248. "IN": TokenIN,
  249. "BETWEEN": TokenBETWEEN,
  250. "LIKE": TokenLIKE,
  251. "GLOB": TokenGLOB,
  252. "ESCAPE": TokenESCAPE,
  253. "IS": TokenIS,
  254. "NULL": TokenNULL,
  255. "EXISTS": TokenEXISTS,
  256. // CASE
  257. "CASE": TokenCASE,
  258. "WHEN": TokenWHEN,
  259. "THEN": TokenTHEN,
  260. "ELSE": TokenELSE,
  261. "END": TokenEND,
  262. // Other
  263. "CAST": TokenCAST,
  264. "COALESCE": TokenCOALESCE,
  265. "NULLIF": TokenNULLIF,
  266. "IF": TokenIF,
  267. // Boolean
  268. "TRUE": TokenTRUE,
  269. "FALSE": TokenFALSE,
  270. // Data types
  271. "INTEGER": TokenINTEGER,
  272. "INT": TokenINT,
  273. "TINYINT": TokenTINYINT,
  274. "SMALLINT": TokenSMALLINT,
  275. "MEDIUMINT": TokenMEDIUMINT,
  276. "BIGINT": TokenBIGINT,
  277. "REAL": TokenREAL,
  278. "FLOAT": TokenFLOAT,
  279. "DOUBLE": TokenDOUBLE,
  280. "NUMERIC": TokenNUMERIC,
  281. "DECIMAL": TokenDECIMAL,
  282. "TEXT": TokenTEXT,
  283. "VARCHAR": TokenVARCHAR,
  284. "CHAR": TokenCHAR,
  285. "CHARACTER": TokenCHARACTER,
  286. "CLOB": TokenCLOB,
  287. "NCHAR": TokenNCHAR,
  288. "NVARCHAR": TokenNVARCHAR,
  289. "BLOB": TokenBLOB,
  290. "BOOLEAN": TokenBOOLEAN,
  291. "DATE": TokenDATE,
  292. "TIME": TokenTIME,
  293. "TIMESTAMP": TokenTIMESTAMP,
  294. "DATETIME": TokenDATETIME,
  295. "JSON": TokenJSON,
  296. "JSONB": TokenJSONB,
  297. // Transactions
  298. "BEGIN": TokenBEGIN,
  299. "COMMIT": TokenCOMMIT,
  300. "ROLLBACK": TokenROLLBACK,
  301. "TRANSACTION": TokenTRANSACTION,
  302. "SAVEPOINT": TokenSAVEPOINT,
  303. "RELEASE": TokenRELEASE,
  304. // SQLite specific
  305. "PRAGMA": TokenPRAGMA,
  306. "EXPLAIN": TokenEXPLAIN,
  307. "QUERY": TokenQUERY,
  308. "ATTACH": TokenATTACH,
  309. "DETACH": TokenDETACH,
  310. "VACUUM": TokenVACUUM,
  311. "ANALYZE": TokenANALYZE,
  312. "REINDEX": TokenREINDEX,
  313. // Conflict resolution
  314. "REPLACE": TokenREPLACE,
  315. "IGNORE": TokenIGNORE,
  316. "FAIL": TokenFAIL,
  317. "ABORT": TokenABORT,
  318. "CONFLICT": TokenCONFLICT,
  319. "DO": TokenDO,
  320. "NOTHING": TokenNOTHING,
  321. }
  322. // LookupKeyword returns the token type for an identifier.
  323. // If the identifier is a keyword, returns the keyword token type.
  324. // Otherwise, returns TokenIdent.
  325. func LookupKeyword(ident string) TokenType {
  326. if tok, ok := keywords[ident]; ok {
  327. return tok
  328. }
  329. return TokenIdent
  330. }
  331. // Token represents a lexical token.
  332. type Token struct {
  333. Type TokenType
  334. Literal string
  335. Line int
  336. Column int
  337. }
  338. func (t Token) String() string {
  339. return fmt.Sprintf("Token{Type: %v, Literal: %q, Line: %d, Col: %d}",
  340. t.Type, t.Literal, t.Line, t.Column)
  341. }
  342. // IsKeyword returns true if the token is a SQL keyword.
  343. func (t Token) IsKeyword() bool {
  344. return t.Type >= TokenSELECT
  345. }
  346. // IsOperator returns true if the token is an operator.
  347. func (t Token) IsOperator() bool {
  348. return t.Type >= TokenPlus && t.Type <= TokenGte
  349. }
  350. var tokenNames = map[TokenType]string{
  351. TokenEOF: "EOF",
  352. TokenError: "ERROR",
  353. TokenComment: "COMMENT",
  354. TokenIdent: "IDENT",
  355. TokenNumber: "NUMBER",
  356. TokenString: "STRING",
  357. TokenBlob: "BLOB",
  358. TokenPlus: "+",
  359. TokenMinus: "-",
  360. TokenStar: "*",
  361. TokenSlash: "/",
  362. TokenPercent: "%",
  363. TokenConcat: "||",
  364. TokenArrow: "->",
  365. TokenArrowText: "->>",
  366. TokenEq: "=",
  367. TokenNeq: "<>",
  368. TokenLt: "<",
  369. TokenLte: "<=",
  370. TokenGt: ">",
  371. TokenGte: ">=",
  372. TokenBitAnd: "&",
  373. TokenBitOr: "|",
  374. TokenBitNot: "~",
  375. TokenShiftLeft: "<<",
  376. TokenShiftRight: ">>",
  377. TokenLParen: "(",
  378. TokenRParen: ")",
  379. TokenComma: ",",
  380. TokenSemicolon: ";",
  381. TokenDot: ".",
  382. }
  383. func (t TokenType) String() string {
  384. if name, ok := tokenNames[t]; ok {
  385. return name
  386. }
  387. // For keywords, look up in reverse
  388. for kw, tok := range keywords {
  389. if tok == t {
  390. return kw
  391. }
  392. }
  393. return fmt.Sprintf("TOKEN(%d)", t)
  394. }