Age Owner TLA 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-2023, 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
2538 tgl 35 UIC 0 : fprintf_to_ereport(const char *fmt, const char *msg)
36 : {
37 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
38 : }
39 :
40 : /* Handles to the buffer that the lexer uses internally */
41 : static YY_BUFFER_STATE scanbufhandle;
42 :
43 : static StringInfoData xdbuf;
44 :
2068 peter_e 45 EUB : /* LCOV_EXCL_START */
46 :
2559 fujii 47 : %}
48 :
49 : %option 8bit
50 : %option never-interactive
51 : %option nodefault
52 : %option noinput
53 : %option nounput
54 : %option noyywrap
55 : %option warn
56 : %option prefix="syncrep_yy"
57 :
58 : /*
59 : * <xd> delimited identifiers (double-quoted identifiers)
60 : */
61 : %x xd
62 :
63 : space [ \t\n\r\f\v]
64 :
65 : digit [0-9]
66 : ident_start [A-Za-z\200-\377_]
67 : ident_cont [A-Za-z\200-\377_0-9\$]
68 : identifier {ident_start}{ident_cont}*
69 :
70 : dquote \"
71 : xdstart {dquote}
72 : xdstop {dquote}
73 : xddouble {dquote}{dquote}
74 : xdinside [^"]+
75 :
76 : %%
77 : {space}+ { /* ignore */ }
2538 tgl 78 GIC 10 :
79 : /* brute-force case insensitivity is safer than relying on flex -i */
2151 80 4 :
81 4 : [Aa][Nn][Yy] { return ANY; }
82 2 : [Ff][Ii][Rr][Ss][Tt] { return FIRST; }
2302 fujii 83 2 :
2559 fujii 84 UIC 0 : {xdstart} {
85 0 : initStringInfo(&xdbuf);
86 0 : BEGIN(xd);
87 : }
2559 fujii 88 LBC 0 : <xd>{xddouble} {
2538 tgl 89 UIC 0 : appendStringInfoChar(&xdbuf, '"');
2559 fujii 90 ECB : }
2559 fujii 91 LBC 0 : <xd>{xdinside} {
92 0 : appendStringInfoString(&xdbuf, yytext);
2559 fujii 93 ECB : }
2559 fujii 94 UBC 0 : <xd>{xdstop} {
217 john.naylor 95 UNC 0 : syncrep_yylval.str = xdbuf.data;
2538 tgl 96 UBC 0 : xdbuf.data = NULL;
2559 fujii 97 UIC 0 : BEGIN(INITIAL);
2559 fujii 98 UBC 0 : return NAME;
2559 fujii 99 EUB : }
100 : <xd><<EOF>> {
217 john.naylor 101 UNC 0 : syncrep_yyerror("unterminated quoted identifier");
2538 tgl 102 UBC 0 : return JUNK;
103 : }
2538 tgl 104 EUB :
2538 tgl 105 GBC 73 : {identifier} {
217 john.naylor 106 GNC 73 : syncrep_yylval.str = pstrdup(yytext);
2538 tgl 107 GBC 73 : return NAME;
2559 fujii 108 EUB : }
109 :
2538 tgl 110 GIC 18 : {digit}+ {
217 john.naylor 111 GNC 18 : syncrep_yylval.str = pstrdup(yytext);
2538 tgl 112 GBC 18 : return NUM;
113 : }
114 :
2538 tgl 115 CBC 24 : "*" {
217 john.naylor 116 GNC 24 : syncrep_yylval.str = "*";
2559 fujii 117 CBC 24 : return NAME;
118 : }
119 :
2538 tgl 120 30 : "," { return ','; }
121 18 : "(" { return '('; }
122 18 : ")" { return ')'; }
2538 tgl 123 GIC 18 :
2538 tgl 124 UIC 0 : . { return JUNK; }
2559 fujii 125 LBC 0 : %%
126 0 :
2068 peter_e 127 ECB : /* LCOV_EXCL_STOP */
128 :
129 : /* Needs to be here for access to yytext */
2559 fujii 130 : void
2538 tgl 131 LBC 0 : syncrep_yyerror(const char *message)
2559 fujii 132 ECB : {
2538 tgl 133 : /* report only the first error in a parse operation */
2538 tgl 134 UBC 0 : if (syncrep_parse_error_msg)
135 0 : return;
136 0 : if (yytext[0])
2538 tgl 137 UIC 0 : syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
138 : message, yytext);
139 : else
140 0 : syncrep_parse_error_msg = psprintf("%s at end of input",
2538 tgl 141 EUB : message);
142 : }
143 :
2559 fujii 144 : void
2559 fujii 145 GBC 67 : syncrep_scanner_init(const char *str)
2559 fujii 146 EUB : {
2559 fujii 147 GBC 67 : Size slen = strlen(str);
148 : char *scanbuf;
149 :
2559 fujii 150 EUB : /*
151 : * Might be left over after ereport()
152 : */
2559 fujii 153 GIC 67 : if (YY_CURRENT_BUFFER)
2559 fujii 154 UIC 0 : yy_delete_buffer(YY_CURRENT_BUFFER);
2559 fujii 155 ECB :
156 : /*
157 : * Make a scan buffer with special termination needed by flex.
158 : */
2559 fujii 159 GIC 67 : scanbuf = (char *) palloc(slen + 2);
160 67 : memcpy(scanbuf, str, slen);
161 67 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
162 67 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
2538 tgl 163 ECB :
2538 tgl 164 EUB : /* Make sure we start in proper state */
2538 tgl 165 GIC 67 : BEGIN(INITIAL);
2559 fujii 166 67 : }
167 :
168 : void
2559 fujii 169 CBC 67 : syncrep_scanner_finish(void)
2559 fujii 170 ECB : {
2559 fujii 171 CBC 67 : yy_delete_buffer(scanbufhandle);
172 67 : scanbufhandle = NULL;
2559 fujii 173 GIC 67 : }
|