Line data Source code
1 : %top{ 2 : /*------------------------------------------------------------------------- 3 : * 4 : * syncrep_scanner.l 5 : * a lexical scanner for synchronous_standby_names 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/replication/syncrep_scanner.l 13 : * 14 : *------------------------------------------------------------------------- 15 : */ 16 : #include "postgres.h" 17 : 18 : #include "lib/stringinfo.h" 19 : #include "nodes/pg_list.h" 20 : 21 : /* 22 : * NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h 23 : * includes node definitions needed for YYSTYPE. 24 : */ 25 : #include "replication/syncrep.h" 26 : #include "syncrep_gram.h" 27 : } 28 : 29 : %{ 30 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 31 : #undef fprintf 32 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 33 : 34 : static void 35 0 : fprintf_to_ereport(const char *fmt, const char *msg) 36 : { 37 0 : ereport(ERROR, (errmsg_internal("%s", msg))); 38 : } 39 : 40 : struct syncrep_yy_extra_type 41 : { 42 : StringInfoData xdbuf; 43 : }; 44 : 45 : /* LCOV_EXCL_START */ 46 : 47 : %} 48 : 49 : %option reentrant 50 : %option bison-bridge 51 : %option 8bit 52 : %option never-interactive 53 : %option nodefault 54 : %option noinput 55 : %option nounput 56 : %option noyywrap 57 : %option noyyalloc 58 : %option noyyrealloc 59 : %option noyyfree 60 : %option warn 61 : %option prefix="syncrep_yy" 62 : %option extra-type="struct syncrep_yy_extra_type *" 63 : 64 : /* 65 : * <xd> delimited identifiers (double-quoted identifiers) 66 : */ 67 : %x xd 68 : 69 : space [ \t\n\r\f\v] 70 : 71 : digit [0-9] 72 : ident_start [A-Za-z\200-\377_] 73 : ident_cont [A-Za-z\200-\377_0-9\$] 74 : identifier {ident_start}{ident_cont}* 75 : 76 : dquote \" 77 : xdstart {dquote} 78 : xdstop {dquote} 79 : xddouble {dquote}{dquote} 80 : xdinside [^"]+ 81 : 82 : %% 83 : {space}+ { /* ignore */ } 84 : 85 : /* brute-force case insensitivity is safer than relying on flex -i */ 86 : 87 : [Aa][Nn][Yy] { return ANY; } 88 : [Ff][Ii][Rr][Ss][Tt] { return FIRST; } 89 : 90 : {xdstart} { 91 : initStringInfo(&yyextra->xdbuf); 92 : BEGIN(xd); 93 : } 94 : <xd>{xddouble} { 95 : appendStringInfoChar(&yyextra->xdbuf, '"'); 96 : } 97 : <xd>{xdinside} { 98 : appendStringInfoString(&yyextra->xdbuf, yytext); 99 : } 100 : <xd>{xdstop} { 101 : yylval->str = yyextra->xdbuf.data; 102 : yyextra->xdbuf.data = NULL; 103 : BEGIN(INITIAL); 104 : return NAME; 105 : } 106 : <xd><<EOF>> { 107 : syncrep_yyerror(yyscanner, "unterminated quoted identifier"); 108 : return JUNK; 109 : } 110 : 111 : {identifier} { 112 : yylval->str = pstrdup(yytext); 113 : return NAME; 114 : } 115 : 116 : {digit}+ { 117 : yylval->str = pstrdup(yytext); 118 : return NUM; 119 : } 120 : 121 : "*" { 122 : yylval->str = "*"; 123 : return NAME; 124 : } 125 : 126 : "," { return ','; } 127 : "(" { return '('; } 128 : ")" { return ')'; } 129 : 130 : . { return JUNK; } 131 : %% 132 : 133 : /* LCOV_EXCL_STOP */ 134 : 135 : /* see scan.l */ 136 : #undef yyextra 137 : #define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r) 138 : 139 : /* Needs to be here for access to yytext */ 140 : void 141 0 : syncrep_yyerror(yyscan_t yyscanner, const char *message) 142 : { 143 0 : struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext 144 : * macro */ 145 : 146 : /* report only the first error in a parse operation */ 147 0 : if (syncrep_parse_error_msg) 148 0 : return; 149 0 : if (yytext[0]) 150 0 : syncrep_parse_error_msg = psprintf("%s at or near \"%s\"", 151 : message, yytext); 152 : else 153 0 : syncrep_parse_error_msg = psprintf("%s at end of input", 154 : message); 155 : } 156 : 157 : void 158 130 : syncrep_scanner_init(const char *str, yyscan_t *yyscannerp) 159 : { 160 : yyscan_t yyscanner; 161 130 : struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type); 162 : 163 130 : if (yylex_init(yyscannerp) != 0) 164 0 : elog(ERROR, "yylex_init() failed: %m"); 165 : 166 130 : yyscanner = *yyscannerp; 167 : 168 130 : yyset_extra(yyext, yyscanner); 169 : 170 130 : yy_scan_string(str, yyscanner); 171 130 : } 172 : 173 : void 174 130 : syncrep_scanner_finish(yyscan_t yyscanner) 175 : { 176 130 : pfree(yyextra); 177 130 : yylex_destroy(yyscanner); 178 130 : } 179 : 180 : /* 181 : * Interface functions to make flex use palloc() instead of malloc(). 182 : * It'd be better to make these static, but flex insists otherwise. 183 : */ 184 : 185 : void * 186 520 : yyalloc(yy_size_t size, yyscan_t yyscanner) 187 : { 188 520 : return palloc(size); 189 : } 190 : 191 : void * 192 0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner) 193 : { 194 0 : if (ptr) 195 0 : return repalloc(ptr, size); 196 : else 197 0 : return palloc(size); 198 : } 199 : 200 : void 201 650 : yyfree(void *ptr, yyscan_t yyscanner) 202 : { 203 650 : if (ptr) 204 520 : pfree(ptr); 205 650 : }