Skip to content

Commit 898c9fe

Browse files
committed
xml_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 09dca35 commit 898c9fe

File tree

4 files changed

+37
-24
lines changed

4 files changed

+37
-24
lines changed

Diff for: src/xmllang/parser.y

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
#include "xml_parser.h"
55

6-
int yyxmllex();
7-
extern char *yyxmltext;
6+
int yyxmllex(void *);
7+
char *yyxmlget_text(void *);
88

9-
int yyxmlerror(const std::string &error)
9+
int yyxmlerror(xml_parsert &xml_parser, void *scanner, const std::string &error)
1010
{
11-
xml_parser.parse_error(error, yyxmltext);
11+
xml_parser.parse_error(error, yyxmlget_text(scanner));
1212
return 0;
1313
}
1414

@@ -26,6 +26,10 @@ int yyxmlerror(const std::string &error)
2626
#endif
2727
%}
2828

29+
%parse-param {xml_parsert &xml_parser}
30+
%parse-param {void *scanner}
31+
%lex-param {void *scanner}
32+
2933
%union {char *s;}
3034

3135
%token STARTXMLDECL

Diff for: src/xmllang/scanner.l

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
%option noinput
44
%option nounistd
55
%option never-interactive
6+
%option noyywrap
7+
%option reentrant
8+
%option extra-type="xml_parsert *"
69

710
%{
811

@@ -19,7 +22,7 @@
1922
#include "xml_parser.h"
2023
#include "xml_y.tab.h"
2124

22-
#define PARSER xml_parser
25+
#define PARSER (*yyextra)
2326

2427
//static int keep; /* To store start condition */
2528

@@ -87,9 +90,5 @@ string \"([^"&]|{esc})*\"|\'([^'&]|{esc})*\'
8790
<DTD>. {/* skip */}
8891
<DTD>\]{close} {BEGIN(INITIAL); /* skip */}
8992

90-
. { yyxmlerror("unexpected character"); }
93+
. { yyxmlerror(*yyextra, yyscanner, "unexpected character"); }
9194
{nl} {/* skip, must be an extra one at EOF */;}
92-
93-
%%
94-
95-
int yywrap() { return 1; }

Diff for: src/xmllang/xml_parser.cpp

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

1111
#include <fstream>
1212

13-
xml_parsert xml_parser;
13+
int yyxmllex_init_extra(xml_parsert *, void **);
14+
int yyxmllex_destroy(void *);
15+
int yyxmlparse(xml_parsert &, void *);
16+
17+
bool xml_parsert::parse()
18+
{
19+
void *scanner;
20+
yyxmllex_init_extra(this, &scanner);
21+
bool parse_fail = yyxmlparse(*this, scanner) != 0;
22+
yyxmllex_destroy(scanner);
23+
return parse_fail;
24+
}
1425

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

27-
bool result=yyxmlparse()!=0;
38+
bool result = xml_parser.parse();
2839

2940
// save result
3041
xml_parser.parse_tree.element.swap(dest);

Diff for: src/xmllang/xml_parser.h

+9-10
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ Author: Daniel Kroening, [email protected]
1414

1515
#include "xml_parse_tree.h"
1616

17-
int yyxmlparse();
18-
1917
class xml_parsert:public parsert
2018
{
2119
public:
20+
explicit xml_parsert(message_handlert &message_handler)
21+
: parsert(message_handler)
22+
{
23+
clear();
24+
}
25+
2226
xml_parse_treet parse_tree;
2327

2428
std::list<xmlt *> stack;
@@ -28,18 +32,15 @@ class xml_parsert:public parsert
2832
return *stack.back();
2933
}
3034

31-
virtual bool parse()
32-
{
33-
return yyxmlparse()!=0;
34-
}
35+
bool parse() override;
3536

3637
void new_level()
3738
{
3839
current().elements.push_back(xmlt());
3940
stack.push_back(&current().elements.back());
4041
}
4142

42-
virtual void clear()
43+
void clear() override
4344
{
4445
parse_tree.clear();
4546
// set up stack
@@ -48,9 +49,7 @@ class xml_parsert:public parsert
4849
}
4950
};
5051

51-
extern xml_parsert xml_parser;
52-
53-
int yyxmlerror(const std::string &error);
52+
int yyxmlerror(xml_parsert &, void *, const std::string &);
5453

5554
// 'do it all' functions
5655
bool parse_xml(

0 commit comments

Comments
 (0)