Skip to content

Commit 8560cdc

Browse files
authored
Merge pull request #8135 from tautschnig/cleanup/xml_parsert
xml_parsert: construct with message handler
2 parents e7520d0 + 9f01d3e commit 8560cdc

File tree

4 files changed

+55
-27
lines changed

4 files changed

+55
-27
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

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

1111
#include <fstream>
1212

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

1528
// 'do it all' function
1629
bool parse_xml(
@@ -19,19 +32,16 @@ bool parse_xml(
1932
message_handlert &message_handler,
2033
xmlt &dest)
2134
{
22-
xml_parser.clear();
35+
xml_parsert xml_parser{message_handler};
36+
2337
xml_parser.set_file(filename);
2438
xml_parser.in=&in;
25-
xml_parser.log.set_message_handler(message_handler);
2639

27-
bool result=yyxmlparse()!=0;
40+
bool result = xml_parser.parse();
2841

2942
// save result
3043
xml_parser.parse_tree.element.swap(dest);
3144

32-
// save some memory
33-
xml_parser.clear();
34-
3545
return result;
3646
}
3747

Diff for: src/xmllang/xml_parser.h

+25-10
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,25 @@ 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+
// Simplistic check that we don't attempt to do reentrant parsing as the
24+
// Bison-generated parser has global state.
25+
PRECONDITION(++instance_count == 1);
26+
stack.push_back(&parse_tree.element);
27+
}
28+
29+
xml_parsert(const xml_parsert &) = delete;
30+
31+
~xml_parsert() override
32+
{
33+
--instance_count;
34+
}
35+
2236
xml_parse_treet parse_tree;
2337

2438
std::list<xmlt *> stack;
@@ -28,29 +42,30 @@ class xml_parsert:public parsert
2842
return *stack.back();
2943
}
3044

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

3647
void new_level()
3748
{
3849
current().elements.push_back(xmlt());
3950
stack.push_back(&current().elements.back());
4051
}
4152

42-
virtual void clear()
53+
/// Clears the parser state. May be removed in future as there should not be a
54+
/// need to re-use an existing parser object.
55+
void clear() override
4356
{
4457
parse_tree.clear();
4558
// set up stack
4659
stack.clear();
4760
stack.push_back(&parse_tree.element);
61+
parsert::clear();
4862
}
49-
};
5063

51-
extern xml_parsert xml_parser;
64+
protected:
65+
static int instance_count;
66+
};
5267

53-
int yyxmlerror(const std::string &error);
68+
int yyxmlerror(xml_parsert &, void *, const std::string &);
5469

5570
// 'do it all' functions
5671
bool parse_xml(

0 commit comments

Comments
 (0)