PostgreSQL Source Code git master
syncrep_scanner.l
Go to the documentation of this file.
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
34static void
35fprintf_to_ereport(const char *fmt, const char *msg)
36{
37 ereport(ERROR, (errmsg_internal("%s", msg)));
38}
39
41{
43};
44
45/*
46 * Better keep this definition here than put it in replication/syncrep.h and
47 * save a bit of duplication. Putting it in replication/syncrep.h would leak
48 * the definition to other parts and possibly affect other scanners.
49*/
50#define YY_DECL extern int syncrep_yylex(union YYSTYPE *yylval_param, char **syncrep_parse_error_msg_p, yyscan_t yyscanner)
51
52/* LCOV_EXCL_START */
53
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static void const char * fmt
StringInfoData xdbuf
static void fprintf_to_ereport(const char *fmt, const char *msg)
54%}
55
56%option reentrant
57%option bison-bridge
58%option 8bit
59%option never-interactive
60%option nodefault
61%option noinput
62%option nounput
63%option noyywrap
64%option noyyalloc
65%option noyyrealloc
66%option noyyfree
67%option warn
68%option prefix="syncrep_yy"
69%option extra-type="struct syncrep_yy_extra_type *"
70
71/*
72 * <xd> delimited identifiers (double-quoted identifiers)
73 */
74%x xd
75
76space [ \t\n\r\f\v]
77
78digit [0-9]
79ident_start [A-Za-z\200-\377_]
80ident_cont [A-Za-z\200-\377_0-9\$]
81identifier {ident_start}{ident_cont}*
82
83dquote \"
84xdstart {dquote}
85xdstop {dquote}
86xddouble {dquote}{dquote}
87xdinside [^"]+
88
89%%
90{space}+ { /* ignore */ }
91
92 /* brute-force case insensitivity is safer than relying on flex -i */
93
94[Aa][Nn][Yy] { return ANY; }
@ ANY
Definition: isn.c:37
95[Ff][Ii][Rr][Ss][Tt] { return FIRST; }
96
97{xdstart} {
98 initStringInfo(&yyextra->xdbuf);
99 BEGIN(xd);
100 }
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
#define yyextra
101<xd>{xddouble} {
102 appendStringInfoChar(&yyextra->xdbuf, '"');
103 }
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
104<xd>{xdinside} {
105 appendStringInfoString(&yyextra->xdbuf, yytext);
106 }
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
107<xd>{xdstop} {
108 yylval->str = yyextra->xdbuf.data;
109 yyextra->xdbuf.data = NULL;
110 BEGIN(INITIAL);
111 return NAME;
112 }
113<xd><<EOF>> {
114 syncrep_yyerror(NULL, syncrep_parse_error_msg_p, yyscanner, "unterminated quoted identifier");
115 return JUNK;
116 }
void syncrep_yyerror(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner, const char *message)
117
118{identifier} {
119 yylval->str = pstrdup(yytext);
120 return NAME;
121 }
char * pstrdup(const char *in)
Definition: mcxt.c:1696
122
123{digit}+ {
124 yylval->str = pstrdup(yytext);
125 return NUM;
126 }
127
128"*" {
129 yylval->str = "*";
130 return NAME;
131 }
132
133"," { return ','; }
134"(" { return '('; }
135")" { return ')'; }
136
137. { return JUNK; }
138%%
139
140/* LCOV_EXCL_STOP */
141
142/* see scan.l */
143#undef yyextra
144#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
145
146/*
147 * This yyerror() function does not raise an error (elog or similar), it just
148 * collects the error message in *syncrep_parse_error_msg_p and leaves it to
149 * the ultimate caller of the syncrep parser to raise the error. (The
150 * ultimate caller will do that with special GUC error functions.)
151 *
152 * (The first argument is enforced by Bison to match the first argument of
153 * yyparse(), but it is not used here.)
154 */
155void
156syncrep_yyerror(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner, const char *message)
157{
158 struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext
159 * macro */
160 char *syncrep_parse_error_msg = *syncrep_parse_error_msg_p;
161
162 /* report only the first error in a parse operation */
163 if (syncrep_parse_error_msg)
164 return;
165 if (yytext[0])
166 syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
167 message, yytext);
168 else
169 syncrep_parse_error_msg = psprintf("%s at end of input",
170 message);
171}
172
173void
174syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
175{
176 yyscan_t yyscanner;
178
179 if (yylex_init(yyscannerp) != 0)
180 elog(ERROR, "yylex_init() failed: %m");
181
182 yyscanner = *yyscannerp;
183
184 yyset_extra(yyext, yyscanner);
185
186 yy_scan_string(str, yyscanner);
187}
188
189void
191{
192 pfree(yyextra);
193 yylex_destroy(yyscanner);
194}
195
196/*
197 * Interface functions to make flex use palloc() instead of malloc().
198 * It'd be better to make these static, but flex insists otherwise.
199 */
200
201void *
202yyalloc(yy_size_t size, yyscan_t yyscanner)
203{
204 return palloc(size);
205}
206
207void *
208yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
209{
210 if (ptr)
211 return repalloc(ptr, size);
212 else
213 return palloc(size);
214}
215
216void
217yyfree(void *ptr, yyscan_t yyscanner)
218{
219 if (ptr)
220 pfree(ptr);
221}
void * yyscan_t
Definition: cubedata.h:67
#define elog(elevel,...)
Definition: elog.h:225
#define palloc0_object(type)
Definition: fe_memutils.h:75
const char * str
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
static pg_noinline void Size size
Definition: slab.c:607
void * yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
void syncrep_scanner_finish(yyscan_t yyscanner)
void syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
void yyfree(void *ptr, yyscan_t yyscanner)
void * yyalloc(yy_size_t size, yyscan_t yyscanner)