From ab6e50ec0ac5e7ef79a373cccf9319ba9a985782 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 3 Dec 2024 15:23:36 +0100 Subject: [PATCH v1 16/19] bootstrap: pure parser and reentrant scanner --- src/backend/bootstrap/bootparse.y | 9 +++-- src/backend/bootstrap/bootscanner.l | 61 +++++++++++++++-------------- src/backend/bootstrap/bootstrap.c | 6 ++- src/include/bootstrap/bootstrap.h | 9 +++-- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 73a7592fb71..05ef26c07d0 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -34,10 +34,6 @@ #include "bootparse.h" -/* silence -Wmissing-variable-declarations */ -extern int boot_yychar; -extern int boot_yynerrs; - /* * Bison doesn't allocate anything that needs to live across parser calls, @@ -81,6 +77,9 @@ static int num_columns_read = 0; %} +%parse-param {yyscan_t yyscanner} +%lex-param {yyscan_t yyscanner} +%pure-parser %expect 0 %name-prefix="boot_yy" @@ -141,6 +140,8 @@ Boot_OpenStmt: do_start(); boot_openrel($2); do_end(); + + (void) yynerrs; /* suppress compiler warning */ } ; diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index 31d63ff3015..c4e7139fa41 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -39,11 +39,10 @@ fprintf_to_ereport(const char *fmt, const char *msg) ereport(ERROR, (errmsg_internal("%s", msg))); } - -static int yyline = 1; /* line number for error reporting */ - %} +%option reentrant +%option bison-bridge %option 8bit %option never-interactive %option nodefault @@ -58,7 +57,7 @@ id [-A-Za-z0-9_]+ sid \'([^']|\'\')*\' /* - * Keyword tokens return the keyword text (as a constant string) in boot_yylval.kw, + * Keyword tokens return the keyword text (as a constant string) in yylval->kw, * just in case that's needed because we want to treat the keyword as an * unreserved identifier. Note that _null_ is not treated as a keyword * for this purpose; it's the one "reserved word" in the bootstrap syntax. @@ -66,23 +65,23 @@ sid \'([^']|\'\')*\' * Notice that all the keywords are case-sensitive, and for historical * reasons some must be upper case. * - * String tokens return a palloc'd string in boot_yylval.str. + * String tokens return a palloc'd string in yylval->str. */ %% -open { boot_yylval.kw = "open"; return OPEN; } +open { yylval->kw = "open"; return OPEN; } -close { boot_yylval.kw = "close"; return XCLOSE; } +close { yylval->kw = "close"; return XCLOSE; } -create { boot_yylval.kw = "create"; return XCREATE; } +create { yylval->kw = "create"; return XCREATE; } -OID { boot_yylval.kw = "OID"; return OBJ_ID; } -bootstrap { boot_yylval.kw = "bootstrap"; return XBOOTSTRAP; } -shared_relation { boot_yylval.kw = "shared_relation"; return XSHARED_RELATION; } -rowtype_oid { boot_yylval.kw = "rowtype_oid"; return XROWTYPE_OID; } +OID { yylval->kw = "OID"; return OBJ_ID; } +bootstrap { yylval->kw = "bootstrap"; return XBOOTSTRAP; } +shared_relation { yylval->kw = "shared_relation"; return XSHARED_RELATION; } +rowtype_oid { yylval->kw = "rowtype_oid"; return XROWTYPE_OID; } -insert { boot_yylval.kw = "insert"; return INSERT_TUPLE; } +insert { yylval->kw = "insert"; return INSERT_TUPLE; } _null_ { return NULLVAL; } @@ -91,35 +90,35 @@ _null_ { return NULLVAL; } "(" { return LPAREN; } ")" { return RPAREN; } -[\n] { yyline++; } +[\n] { yylineno++; } [\r\t ] ; ^\#[^\n]* ; /* drop everything after "#" for comments */ -declare { boot_yylval.kw = "declare"; return XDECLARE; } -build { boot_yylval.kw = "build"; return XBUILD; } -indices { boot_yylval.kw = "indices"; return INDICES; } -unique { boot_yylval.kw = "unique"; return UNIQUE; } -index { boot_yylval.kw = "index"; return INDEX; } -on { boot_yylval.kw = "on"; return ON; } -using { boot_yylval.kw = "using"; return USING; } -toast { boot_yylval.kw = "toast"; return XTOAST; } -FORCE { boot_yylval.kw = "FORCE"; return XFORCE; } -NOT { boot_yylval.kw = "NOT"; return XNOT; } -NULL { boot_yylval.kw = "NULL"; return XNULL; } +declare { yylval->kw = "declare"; return XDECLARE; } +build { yylval->kw = "build"; return XBUILD; } +indices { yylval->kw = "indices"; return INDICES; } +unique { yylval->kw = "unique"; return UNIQUE; } +index { yylval->kw = "index"; return INDEX; } +on { yylval->kw = "on"; return ON; } +using { yylval->kw = "using"; return USING; } +toast { yylval->kw = "toast"; return XTOAST; } +FORCE { yylval->kw = "FORCE"; return XFORCE; } +NOT { yylval->kw = "NOT"; return XNOT; } +NULL { yylval->kw = "NULL"; return XNULL; } {id} { - boot_yylval.str = pstrdup(yytext); + yylval->str = pstrdup(yytext); return ID; } {sid} { /* strip quotes and escapes */ - boot_yylval.str = DeescapeQuotedString(yytext); + yylval->str = DeescapeQuotedString(yytext); return ID; } . { - elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yyline, yytext); + elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yylineno, yytext); } %% @@ -127,7 +126,9 @@ NULL { boot_yylval.kw = "NULL"; return XNULL; } /* LCOV_EXCL_STOP */ void -boot_yyerror(const char *message) +boot_yyerror(yyscan_t yyscanner, const char *message) { - elog(ERROR, "%s at line %d", message, yyline); + struct yyguts_t * yyg = (struct yyguts_t *) yyscanner; /* needed for yylineno macro */ + + elog(ERROR, "%s at line %d", message, yylineno); } diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index a5217773ffc..388458a5724 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -202,6 +202,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only) int flag; char *userDoption = NULL; uint32 bootstrap_data_checksum_version = 0; /* No checksum */ + yyscan_t scanner; Assert(!IsUnderPostmaster); @@ -372,11 +373,14 @@ BootstrapModeMain(int argc, char *argv[], bool check_only) Nulls[i] = false; } + if (boot_yylex_init(&scanner) != 0) + elog(ERROR, "yylex_init() failed: %m"); + /* * Process bootstrap input. */ StartTransactionCommand(); - boot_yyparse(); + boot_yyparse(scanner); CommitTransactionCommand(); /* diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index 73b78b31335..ccec9415acb 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -55,9 +55,12 @@ extern void boot_get_type_io_data(Oid typid, Oid *typinput, Oid *typoutput); -extern int boot_yyparse(void); +union YYSTYPE; +typedef void *yyscan_t; -extern int boot_yylex(void); -extern void boot_yyerror(const char *message) pg_attribute_noreturn(); +extern int boot_yyparse(yyscan_t yyscanner); +extern int boot_yylex_init(yyscan_t *yyscannerp); +extern int boot_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner); +extern void boot_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn(); #endif /* BOOTSTRAP_H */ -- 2.47.1