postgresql/src/backend/replication/syncrep_scanner.l

173 lines
3.4 KiB
Plaintext

%top{
/*-------------------------------------------------------------------------
*
* syncrep_scanner.l
* a lexical scanner for synchronous_standby_names
*
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/replication/syncrep_scanner.l
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "lib/stringinfo.h"
/*
* NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h
* includes node definitions needed for YYSTYPE.
*/
#include "replication/syncrep.h"
#include "syncrep_gram.h"
}
%{
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
static void
fprintf_to_ereport(const char *fmt, const char *msg)
{
ereport(ERROR, (errmsg_internal("%s", msg)));
}
/* Handles to the buffer that the lexer uses internally */
static YY_BUFFER_STATE scanbufhandle;
static StringInfoData xdbuf;
/* LCOV_EXCL_START */
%}
%option 8bit
%option never-interactive
%option nodefault
%option noinput
%option nounput
%option noyywrap
%option warn
%option prefix="syncrep_yy"
/*
* <xd> delimited identifiers (double-quoted identifiers)
*/
%x xd
space [ \t\n\r\f\v]
digit [0-9]
ident_start [A-Za-z\200-\377_]
ident_cont [A-Za-z\200-\377_0-9\$]
identifier {ident_start}{ident_cont}*
dquote \"
xdstart {dquote}
xdstop {dquote}
xddouble {dquote}{dquote}
xdinside [^"]+
%%
{space}+ { /* ignore */ }
/* brute-force case insensitivity is safer than relying on flex -i */
[Aa][Nn][Yy] { return ANY; }
[Ff][Ii][Rr][Ss][Tt] { return FIRST; }
{xdstart} {
initStringInfo(&xdbuf);
BEGIN(xd);
}
<xd>{xddouble} {
appendStringInfoChar(&xdbuf, '"');
}
<xd>{xdinside} {
appendStringInfoString(&xdbuf, yytext);
}
<xd>{xdstop} {
syncrep_yylval.str = xdbuf.data;
xdbuf.data = NULL;
BEGIN(INITIAL);
return NAME;
}
<xd><<EOF>> {
syncrep_yyerror("unterminated quoted identifier");
return JUNK;
}
{identifier} {
syncrep_yylval.str = pstrdup(yytext);
return NAME;
}
{digit}+ {
syncrep_yylval.str = pstrdup(yytext);
return NUM;
}
"*" {
syncrep_yylval.str = "*";
return NAME;
}
"," { return ','; }
"(" { return '('; }
")" { return ')'; }
. { return JUNK; }
%%
/* LCOV_EXCL_STOP */
/* Needs to be here for access to yytext */
void
syncrep_yyerror(const char *message)
{
/* report only the first error in a parse operation */
if (syncrep_parse_error_msg)
return;
if (yytext[0])
syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
message, yytext);
else
syncrep_parse_error_msg = psprintf("%s at end of input",
message);
}
void
syncrep_scanner_init(const char *str)
{
Size slen = strlen(str);
char *scanbuf;
/*
* Might be left over after ereport()
*/
if (YY_CURRENT_BUFFER)
yy_delete_buffer(YY_CURRENT_BUFFER);
/*
* Make a scan buffer with special termination needed by flex.
*/
scanbuf = (char *) palloc(slen + 2);
memcpy(scanbuf, str, slen);
scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
/* Make sure we start in proper state */
BEGIN(INITIAL);
}
void
syncrep_scanner_finish(void)
{
yy_delete_buffer(scanbufhandle);
scanbufhandle = NULL;
}