Skip to content

Commit 63e5910

Browse files
committed
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.
1 parent 6438259 commit 63e5910

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

src/json/json_parser.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,18 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <fstream>
1212

13-
json_parsert json_parser;
13+
int yyjsonlex_init_extra(json_parsert *, void **);
14+
int yyjsonlex_destroy(void *);
15+
int yyjsonparse(json_parsert &, void *);
16+
17+
bool json_parsert::parse()
18+
{
19+
void *scanner;
20+
yyjsonlex_init_extra(this, &scanner);
21+
bool parse_fail = yyjsonparse(*this, scanner) != 0;
22+
yyjsonlex_destroy(scanner);
23+
return parse_fail;
24+
}
1425

1526
// 'do it all' function
1627
bool parse_json(
@@ -19,10 +30,10 @@ bool parse_json(
1930
message_handlert &message_handler,
2031
jsont &dest)
2132
{
22-
json_parser.clear();
33+
json_parsert json_parser{message_handler};
34+
2335
json_parser.set_file(filename);
2436
json_parser.in=&in;
25-
json_parser.log.set_message_handler(message_handler);
2637

2738
bool result=json_parser.parse();
2839

src/json/json_parser.h

+6-12
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,20 @@ Author: Daniel Kroening, [email protected]
1515
#include <util/parser.h>
1616
#include <util/json.h>
1717

18-
int yyjsonparse();
19-
void yyjsonrestart(FILE *input_file);
20-
2118
class json_parsert:public parsert
2219
{
2320
public:
21+
explicit json_parsert(message_handlert &message_handler)
22+
: parsert(message_handler)
23+
{
24+
}
25+
2426
typedef std::stack<jsont, std::vector<jsont> > stackt;
2527
stackt stack;
2628

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

29-
virtual bool parse() override
30-
{
31-
return yyjsonparse()!=0;
32-
}
31+
bool parse() override;
3332

3433
void push(const jsont &x)
3534
{
@@ -46,14 +45,9 @@ class json_parsert:public parsert
4645
virtual void clear() override
4746
{
4847
stack=stackt();
49-
yyjsonrestart(nullptr);
5048
}
5149
};
5250

53-
extern json_parsert json_parser;
54-
55-
int yyjsonerror(const std::string &error);
56-
5751
// 'do it all' functions
5852
bool parse_json(
5953
std::istream &in,

src/json/parser.y

+15-9
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
#include <util/unicode.h>
2222

23-
int yyjsonlex();
24-
extern char *yyjsontext;
25-
extern int yyjsonleng; // really an int, not a size_t
23+
int yyjsonlex(void *);
24+
char *yyjsonget_text(void *);
25+
#define yyjsontext yyjsonget_text(scanner)
26+
int yyjsonget_leng(void *); // really an int, not a size_t
27+
#define yyjsonleng yyjsonget_leng(scanner)
2628

27-
static std::string convert_TOK_STRING()
29+
static std::string convert_TOK_STRING(void *scanner)
2830
{
2931
PRECONDITION(yyjsontext[0]=='"');
3032
std::size_t len=yyjsonleng;
@@ -70,19 +72,23 @@ static std::string convert_TOK_STRING()
7072
return result;
7173
}
7274

73-
static std::string convert_TOK_NUMBER()
75+
static std::string convert_TOK_NUMBER(void *scanner)
7476
{
7577
return yyjsontext;
7678
}
7779

78-
int yyjsonerror(const std::string &error)
80+
int yyjsonerror(json_parsert &json_parser, void *scanner, const std::string &error)
7981
{
8082
json_parser.parse_error(error, yyjsontext);
8183
return 0;
8284
}
8385

8486
%}
8587

88+
%parse-param {json_parsert &json_parser}
89+
%parse-param {void *scanner}
90+
%lex-param {void *scanner}
91+
8692
%token TOK_STRING
8793
%token TOK_NUMBER
8894
%token TOK_TRUE
@@ -109,7 +115,7 @@ key_value_pair:
109115
TOK_STRING
110116
{
111117
// we abuse the 'value' to temporarily store the key
112-
json_parser.top().value=convert_TOK_STRING();
118+
json_parser.top().value=convert_TOK_STRING(scanner);
113119
}
114120
':' value
115121
{
@@ -139,9 +145,9 @@ array_value:
139145
;
140146

141147
value : TOK_STRING
142-
{ json_parser.push(json_stringt(convert_TOK_STRING())); }
148+
{ json_parser.push(json_stringt(convert_TOK_STRING(scanner))); }
143149
| TOK_NUMBER
144-
{ json_parser.push(json_numbert(convert_TOK_NUMBER())); }
150+
{ json_parser.push(json_numbert(convert_TOK_NUMBER(scanner))); }
145151
| object
146152
| array
147153
| TOK_TRUE

src/json/scanner.l

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
%option noinput
1212
%option nounistd
1313
%option never-interactive
14-
1514
%option noyywrap
15+
%option reentrant
16+
%option extra-type="json_parsert *"
1617

1718
%{
1819

@@ -24,7 +25,7 @@
2425
#pragma warning(disable:4005)
2526
#endif
2627

27-
#define PARSER json_parser
28+
#define PARSER (*yyextra)
2829

2930
#include "json_parser.h"
3031
#include "json_y.tab.h"

0 commit comments

Comments
 (0)