From 63e59107d28145072f94e0415124ffb020839597 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 20 Dec 2023 13:24:14 +0000 Subject: [PATCH] json_parsert: construct with message handler This both avoids an object of static lifetime as well as it fixes the (transitive) use of the deprecated messaget() constructor. Both the parser and lexer are now fully reentrant. --- src/json/json_parser.cpp | 17 ++++++++++++++--- src/json/json_parser.h | 18 ++++++------------ src/json/parser.y | 24 +++++++++++++++--------- src/json/scanner.l | 5 +++-- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/json/json_parser.cpp b/src/json/json_parser.cpp index cb30114cb39..cfc636dc4a5 100644 --- a/src/json/json_parser.cpp +++ b/src/json/json_parser.cpp @@ -10,7 +10,18 @@ Author: Daniel Kroening, kroening@kroening.com #include -json_parsert json_parser; +int yyjsonlex_init_extra(json_parsert *, void **); +int yyjsonlex_destroy(void *); +int yyjsonparse(json_parsert &, void *); + +bool json_parsert::parse() +{ + void *scanner; + yyjsonlex_init_extra(this, &scanner); + bool parse_fail = yyjsonparse(*this, scanner) != 0; + yyjsonlex_destroy(scanner); + return parse_fail; +} // 'do it all' function bool parse_json( @@ -19,10 +30,10 @@ bool parse_json( message_handlert &message_handler, jsont &dest) { - json_parser.clear(); + json_parsert json_parser{message_handler}; + json_parser.set_file(filename); json_parser.in=∈ - json_parser.log.set_message_handler(message_handler); bool result=json_parser.parse(); diff --git a/src/json/json_parser.h b/src/json/json_parser.h index 926a30e10bf..132a399a6a5 100644 --- a/src/json/json_parser.h +++ b/src/json/json_parser.h @@ -15,21 +15,20 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -int yyjsonparse(); -void yyjsonrestart(FILE *input_file); - class json_parsert:public parsert { public: + explicit json_parsert(message_handlert &message_handler) + : parsert(message_handler) + { + } + typedef std::stack > stackt; stackt stack; jsont &top() { return stack.top(); } - virtual bool parse() override - { - return yyjsonparse()!=0; - } + bool parse() override; void push(const jsont &x) { @@ -46,14 +45,9 @@ class json_parsert:public parsert virtual void clear() override { stack=stackt(); - yyjsonrestart(nullptr); } }; -extern json_parsert json_parser; - -int yyjsonerror(const std::string &error); - // 'do it all' functions bool parse_json( std::istream &in, diff --git a/src/json/parser.y b/src/json/parser.y index facaf48638d..fd001f8ab75 100644 --- a/src/json/parser.y +++ b/src/json/parser.y @@ -20,11 +20,13 @@ #include -int yyjsonlex(); -extern char *yyjsontext; -extern int yyjsonleng; // really an int, not a size_t +int yyjsonlex(void *); +char *yyjsonget_text(void *); +#define yyjsontext yyjsonget_text(scanner) +int yyjsonget_leng(void *); // really an int, not a size_t +#define yyjsonleng yyjsonget_leng(scanner) -static std::string convert_TOK_STRING() +static std::string convert_TOK_STRING(void *scanner) { PRECONDITION(yyjsontext[0]=='"'); std::size_t len=yyjsonleng; @@ -70,12 +72,12 @@ static std::string convert_TOK_STRING() return result; } -static std::string convert_TOK_NUMBER() +static std::string convert_TOK_NUMBER(void *scanner) { return yyjsontext; } -int yyjsonerror(const std::string &error) +int yyjsonerror(json_parsert &json_parser, void *scanner, const std::string &error) { json_parser.parse_error(error, yyjsontext); return 0; @@ -83,6 +85,10 @@ int yyjsonerror(const std::string &error) %} +%parse-param {json_parsert &json_parser} +%parse-param {void *scanner} +%lex-param {void *scanner} + %token TOK_STRING %token TOK_NUMBER %token TOK_TRUE @@ -109,7 +115,7 @@ key_value_pair: TOK_STRING { // we abuse the 'value' to temporarily store the key - json_parser.top().value=convert_TOK_STRING(); + json_parser.top().value=convert_TOK_STRING(scanner); } ':' value { @@ -139,9 +145,9 @@ array_value: ; value : TOK_STRING - { json_parser.push(json_stringt(convert_TOK_STRING())); } + { json_parser.push(json_stringt(convert_TOK_STRING(scanner))); } | TOK_NUMBER - { json_parser.push(json_numbert(convert_TOK_NUMBER())); } + { json_parser.push(json_numbert(convert_TOK_NUMBER(scanner))); } | object | array | TOK_TRUE diff --git a/src/json/scanner.l b/src/json/scanner.l index c10efc414fb..95e07f8559a 100755 --- a/src/json/scanner.l +++ b/src/json/scanner.l @@ -11,8 +11,9 @@ %option noinput %option nounistd %option never-interactive - %option noyywrap +%option reentrant +%option extra-type="json_parsert *" %{ @@ -24,7 +25,7 @@ #pragma warning(disable:4005) #endif -#define PARSER json_parser +#define PARSER (*yyextra) #include "json_parser.h" #include "json_y.tab.h"