Skip to content

Commit

Permalink
json_parsert: construct with message handler
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tautschnig committed Jan 8, 2024
1 parent 6438259 commit 63e5910
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 26 deletions.
17 changes: 14 additions & 3 deletions src/json/json_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@ Author: Daniel Kroening, [email protected]

#include <fstream>

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(
Expand All @@ -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=&in;
json_parser.log.set_message_handler(message_handler);

bool result=json_parser.parse();

Expand Down
18 changes: 6 additions & 12 deletions src/json/json_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,20 @@ Author: Daniel Kroening, [email protected]
#include <util/parser.h>
#include <util/json.h>

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<jsont, std::vector<jsont> > stackt;
stackt stack;

jsont &top() { return stack.top(); }

virtual bool parse() override
{
return yyjsonparse()!=0;
}
bool parse() override;

void push(const jsont &x)
{
Expand All @@ -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,
Expand Down
24 changes: 15 additions & 9 deletions src/json/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@

#include <util/unicode.h>

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;
Expand Down Expand Up @@ -70,19 +72,23 @@ 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;
}

%}

%parse-param {json_parsert &json_parser}
%parse-param {void *scanner}
%lex-param {void *scanner}

%token TOK_STRING
%token TOK_NUMBER
%token TOK_TRUE
Expand All @@ -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
{
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/json/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
%option noinput
%option nounistd
%option never-interactive

%option noyywrap
%option reentrant
%option extra-type="json_parsert *"

%{

Expand All @@ -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"
Expand Down

0 comments on commit 63e5910

Please sign in to comment.