Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdb6856c

Browse files
committed
syncrep parser: pure parser and reentrant scanner
Use the flex %option reentrant and the bison option %pure-parser tomake the generated scanner and parser pure, reentrant, andthread-safe.Make the generated scanner use palloc() etc. instead of malloc() etc.Previously, we only used palloc() for the buffer, but flex would stilluse malloc() for its internal structures. Now, all the memory isunder palloc() control.Simplify flex scan buffer management: Instead of constructing thebuffer from pieces and then using yy_scan_buffer(), we can just useyy_scan_string(), which does the same thing internally.The previous code was necessary because we allocated the buffer withpalloc() and the rest of the state was handled by malloc(). But thisis no longer the case; everything is under palloc() now.Use flex yyextra to handle context information, instead of globalvariables. This complements the other changes to make the scannerreentrant.Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>Reviewed-by: Andreas Karlsson <andreas@proxel.se>Discussion:https://www.postgresql.org/message-id/flat/eb6faeac-2a8a-4b69-9189-c33c520e5b7b@eisentraut.org
1 parente4a8fb8 commitdb6856c

File tree

5 files changed

+90
-51
lines changed

5 files changed

+90
-51
lines changed

‎src/backend/nls.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \
1111
parser_yyerror\
1212
replication_yyerror:2\
1313
scanner_yyerror\
14-
syncrep_yyerror\
14+
syncrep_yyerror:2\
1515
report_invalid_record:2\
1616
ereport_startup_progress\
1717
json_token_error:2\

‎src/backend/replication/syncrep.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ check_synchronous_standby_names(char **newval, void **extra, GucSource source)
992992
{
993993
if (*newval!=NULL&& (*newval)[0]!='\0')
994994
{
995+
yyscan_tscanner;
995996
intparse_rc;
996997
SyncRepConfigData*pconf;
997998

@@ -1000,9 +1001,9 @@ check_synchronous_standby_names(char **newval, void **extra, GucSource source)
10001001
syncrep_parse_error_msg=NULL;
10011002

10021003
/* Parse the synchronous_standby_names string */
1003-
syncrep_scanner_init(*newval);
1004-
parse_rc=syncrep_yyparse();
1005-
syncrep_scanner_finish();
1004+
syncrep_scanner_init(*newval,&scanner);
1005+
parse_rc=syncrep_yyparse(scanner);
1006+
syncrep_scanner_finish(scanner);
10061007

10071008
if (parse_rc!=0||syncrep_parse_result==NULL)
10081009
{

‎src/backend/replication/syncrep_gram.y

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ char *syncrep_parse_error_msg;
2626
static SyncRepConfigData *create_syncrep_config(constchar *num_sync,
2727
List *members, uint8 syncrep_method);
2828

29-
/* silence -Wmissing-variable-declarations*/
30-
externint syncrep_yychar;
31-
externint syncrep_yynerrs;
32-
3329
/*
3430
* Bison doesn't allocate anything that needs to live across parser calls,
3531
* so we can easily have it use palloc instead of malloc. This prevents
@@ -40,6 +36,9 @@ extern int syncrep_yynerrs;
4036

4137
%}
4238

39+
%parse-param {yyscan_t yyscanner}
40+
%lex-param {yyscan_t yyscanner}
41+
%pure-parser
4342
%expect0
4443
%name-prefix="syncrep_yy"
4544

@@ -60,7 +59,10 @@ extern int syncrep_yynerrs;
6059

6160
%%
6261
result:
63-
standby_config{ syncrep_parse_result =$1; }
62+
standby_config{
63+
syncrep_parse_result =$1;
64+
(void)yynerrs;/* suppress compiler warning*/
65+
}
6466
;
6567

6668
standby_config:

‎src/backend/replication/syncrep_scanner.l

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,27 @@ fprintf_to_ereport(const char *fmt, const char *msg)
3737
ereport(ERROR, (errmsg_internal("%s", msg)));
3838
}
3939

40-
/* Handles to the buffer that the lexer uses internally*/
41-
static YY_BUFFER_STATE scanbufhandle;
42-
43-
static StringInfoData xdbuf;
40+
structsyncrep_yy_extra_type
41+
{
42+
StringInfoData xdbuf;
43+
};
44+
#defineYY_EXTRA_TYPEstructsyncrep_yy_extra_type *
4445

4546
/* LCOV_EXCL_START */
4647

4748
%}
4849

50+
%option reentrant
51+
%option bison-bridge
4952
%option 8bit
5053
%option never-interactive
5154
%option nodefault
5255
%option noinput
5356
%option nounput
5457
%option noyywrap
58+
%option noyyalloc
59+
%option noyyrealloc
60+
%option noyyfree
5561
%option warn
5662
%option prefix="syncrep_yy"
5763

@@ -82,38 +88,38 @@ xdinside[^"]+
8288
[Ff][Ii][Rr][Ss][Tt]{return FIRST; }
8389

8490
{xdstart}{
85-
initStringInfo(&xdbuf);
91+
initStringInfo(&yyextra->xdbuf);
8692
BEGIN(xd);
8793
}
8894
<xd>{xddouble} {
89-
appendStringInfoChar(&xdbuf,'"');
95+
appendStringInfoChar(&yyextra->xdbuf,'"');
9096
}
9197
<xd>{xdinside} {
92-
appendStringInfoString(&xdbuf, yytext);
98+
appendStringInfoString(&yyextra->xdbuf, yytext);
9399
}
94100
<xd>{xdstop} {
95-
syncrep_yylval.str = xdbuf.data;
96-
xdbuf.data =NULL;
101+
yylval->str =yyextra->xdbuf.data;
102+
yyextra->xdbuf.data =NULL;
97103
BEGIN(INITIAL);
98104
return NAME;
99105
}
100106
<xd><<EOF>> {
101-
syncrep_yyerror("unterminated quoted identifier");
107+
syncrep_yyerror(yyscanner,"unterminated quoted identifier");
102108
return JUNK;
103109
}
104110

105111
{identifier} {
106-
syncrep_yylval.str =pstrdup(yytext);
112+
yylval->str =pstrdup(yytext);
107113
return NAME;
108114
}
109115

110116
{digit}+{
111-
syncrep_yylval.str =pstrdup(yytext);
117+
yylval->str =pstrdup(yytext);
112118
return NUM;
113119
}
114120

115121
"*"{
116-
syncrep_yylval.str ="*";
122+
yylval->str ="*";
117123
return NAME;
118124
}
119125

@@ -126,10 +132,16 @@ xdinside[^"]+
126132

127133
/* LCOV_EXCL_STOP*/
128134

135+
/* see scan.l*/
136+
#undef yyextra
137+
#defineyyextra (((structyyguts_t *) yyscanner)->yyextra_r)
138+
129139
/* Needs to be here for access to yytext*/
130140
void
131-
syncrep_yyerror(constchar *message)
141+
syncrep_yyerror(yyscan_t yyscanner,constchar *message)
132142
{
143+
structyyguts_t * yyg = (structyyguts_t *) yyscanner;/* needed for yytext macro */
144+
133145
/* report only the first error in a parse operation */
134146
if (syncrep_parse_error_msg)
135147
return;
@@ -142,32 +154,51 @@ syncrep_yyerror(const char *message)
142154
}
143155

144156
void
145-
syncrep_scanner_init(constchar *str)
157+
syncrep_scanner_init(constchar *str,yyscan_t *yyscannerp)
158+
{
159+
yyscan_tyyscanner;
160+
structsyncrep_yy_extra_type *yyext =palloc0_object(structsyncrep_yy_extra_type);
161+
162+
if (yylex_init(yyscannerp) !=0)
163+
elog(ERROR,"yylex_init() failed: %m");
164+
165+
yyscanner = *yyscannerp;
166+
167+
yyset_extra(yyext, yyscanner);
168+
169+
yy_scan_string(str, yyscanner);
170+
}
171+
172+
void
173+
syncrep_scanner_finish(yyscan_t yyscanner)
146174
{
147-
Sizeslen =strlen(str);
148-
char *scanbuf;
149-
150-
/*
151-
* Might be left over after ereport()
152-
*/
153-
if (YY_CURRENT_BUFFER)
154-
yy_delete_buffer(YY_CURRENT_BUFFER);
155-
156-
/*
157-
* Make a scan buffer with special termination needed by flex.
158-
*/
159-
scanbuf = (char *)palloc(slen +2);
160-
memcpy(scanbuf, str, slen);
161-
scanbuf[slen] = scanbuf[slen +1] = YY_END_OF_BUFFER_CHAR;
162-
scanbufhandle =yy_scan_buffer(scanbuf, slen +2);
163-
164-
/* Make sure we start in proper state */
165-
BEGIN(INITIAL);
175+
pfree(yyextra);
176+
yylex_destroy(yyscanner);
177+
}
178+
179+
/*
180+
* Interface functions to make flex use palloc() instead of malloc().
181+
* It'd be better to make these static, but flex insists otherwise.
182+
*/
183+
184+
void *
185+
yyalloc(yy_size_t size,yyscan_t yyscanner)
186+
{
187+
returnpalloc(size);
188+
}
189+
190+
void *
191+
yyrealloc(void *ptr,yy_size_t size,yyscan_t yyscanner)
192+
{
193+
if (ptr)
194+
returnrepalloc(ptr, size);
195+
else
196+
returnpalloc(size);
166197
}
167198

168199
void
169-
syncrep_scanner_finish(void)
200+
yyfree(void *ptr,yyscan_t yyscanner)
170201
{
171-
yy_delete_buffer(scanbufhandle);
172-
scanbufhandle =NULL;
202+
if (ptr)
203+
pfree(ptr);
173204
}

‎src/include/replication/syncrep.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,15 @@ extern void SyncRepUpdateSyncStandbysDefined(void);
100100
* Internal functions for parsing synchronous_standby_names grammar,
101101
* in syncrep_gram.y and syncrep_scanner.l
102102
*/
103-
externintsyncrep_yyparse(void);
104-
externintsyncrep_yylex(void);
105-
externvoidsyncrep_yyerror(constchar*str);
106-
externvoidsyncrep_scanner_init(constchar*str);
107-
externvoidsyncrep_scanner_finish(void);
103+
unionYYSTYPE;
104+
#ifndefYY_TYPEDEF_YY_SCANNER_T
105+
#defineYY_TYPEDEF_YY_SCANNER_T
106+
typedefvoid*yyscan_t;
107+
#endif
108+
externintsyncrep_yyparse(yyscan_tyyscanner);
109+
externintsyncrep_yylex(unionYYSTYPE*yylval_param,yyscan_tyyscanner);
110+
externvoidsyncrep_yyerror(yyscan_tyyscanner,constchar*str);
111+
externvoidsyncrep_scanner_init(constchar*str,yyscan_t*yyscannerp);
112+
externvoidsyncrep_scanner_finish(yyscan_tyyscanner);
108113

109114
#endif/* _SYNCREP_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp