Line data Source code
1 : %{ 2 : /*------------------------------------------------------------------------- 3 : * 4 : * syncrep_scanner.l 5 : * a lexical scanner for synchronous_standby_names 6 : * 7 : * Portions Copyright (c) 1996-2020, 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 : 20 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 21 : #undef fprintf 22 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 23 : 24 : static void 25 0 : fprintf_to_ereport(const char *fmt, const char *msg) 26 : { 27 0 : ereport(ERROR, (errmsg_internal("%s", msg))); 28 : } 29 : 30 : /* Handles to the buffer that the lexer uses internally */ 31 : static YY_BUFFER_STATE scanbufhandle; 32 : 33 : static StringInfoData xdbuf; 34 : 35 : /* LCOV_EXCL_START */ 36 : 37 : %} 38 : 39 : %option 8bit 40 : %option never-interactive 41 : %option nodefault 42 : %option noinput 43 : %option nounput 44 : %option noyywrap 45 : %option warn 46 : %option prefix="syncrep_yy" 47 : 48 : /* 49 : * <xd> delimited identifiers (double-quoted identifiers) 50 : */ 51 : %x xd 52 : 53 : space [ \t\n\r\f\v] 54 : 55 : digit [0-9] 56 : ident_start [A-Za-z\200-\377_] 57 : ident_cont [A-Za-z\200-\377_0-9\$] 58 : identifier {ident_start}{ident_cont}* 59 : 60 : dquote \" 61 : xdstart {dquote} 62 : xdstop {dquote} 63 : xddouble {dquote}{dquote} 64 : xdinside [^"]+ 65 : 66 : %% 67 : {space}+ { /* ignore */ } 68 : 69 : /* brute-force case insensitivity is safer than relying on flex -i */ 70 : 71 : [Aa][Nn][Yy] { return ANY; } 72 : [Ff][Ii][Rr][Ss][Tt] { return FIRST; } 73 : 74 : {xdstart} { 75 : initStringInfo(&xdbuf); 76 : BEGIN(xd); 77 : } 78 : <xd>{xddouble} { 79 : appendStringInfoChar(&xdbuf, '"'); 80 : } 81 : <xd>{xdinside} { 82 : appendStringInfoString(&xdbuf, yytext); 83 : } 84 : <xd>{xdstop} { 85 : yylval.str = xdbuf.data; 86 : xdbuf.data = NULL; 87 : BEGIN(INITIAL); 88 : return NAME; 89 : } 90 : <xd><<EOF>> { 91 : yyerror("unterminated quoted identifier"); 92 : return JUNK; 93 : } 94 : 95 : {identifier} { 96 : yylval.str = pstrdup(yytext); 97 : return NAME; 98 : } 99 : 100 : {digit}+ { 101 : yylval.str = pstrdup(yytext); 102 : return NUM; 103 : } 104 : 105 : "*" { 106 : yylval.str = "*"; 107 : return NAME; 108 : } 109 : 110 : "," { return ','; } 111 : "(" { return '('; } 112 : ")" { return ')'; } 113 : 114 : . { return JUNK; } 115 : %% 116 : 117 : /* LCOV_EXCL_STOP */ 118 : 119 : /* Needs to be here for access to yytext */ 120 : void 121 : syncrep_yyerror(const char *message) 122 0 : { 123 : /* report only the first error in a parse operation */ 124 : if (syncrep_parse_error_msg) 125 0 : return; 126 0 : if (yytext[0]) 127 0 : syncrep_parse_error_msg = psprintf("%s at or near \"%s\"", 128 0 : message, yytext); 129 : else 130 : syncrep_parse_error_msg = psprintf("%s at end of input", 131 0 : message); 132 : } 133 : 134 : void 135 : syncrep_scanner_init(const char *str) 136 0 : { 137 : Size slen = strlen(str); 138 0 : char *scanbuf; 139 : 140 : /* 141 : * Might be left over after ereport() 142 : */ 143 : if (YY_CURRENT_BUFFER) 144 0 : yy_delete_buffer(YY_CURRENT_BUFFER); 145 0 : 146 : /* 147 : * Make a scan buffer with special termination needed by flex. 148 : */ 149 : scanbuf = (char *) palloc(slen + 2); 150 0 : memcpy(scanbuf, str, slen); 151 0 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; 152 0 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); 153 0 : 154 : /* Make sure we start in proper state */ 155 : BEGIN(INITIAL); 156 0 : } 157 0 : 158 : void 159 : syncrep_scanner_finish(void) 160 0 : { 161 : yy_delete_buffer(scanbufhandle); 162 0 : scanbufhandle = NULL; 163 0 : }