2
0

token.go 7.4 KB

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