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"