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:1170
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
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:41
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:1759
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
161 /* report only the first error in a parse operation */
162 if (*syncrep_parse_error_msg_p)
163 return;
164 if (yytext[0])
165 *syncrep_parse_error_msg_p = psprintf("%s at or near \"%s\"",
166 message, yytext);
167 else
168 *syncrep_parse_error_msg_p = psprintf("%s at end of input",
169 message);
170}
171
172void
173syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
174{
175 yyscan_t yyscanner;
177
178 if (yylex_init(yyscannerp) != 0)
179 elog(ERROR, "yylex_init() failed: %m");
180
181 yyscanner = *yyscannerp;
182
183 yyset_extra(yyext, yyscanner);
184
185 yy_scan_string(str, yyscanner);
186}
187
188void
190{
191 pfree(yyextra);
192 yylex_destroy(yyscanner);
193}
194
195/*
196 * Interface functions to make flex use palloc() instead of malloc().
197 * It'd be better to make these static, but flex insists otherwise.
198 */
199
200void *
201yyalloc(yy_size_t size, yyscan_t yyscanner)
202{
203 return palloc(size);
204}
205
206void *
207yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
208{
209 if (ptr)
210 return repalloc(ptr, size);
211 else
212 return palloc(size);
213}
214
215void
216yyfree(void *ptr, yyscan_t yyscanner)
217{
218 if (ptr)
219 pfree(ptr);
220}
void * yyscan_t
Definition: cubedata.h:65
#define elog(elevel,...)
Definition: elog.h:226
#define palloc0_object(type)
Definition: fe_memutils.h:75
const char * str
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1610
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc(Size size)
Definition: mcxt.c:1365
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
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)