Skip to content

xml_parsert: construct with message handler #8135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/xmllang/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

#include "xml_parser.h"

int yyxmllex();
extern char *yyxmltext;
int yyxmllex(void *);
char *yyxmlget_text(void *);

int yyxmlerror(const std::string &error)
int yyxmlerror(xml_parsert &xml_parser, void *scanner, const std::string &error)
{
xml_parser.parse_error(error, yyxmltext);
xml_parser.parse_error(error, yyxmlget_text(scanner));
return 0;
}

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

%parse-param {xml_parsert &xml_parser}
%parse-param {void *scanner}
%lex-param {void *scanner}

%union {char *s;}

%token STARTXMLDECL
Expand Down
11 changes: 5 additions & 6 deletions src/xmllang/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
%option noinput
%option nounistd
%option never-interactive
%option noyywrap
%option reentrant
%option extra-type="xml_parsert *"

%{

Expand All @@ -19,7 +22,7 @@
#include "xml_parser.h"
#include "xml_y.tab.h"

#define PARSER xml_parser
#define PARSER (*yyextra)

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

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

. { yyxmlerror("unexpected character"); }
. { yyxmlerror(*yyextra, yyscanner, "unexpected character"); }
{nl} {/* skip, must be an extra one at EOF */;}

%%

int yywrap() { return 1; }
24 changes: 17 additions & 7 deletions src/xmllang/xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,20 @@ Author: Daniel Kroening, [email protected]

#include <fstream>

xml_parsert xml_parser;
int xml_parsert::instance_count = 0;

int yyxmllex_init_extra(xml_parsert *, void **);
int yyxmllex_destroy(void *);
int yyxmlparse(xml_parsert &, void *);

bool xml_parsert::parse()
{
void *scanner;
yyxmllex_init_extra(this, &scanner);
bool parse_fail = yyxmlparse(*this, scanner) != 0;
yyxmllex_destroy(scanner);
return parse_fail;
}

// 'do it all' function
bool parse_xml(
Expand All @@ -19,19 +32,16 @@ bool parse_xml(
message_handlert &message_handler,
xmlt &dest)
{
xml_parser.clear();
xml_parsert xml_parser{message_handler};

xml_parser.set_file(filename);
xml_parser.in=&in;
xml_parser.log.set_message_handler(message_handler);

bool result=yyxmlparse()!=0;
bool result = xml_parser.parse();

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

// save some memory
xml_parser.clear();

return result;
}

Expand Down
35 changes: 25 additions & 10 deletions src/xmllang/xml_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,25 @@ Author: Daniel Kroening, [email protected]

#include "xml_parse_tree.h"

int yyxmlparse();

class xml_parsert:public parsert
{
public:
explicit xml_parsert(message_handlert &message_handler)
: parsert(message_handler)
{
// Simplistic check that we don't attempt to do reentrant parsing as the
// Bison-generated parser has global state.
PRECONDITION(++instance_count == 1);
stack.push_back(&parse_tree.element);
}

xml_parsert(const xml_parsert &) = delete;

~xml_parsert() override
{
--instance_count;
}

xml_parse_treet parse_tree;

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

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

void new_level()
{
current().elements.push_back(xmlt());
stack.push_back(&current().elements.back());
}

virtual void clear()
/// Clears the parser state. May be removed in future as there should not be a
/// need to re-use an existing parser object.
void clear() override
{
parse_tree.clear();
// set up stack
stack.clear();
stack.push_back(&parse_tree.element);
parsert::clear();
}
};

extern xml_parsert xml_parser;
protected:
static int instance_count;
};

int yyxmlerror(const std::string &error);
int yyxmlerror(xml_parsert &, void *, const std::string &);

// 'do it all' functions
bool parse_xml(
Expand Down