sources/cql.l (305 lines of code) (raw):

%option noyywrap nodefault yylineno case-insensitive never-interactive %{ /* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // In case there is any doubt, 'cql.l' is included in the license as well as // the code flex generates from it. #include "cql.y.h" #include <stdarg.h> #include <string.h> #include <stdio.h> #include <cql.h> #include <charbuf.h> #include <encoders.h> void yyerror(const char *s, ...); void line_directive(const char *); char *Strdup(const char *); int fileno(FILE *); static CSTR last_doc_comment = NULL; // the lexer has unused functions and implicit conversions, not easily removed #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wconversion" cql_noexport CSTR get_last_doc_comment() { CSTR result = last_doc_comment; last_doc_comment = NULL; return result; } %} stop [^A-Z_0-9] sp [ \t]+ hex [0-9A-F] d [0-9] %% EXCLUDE{sp}NO{sp}OTHERS/{stop} { return EXCLUDE_NO_OTHERS; } EXCLUDE{sp}CURRENT{sp}ROW/{stop} { return EXCLUDE_CURRENT_ROW; } EXCLUDE{sp}GROUP/{stop} { return EXCLUDE_GROUP; } EXCLUDE{sp}TIES/{stop} { return EXCLUDE_TIES; } CURRENT{sp}ROW/{stop} { return CURRENT_ROW; } UNBOUNDED { return UNBOUNDED; } PRECEDING { return PRECEDING; } FOLLOWING { return FOLLOWING; } SWITCH { return SWITCH; } RANGE { return RANGE; } ENUM { return ENUM; } ROWS { return ROWS; } GROUPS { return GROUPS; } PARTITION { return PARTITION; } FILTER { return FILTER; } WINDOW { return WINDOW; } EXPLAIN { return EXPLAIN; } QUERY{sp}PLAN/{stop} { return QUERY_PLAN; } SELECT { return SELECT; } CAST { return CAST; } CREATE { return CREATE; } DROP { return DROP; } TABLE { return TABLE; } TEMP { return TEMP; } COLLATE { return COLLATE; } HIDDEN { return HIDDEN; } PRIMARY { return PRIMARY; } KEY { return KEY; } IF { return IF; } WHILE { return WHILE; } CALL { return CALL; } EXISTS { return EXISTS; } UNION { return UNION; } UNION{sp}ALL/{stop} { return UNION_ALL; } INTERSECT { return INTERSECT; } EXCEPT { return EXCEPT; } NOT { return NOT; } NULL { return NULL_; } TRUE { return TRUE_; } FALSE { return FALSE_; } DEFAULT { return DEFAULT; } CHECK { return CHECK; } LET { return LET; } LONG { return LONG_; } LONG_INTEGER { return LONG_INTEGER; } LONG_INT { return LONG_INT; } INT { return INT_; } INTEGER { return INTEGER; } TEXT { return TEXT; } VIRTUAL { return VIRTUAL; } WITH { return WITH; } RECURSIVE { return RECURSIVE; } WITHOUT { return WITHOUT; } ROWID { return ROWID; } AUTOINCREMENT { return AUTOINCREMENT; } BOOL { return BOOL_; } REFERENCES { return REFERENCES; } FOREIGN { return FOREIGN; } REAL { return REAL; } CASCADE { return CASCADE; } ON { return ON; } ON{sp}CONFLICT/{stop} { return ON_CONFLICT; } DO { return DO; } NOTHING { return NOTHING; } UPDATE { return UPDATE; } DELETE { return DELETE; } CONST { return CONST; } CONSTRAINT { return CONSTRAINT; } UNIQUE { return UNIQUE; } PRIVATE { return PRIVATE; } INDEX { return INDEX; } ALL { return ALL; } AS { return AS; } BY { return BY; } DISTINCT { return DISTINCT; } DISTINCTROW { return DISTINCTROW; } INNER { return INNER; } OUTER { return OUTER; } CROSS { return CROSS; } USING { return USING; } RIGHT { return RIGHT; } FROM { return FROM; } FROM{sp}BLOB/{stop} { return FROM_BLOB; } WHERE { return WHERE; } GROUP { return GROUP; } HAVING { return HAVING; } ASC { return ASC; } DESC { return DESC; } LEFT { return LEFT; } JOIN { return JOIN; } SET { return SET; } OVER { return OVER; } "<<" { return LS; } ">>" { return RS; } "<>" { return NE; } "!=" { return NE_; } ">=" { return GE; } "<=" { return LE; } ":=" { return ASSIGN; } "==" { return EQEQ; } "||" { return CONCAT; } IS{sp}NOT{sp}FALSE/{stop} { return IS_NOT_FALSE; } IS{sp}NOT{sp}TRUE/{stop} { return IS_NOT_TRUE; } IS{sp}FALSE/{stop} { return IS_FALSE; } IS{sp}TRUE/{stop} { return IS_TRUE; } IS{sp}NOT/{stop} { return IS_NOT; } ISNULL { return ISNULL; } NOTNULL { return NOTNULL; } IS { return IS; } AND { return AND; } ORDER { return ORDER; } CASE { return CASE; } END { return END; } WHEN { return WHEN; } ELSE { return ELSE; } THEN { return THEN; } VIEW { return VIEW; } INSERT { return INSERT; } INTO { return INTO; } VALUES { return VALUES; } OR { return OR; } LIMIT { return LIMIT; } OFFSET { return OFFSET; } PROC { return PROC; } @PROC { return AT_PROC; } @RC { return AT_RC; } PROCEDURE { return PROCEDURE; } FUNCTION { return FUNCTION; } FUNC { return FUNC; } BEGIN { return BEGIN_; } IN { return IN; } NOT{sp}IN/{stop} { return NOT_IN; } TO { return TO; } FOR { return FOR; } THROW { return THROW; } TRY { return TRY; } CATCH { return CATCH; } NOT{sp}LIKE/{stop} { return NOT_LIKE; } LIKE { return LIKE; } NOT{sp}MATCH/{stop} { return NOT_MATCH; } MATCH { return MATCH; } NOT{sp}REGEXP/{stop} { return NOT_REGEXP; } REGEXP { return REGEXP; } NOT{sp}GLOB/{stop} { return NOT_GLOB; } GLOB { return GLOB; } NOT{sp}BETWEEN/{stop} { return NOT_BETWEEN; } BETWEEN { return BETWEEN; } OUT { return OUT; } INOUT { return INOUT; } CURSOR { return CURSOR; } DECLARE { return DECLARE; } FETCH { return FETCH; } LOOP { return LOOP; } LEAVE { return LEAVE; } CONTINUE { return CONTINUE; } CLOSE { return CLOSE; } ELSE{sp}IF/{stop} { return ELSE_IF; } SAVEPOINT { return SAVEPOINT; } ROLLBACK { return ROLLBACK; } RAISE { return RAISE; } FAIL { return FAIL; } ABORT { return ABORT; } COMMIT { return COMMIT; } TRANSACTION { return TRANSACTION; } RELEASE { return RELEASE; } REPLACE { return REPLACE; } IGNORE { return IGNORE; } OBJECT { return OBJECT; } BLOB { return BLOB; } UPSERT { return UPSERT; } STATEMENT { return STATEMENT; } TYPE { return TYPE; } @ATTRIBUTE { return AT_ATTRIBUTE; } @BEGIN_SCHEMA_REGION { return AT_BEGIN_SCHEMA_REGION; } @CREATE { return AT_CREATE; } @DECLARE_DEPLOYABLE_REGION { return AT_DECLARE_DEPLOYABLE_REGION; } @DECLARE_SCHEMA_REGION { return AT_DECLARE_SCHEMA_REGION; } @DELETE { return AT_DELETE; } @DUMMY_DEFAULTS { return AT_DUMMY_DEFAULTS; } @DUMMY_NULLABLES { return AT_DUMMY_NULLABLES; } @DUMMY_SEED { return AT_DUMMY_SEED; } @ECHO { return AT_ECHO; } @EMIT_CONSTANTS { return AT_EMIT_CONSTANTS; } @EMIT_ENUMS { return AT_EMIT_ENUMS; } @EMIT_GROUP { return AT_EMIT_GROUP; } @END_SCHEMA_REGION { return AT_END_SCHEMA_REGION; } @ENFORCE_NORMAL { return AT_ENFORCE_NORMAL; } @ENFORCE_POP { return AT_ENFORCE_POP; } @ENFORCE_PUSH { return AT_ENFORCE_PUSH; } @ENFORCE_RESET { return AT_ENFORCE_RESET; } @ENFORCE_STRICT { return AT_ENFORCE_STRICT; } @EPONYMOUS { return AT_EPONYMOUS; } @FILE { return AT_FILE; } @PREVIOUS_SCHEMA { return AT_PREVIOUS_SCHEMA; } @RECREATE { return AT_RECREATE; } @RESUB { return AT_RESUB; } @SCHEMA_AD_HOC_MIGRATION { return AT_SCHEMA_AD_HOC_MIGRATION; } @SCHEMA_UPGRADE_SCRIPT { return AT_SCHEMA_UPGRADE_SCRIPT; } @SCHEMA_UPGRADE_VERSION { return AT_SCHEMA_UPGRADE_VERSION; } @SENSITIVE { return AT_SENSITIVE; } @UNSUB { return AT_UNSUB; } ALTER { return ALTER; } RENAME { return RENAME; } COLUMN { return COLUMN; } COLUMNS { return COLUMNS; } ADD { return ADD; } ARGUMENTS { return ARGUMENTS; } RETURN { return RETURN; } DEFERRED { return DEFERRED; } DEFERRABLE { return DEFERRABLE; } NOT{sp}DEFERRABLE/{stop} { return NOT_DEFERRABLE; } IMMEDIATE { return IMMEDIATE; } EXCLUSIVE { return EXCLUSIVE; } RESTRICT { return RESTRICT; } ACTION { return ACTION; } INITIALLY { return INITIALLY; } NO { return NO; } BEFORE { return BEFORE; } AFTER { return AFTER; } INSTEAD { return INSTEAD; } OF { return OF; } TRIGGER { return TRIGGER; } FOR{sp}EACH{sp}ROW/{stop} { return FOR_EACH_ROW; } ENCODE { return ENCODE; } CONTEXT{sp}COLUMN/{stop} { return CONTEXT_COLUMN; } CONTEXT{sp}TYPE/{stop} { return CONTEXT_TYPE; } SIGN{sp}FUNCTION/{stop} { return SIGN_FUNCTION; } CURSOR{sp}HAS{sp}ROW/{stop} { return CURSOR_HAS_ROW; } 0x{hex}+ { char *s = Strdup(yytext); yylval.sval = s; return strtoll(s+2, NULL, 16) <= 0x7fffffff ? INTLIT: LONGLIT; } 0x{hex}+L { char *s = Strdup(yytext); s[strlen(s)-1] = 0; /* remove the L */ yylval.sval = s; return LONGLIT; } {d}+ { char *s = Strdup(yytext); yylval.sval = s; return atoll(s) <= 0x7fffffff ? INTLIT: LONGLIT; } {d}+L { char *s = Strdup(yytext); s[strlen(s)-1] = 0; /* remove the L */ yylval.sval = s; return LONGLIT; } ({d}+"."{d}*|"."{d}+)(E("+"|"-")?{d}+)? { yylval.sval = Strdup(yytext); return REALLIT; } \"(\\.|[^\\"\n])*\" { yylval.sval = Strdup(yytext); return CSTRLIT; } '(''|[^'\n])*' { yylval.sval = Strdup(yytext); return STRLIT; } X'({hex}{hex})*' { yylval.sval = Strdup(yytext); return BLOBLIT; } [-+&~|^/%*(),.;!<>:=] { return yytext[0]; } [_A-Z][A-Z0-9_]* { yylval.sval = Strdup(yytext); return ID; } [ \t\n] ; \-\-.* ; . { yyerror("Unexpected %s\n", yytext); } ^#\ {d}+\ \"[^"]*\".* { line_directive(yytext); } ^\ *#line\ {d}+\ \"[^"]*\".* { line_directive(yytext); } "/*" { // sqlite supports C style comments... ignore those CHARBUF_OPEN(tmp); int c1 = 0, c2 = input(); bool_t save_comment = false; if (c2 == '!' || c2 == '*') { save_comment = true; bputc(&tmp, '/'); bputc(&tmp, '*'); } for (;;) { if (c2 == EOF) break; if (save_comment) { bputc(&tmp, c2); } if (c1 == '*' && c2 == '/') break; c1 = c2; c2 = input(); } if (save_comment) { CHARBUF_OPEN(strlit); cg_encode_c_string_literal(tmp.ptr, &strlit); last_doc_comment = Strdup(strlit.ptr); CHARBUF_CLOSE(strlit); } CHARBUF_CLOSE(tmp); }