Allow adding source blocks to the top the of header and source files
This commit is contained in:
parent
7b8ebfcef1
commit
9c990ae801
8 changed files with 81 additions and 5 deletions
|
@ -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,
|
||||
const std::map<std::string, std::string> &nonterm_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::map<symbol_t, std::pair<std::string, std::string>> &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++) {
|
||||
item_t rule = std::get<0>(rules[i]);
|
||||
|
||||
|
|
|
@ -63,6 +63,10 @@ private:
|
|||
std::map<std::string, std::string> nonterm_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);
|
||||
std::set<item_t> get_set(const std::string &nonterm);
|
||||
|
||||
|
@ -152,9 +156,19 @@ public:
|
|||
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,
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ struct keyword_t {
|
|||
|
||||
/* the keyword list must be sorted */
|
||||
static const keyword_t keywords[] = {
|
||||
{"%header", TOK_HEADER},
|
||||
{"%source", TOK_SOURCE},
|
||||
{"%type", TOK_TYPE},
|
||||
};
|
||||
|
||||
|
|
|
@ -88,6 +88,11 @@ void output_t::emit_token_value() {
|
|||
}
|
||||
|
||||
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_token_value();
|
||||
|
||||
|
@ -261,12 +266,15 @@ void output_t::emit_header_include() {
|
|||
const char *slash = std::strrchr(header_filename.c_str(), sep);
|
||||
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() {
|
||||
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, "\t%stoken_value_t token;\n", prefix());
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ enum parser_state {
|
|||
STATE_TYPE_NONTERM,
|
||||
STATE_TYPE_TERM,
|
||||
STATE_TYPE_TERM_BLOCK,
|
||||
STATE_HEADER,
|
||||
STATE_SOURCE,
|
||||
};
|
||||
|
||||
struct parser {
|
||||
|
@ -70,6 +72,14 @@ int parser_push(parser_t *parser, int token, const parser_value_t *value, parser
|
|||
parser->state = STATE_TYPE;
|
||||
return 1;
|
||||
|
||||
case TOK_SOURCE:
|
||||
parser->state = STATE_SOURCE;
|
||||
return 1;
|
||||
|
||||
case TOK_HEADER:
|
||||
parser->state = STATE_HEADER;
|
||||
return 1;
|
||||
|
||||
case 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;
|
||||
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) {
|
||||
|
|
|
@ -41,6 +41,8 @@ enum parser_token_t {
|
|||
TOK_CHAR,
|
||||
TOK_UINT,
|
||||
TOK_TYPE,
|
||||
TOK_SOURCE,
|
||||
TOK_HEADER,
|
||||
};
|
||||
|
||||
typedef struct parser_value {
|
||||
|
|
|
@ -44,6 +44,9 @@ private:
|
|||
std::string current_var;
|
||||
std::string current_type;
|
||||
|
||||
std::string header_block;
|
||||
std::string source_block;
|
||||
|
||||
public:
|
||||
parser_state_t() : current("") {}
|
||||
|
||||
|
@ -59,6 +62,22 @@ public:
|
|||
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 add_rule_nonterminal(const char *nonterm);
|
||||
void add_rule_terminal(const char *term);
|
||||
|
|
|
@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
|
|||
if (!read_grammar(argv[1], &state))
|
||||
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.write();
|
||||
|
|
Reference in a new issue