Line data Source code
1 : %top{ 2 : /*------------------------------------------------------------------------- 3 : * 4 : * bootscanner.l 5 : * a lexical scanner for the bootstrap parser 6 : * 7 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group 8 : * Portions Copyright (c) 1994, Regents of the University of California 9 : * 10 : * 11 : * IDENTIFICATION 12 : * src/backend/bootstrap/bootscanner.l 13 : * 14 : *------------------------------------------------------------------------- 15 : */ 16 : #include "postgres.h" 17 : 18 : /* 19 : * NB: include bootparse.h only AFTER including bootstrap.h, because bootstrap.h 20 : * includes node definitions needed for YYSTYPE. 21 : */ 22 : #include "bootstrap/bootstrap.h" 23 : #include "bootparse.h" 24 : #include "utils/guc.h" 25 : 26 : } 27 : 28 : %{ 29 : 30 : /* LCOV_EXCL_START */ 31 : 32 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 33 : #undef fprintf 34 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 35 : 36 : static void 37 : fprintf_to_ereport(const char *fmt, const char *msg) 38 : { 39 : ereport(ERROR, (errmsg_internal("%s", msg))); 40 : } 41 : 42 : %} 43 : 44 : %option reentrant 45 : %option bison-bridge 46 : %option 8bit 47 : %option never-interactive 48 : %option nodefault 49 : %option noinput 50 : %option nounput 51 : %option noyywrap 52 : %option noyyalloc 53 : %option noyyrealloc 54 : %option noyyfree 55 : %option warn 56 : %option prefix="boot_yy" 57 : 58 : 59 : id [-A-Za-z0-9_]+ 60 : sid \'([^']|\'\')*\' 61 : 62 : /* 63 : * Keyword tokens return the keyword text (as a constant string) in yylval->kw, 64 : * just in case that's needed because we want to treat the keyword as an 65 : * unreserved identifier. Note that _null_ is not treated as a keyword 66 : * for this purpose; it's the one "reserved word" in the bootstrap syntax. 67 : * 68 : * Notice that all the keywords are case-sensitive, and for historical 69 : * reasons some must be upper case. 70 : * 71 : * String tokens return a palloc'd string in yylval->str. 72 : */ 73 : 74 : %% 75 : 76 : open { yylval->kw = "open"; return OPEN; } 77 : 78 : close { yylval->kw = "close"; return XCLOSE; } 79 : 80 : create { yylval->kw = "create"; return XCREATE; } 81 : 82 : OID { yylval->kw = "OID"; return OBJ_ID; } 83 : bootstrap { yylval->kw = "bootstrap"; return XBOOTSTRAP; } 84 : shared_relation { yylval->kw = "shared_relation"; return XSHARED_RELATION; } 85 : rowtype_oid { yylval->kw = "rowtype_oid"; return XROWTYPE_OID; } 86 : 87 : insert { yylval->kw = "insert"; return INSERT_TUPLE; } 88 : 89 : _null_ { return NULLVAL; } 90 : 91 : "," { return COMMA; } 92 : "=" { return EQUALS; } 93 : "(" { return LPAREN; } 94 : ")" { return RPAREN; } 95 : 96 : [\n] { yylineno++; } 97 : [\r\t ] ; 98 : 99 : ^\#[^\n]* ; /* drop everything after "#" for comments */ 100 : 101 : declare { yylval->kw = "declare"; return XDECLARE; } 102 : build { yylval->kw = "build"; return XBUILD; } 103 : indices { yylval->kw = "indices"; return INDICES; } 104 : unique { yylval->kw = "unique"; return UNIQUE; } 105 : index { yylval->kw = "index"; return INDEX; } 106 : on { yylval->kw = "on"; return ON; } 107 : using { yylval->kw = "using"; return USING; } 108 : toast { yylval->kw = "toast"; return XTOAST; } 109 : FORCE { yylval->kw = "FORCE"; return XFORCE; } 110 : NOT { yylval->kw = "NOT"; return XNOT; } 111 : NULL { yylval->kw = "NULL"; return XNULL; } 112 : 113 : {id} { 114 : yylval->str = pstrdup(yytext); 115 : return ID; 116 : } 117 : {sid} { 118 : /* strip quotes and escapes */ 119 : yylval->str = DeescapeQuotedString(yytext); 120 : return ID; 121 : } 122 : 123 : . { 124 : elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yylineno, yytext); 125 : } 126 : 127 : %% 128 : 129 : /* LCOV_EXCL_STOP */ 130 : 131 : void 132 0 : boot_yyerror(yyscan_t yyscanner, const char *message) 133 : { 134 0 : struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yylineno 135 : * macro */ 136 : 137 0 : elog(ERROR, "%s at line %d", message, yylineno); 138 : } 139 : 140 : /* 141 : * Interface functions to make flex use palloc() instead of malloc(). 142 : * It'd be better to make these static, but flex insists otherwise. 143 : */ 144 : 145 : void * 146 360 : yyalloc(yy_size_t size, yyscan_t yyscanner) 147 : { 148 360 : return palloc(size); 149 : } 150 : 151 : void * 152 0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner) 153 : { 154 0 : if (ptr) 155 0 : return repalloc(ptr, size); 156 : else 157 0 : return palloc(size); 158 : } 159 : 160 : void 161 0 : yyfree(void *ptr, yyscan_t yyscanner) 162 : { 163 0 : if (ptr) 164 0 : pfree(ptr); 165 0 : }