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
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 :
45 EUB : /* LCOV_EXCL_START */
46 :
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 */ }
78 GIC 10 :
79 : /* brute-force case insensitivity is safer than relying on flex -i */
80 4 :
81 4 : [Aa][Nn][Yy] { return ANY; }
82 2 : [Ff][Ii][Rr][Ss][Tt] { return FIRST; }
83 2 :
84 UIC 0 : {xdstart} {
85 0 : initStringInfo(&xdbuf);
86 0 : BEGIN(xd);
87 : }
88 LBC 0 : <xd>{xddouble} {
89 UIC 0 : appendStringInfoChar(&xdbuf, '"');
90 ECB : }
91 LBC 0 : <xd>{xdinside} {
92 0 : appendStringInfoString(&xdbuf, yytext);
93 ECB : }
94 UBC 0 : <xd>{xdstop} {
95 UNC 0 : syncrep_yylval.str = xdbuf.data;
96 UBC 0 : xdbuf.data = NULL;
97 UIC 0 : BEGIN(INITIAL);
98 UBC 0 : return NAME;
99 EUB : }
100 : <xd><<EOF>> {
101 UNC 0 : syncrep_yyerror("unterminated quoted identifier");
102 UBC 0 : return JUNK;
103 : }
104 EUB :
105 GBC 73 : {identifier} {
106 GNC 73 : syncrep_yylval.str = pstrdup(yytext);
107 GBC 73 : return NAME;
108 EUB : }
109 :
110 GIC 18 : {digit}+ {
111 GNC 18 : syncrep_yylval.str = pstrdup(yytext);
112 GBC 18 : return NUM;
113 : }
114 :
115 CBC 24 : "*" {
116 GNC 24 : syncrep_yylval.str = "*";
117 CBC 24 : return NAME;
118 : }
119 :
120 30 : "," { return ','; }
121 18 : "(" { return '('; }
122 18 : ")" { return ')'; }
123 GIC 18 :
124 UIC 0 : . { return JUNK; }
125 LBC 0 : %%
126 0 :
127 ECB : /* LCOV_EXCL_STOP */
128 :
129 : /* Needs to be here for access to yytext */
130 : void
131 LBC 0 : syncrep_yyerror(const char *message)
132 ECB : {
133 : /* report only the first error in a parse operation */
134 UBC 0 : if (syncrep_parse_error_msg)
135 0 : return;
136 0 : if (yytext[0])
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",
141 EUB : message);
142 : }
143 :
144 : void
145 GBC 67 : syncrep_scanner_init(const char *str)
146 EUB : {
147 GBC 67 : Size slen = strlen(str);
148 : char *scanbuf;
149 :
150 EUB : /*
151 : * Might be left over after ereport()
152 : */
153 GIC 67 : if (YY_CURRENT_BUFFER)
154 UIC 0 : yy_delete_buffer(YY_CURRENT_BUFFER);
155 ECB :
156 : /*
157 : * Make a scan buffer with special termination needed by flex.
158 : */
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);
163 ECB :
164 EUB : /* Make sure we start in proper state */
165 GIC 67 : BEGIN(INITIAL);
166 67 : }
167 :
168 : void
169 CBC 67 : syncrep_scanner_finish(void)
170 ECB : {
171 CBC 67 : yy_delete_buffer(scanbufhandle);
172 67 : scanbufhandle = NULL;
173 GIC 67 : }
|