Allow adding source blocks to the top the of header and source files

This commit is contained in:
Matthias Schiffer 2015-04-08 23:49:42 +02:00
parent 7b8ebfcef1
commit 9c990ae801
8 changed files with 81 additions and 5 deletions

View file

@ -119,8 +119,10 @@ void generator_t::generate_itemsets() {
generator_t::generator_t(const std::vector<std::tuple<item_t, std::vector<std::string>, std::string>> &rules0, generator_t::generator_t(const std::vector<std::tuple<item_t, std::vector<std::string>, std::string>> &rules0,
const std::map<std::string, std::string> &nonterm_types0, const std::map<std::string, std::string> &nonterm_types0,
const std::map<symbol_t, std::pair<std::string, std::string>> &term_types0) const std::map<symbol_t, std::pair<std::string, std::string>> &term_types0,
: rules(rules0), nonterm_types(nonterm_types0), term_types(term_types0) { const std::string &header_block0, const std::string &source_block0)
: rules(rules0), nonterm_types(nonterm_types0), term_types(term_types0),
header_block(header_block0), source_block(source_block0) {
for (size_t i = 0; i < rules.size(); i++) { for (size_t i = 0; i < rules.size(); i++) {
item_t rule = std::get<0>(rules[i]); item_t rule = std::get<0>(rules[i]);

View file

@ -63,6 +63,10 @@ private:
std::map<std::string, std::string> nonterm_types; std::map<std::string, std::string> nonterm_types;
std::map<symbol_t, std::pair<std::string, std::string>> term_types; std::map<symbol_t, std::pair<std::string, std::string>> term_types;
std::string header_block;
std::string source_block;
void close_set(std::set<item_t> *set); void close_set(std::set<item_t> *set);
std::set<item_t> get_set(const std::string &nonterm); std::set<item_t> get_set(const std::string &nonterm);
@ -152,9 +156,19 @@ public:
return gotos; return gotos;
} }
const std::string & get_header_block() const {
return header_block;
}
const std::string & get_source_block() const {
return source_block;
}
generator_t(const std::vector<std::tuple<item_t, std::vector<std::string>, std::string>> &rules0, generator_t(const std::vector<std::tuple<item_t, std::vector<std::string>, std::string>> &rules0,
const std::map<std::string, std::string> &nonterm_types0, const std::map<std::string, std::string> &nonterm_types0,
const std::map<symbol_t, std::pair<std::string, std::string>> &term_types0); const std::map<symbol_t, std::pair<std::string, std::string>> &term_types0,
const std::string &header_block0, const std::string &source_block0);
}; };
} }

View file

@ -42,6 +42,8 @@ struct keyword_t {
/* the keyword list must be sorted */ /* the keyword list must be sorted */
static const keyword_t keywords[] = { static const keyword_t keywords[] = {
{"%header", TOK_HEADER},
{"%source", TOK_SOURCE},
{"%type", TOK_TYPE}, {"%type", TOK_TYPE},
}; };

View file

@ -88,6 +88,11 @@ void output_t::emit_token_value() {
} }
void output_t::emit_header() { void output_t::emit_header() {
std::fprintf(header_file, "#pragma once\n\n");
if (!generator->get_header_block().empty())
std::fprintf(header_file, "%s\n", generator->get_header_block().c_str());
emit_tokens(); emit_tokens();
emit_token_value(); emit_token_value();
@ -261,12 +266,15 @@ void output_t::emit_header_include() {
const char *slash = std::strrchr(header_filename.c_str(), sep); const char *slash = std::strrchr(header_filename.c_str(), sep);
const char *basename = slash ? slash+1 : header_filename.c_str(); const char *basename = slash ? slash+1 : header_filename.c_str();
std::fprintf(source_file, "#include \"%s\"\n\n\n", basename); std::fprintf(source_file, "#include \"%s\"\n\n", basename);
} }
void output_t::emit_source() { void output_t::emit_source() {
emit_header_include(); emit_header_include();
if (!generator->get_source_block().empty())
std::fprintf(source_file, "%s\n\n", generator->get_source_block().c_str());
std::fprintf(source_file, "typedef union %ssymbol_value {\n", prefix()); std::fprintf(source_file, "typedef union %ssymbol_value {\n", prefix());
std::fprintf(source_file, "\t%stoken_value_t token;\n", prefix()); std::fprintf(source_file, "\t%stoken_value_t token;\n", prefix());

View file

@ -43,6 +43,8 @@ enum parser_state {
STATE_TYPE_NONTERM, STATE_TYPE_NONTERM,
STATE_TYPE_TERM, STATE_TYPE_TERM,
STATE_TYPE_TERM_BLOCK, STATE_TYPE_TERM_BLOCK,
STATE_HEADER,
STATE_SOURCE,
}; };
struct parser { struct parser {
@ -70,6 +72,14 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
parser->state = STATE_TYPE; parser->state = STATE_TYPE;
return 1; return 1;
case TOK_SOURCE:
parser->state = STATE_SOURCE;
return 1;
case TOK_HEADER:
parser->state = STATE_HEADER;
return 1;
case 0: case 0:
return 0; return 0;
} }
@ -224,6 +234,25 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
parser->state = STATE_INIT; parser->state = STATE_INIT;
return 1; return 1;
} }
case STATE_HEADER:
if (token == TOK_BLOCK) {
state->set_header_block(value->str);
free(value->str);
parser->state = STATE_INIT;
return 1;
}
break;
case STATE_SOURCE:
if (token == TOK_BLOCK) {
state->set_source_block(value->str);
free(value->str);
parser->state = STATE_INIT;
return 1;
}
break;
} }
switch (token) { switch (token) {

View file

@ -41,6 +41,8 @@ enum parser_token_t {
TOK_CHAR, TOK_CHAR,
TOK_UINT, TOK_UINT,
TOK_TYPE, TOK_TYPE,
TOK_SOURCE,
TOK_HEADER,
}; };
typedef struct parser_value { typedef struct parser_value {

View file

@ -44,6 +44,9 @@ private:
std::string current_var; std::string current_var;
std::string current_type; std::string current_type;
std::string header_block;
std::string source_block;
public: public:
parser_state_t() : current("") {} parser_state_t() : current("") {}
@ -59,6 +62,22 @@ public:
return term_types; return term_types;
} }
const std::string & get_header_block() const {
return header_block;
}
void set_header_block(const char *value) {
header_block = value;
}
const std::string & get_source_block() const {
return source_block;
}
void set_source_block(const char *value) {
source_block = value;
}
void new_rule(const char *nonterm); void new_rule(const char *nonterm);
void add_rule_nonterminal(const char *nonterm); void add_rule_nonterminal(const char *nonterm);
void add_rule_terminal(const char *term); void add_rule_terminal(const char *term);

View file

@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
if (!read_grammar(argv[1], &state)) if (!read_grammar(argv[1], &state))
return 1; return 1;
generator_t generator(state.get_rules(), state.get_nonterm_types(), state.get_term_types()); generator_t generator(state.get_rules(), state.get_nonterm_types(), state.get_term_types(), state.get_header_block(), state.get_source_block());
output_t output(&generator, argv[3], argv[2]); output_t output(&generator, argv[3], argv[2]);
output.write(); output.write();