summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-04-08 23:49:42 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-04-08 23:49:42 +0200
commit9c990ae801b949de2728bfff4258aa90f9c96a52 (patch)
treeba2742dc1b3ef0b9898e20a6162e54fb58f440e2
parent7b8ebfcef1dada98ff36aeb4d16cd3c06517e879 (diff)
downloadsolar-9c990ae801b949de2728bfff4258aa90f9c96a52.tar
solar-9c990ae801b949de2728bfff4258aa90f9c96a52.zip
Allow adding source blocks to the top the of header and source files
-rw-r--r--src/generator.cpp6
-rw-r--r--src/generator.hpp16
-rw-r--r--src/lex.cpp2
-rw-r--r--src/output.cpp10
-rw-r--r--src/parser.cpp29
-rw-r--r--src/parser.hpp2
-rw-r--r--src/parser_state.hpp19
-rw-r--r--src/solar.cpp2
8 files changed, 81 insertions, 5 deletions
diff --git a/src/generator.cpp b/src/generator.cpp
index 9350f40..31dac2a 100644
--- a/src/generator.cpp
+++ b/src/generator.cpp
@@ -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]);
diff --git a/src/generator.hpp b/src/generator.hpp
index 5f2cb22..23f4f9d 100644
--- a/src/generator.hpp
+++ b/src/generator.hpp
@@ -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);
};
}
diff --git a/src/lex.cpp b/src/lex.cpp
index 3adfb5b..7dfc013 100644
--- a/src/lex.cpp
+++ b/src/lex.cpp
@@ -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},
};
diff --git a/src/output.cpp b/src/output.cpp
index 72e9a6e..e1ca496 100644
--- a/src/output.cpp
+++ b/src/output.cpp
@@ -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());
diff --git a/src/parser.cpp b/src/parser.cpp
index 9d2fbce..84159dc 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -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) {
diff --git a/src/parser.hpp b/src/parser.hpp
index f677bf1..9117914 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -41,6 +41,8 @@ enum parser_token_t {
TOK_CHAR,
TOK_UINT,
TOK_TYPE,
+ TOK_SOURCE,
+ TOK_HEADER,
};
typedef struct parser_value {
diff --git a/src/parser_state.hpp b/src/parser_state.hpp
index 882fec2..b183898 100644
--- a/src/parser_state.hpp
+++ b/src/parser_state.hpp
@@ -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);
diff --git a/src/solar.cpp b/src/solar.cpp
index f3b04f6..46c7fad 100644
--- a/src/solar.cpp
+++ b/src/solar.cpp
@@ -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();