summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-04-10 16:48:43 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-04-10 16:48:43 +0200
commit5a54699f18e3ac52fe18d854f6d57be6795ed8e5 (patch)
tree9c73cd95b8486e49b6258ff93ffbebed611dec02
parenta5d1689bc7e05983a44cef5310ae7c50e10fefce (diff)
downloadsolar-5a54699f18e3ac52fe18d854f6d57be6795ed8e5.tar
solar-5a54699f18e3ac52fe18d854f6d57be6795ed8e5.zip
Replace hand-written parser by one generated by solar itself :D
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/lex.cpp35
-rw-r--r--src/lex.hpp24
-rw-r--r--src/parse.cpp1548
-rw-r--r--src/parse.hpp28
-rw-r--r--src/parse.y143
-rw-r--r--src/parser.cpp302
-rw-r--r--src/parser.hpp62
-rw-r--r--src/parser_state.cpp86
-rw-r--r--src/parser_state.hpp83
-rw-r--r--src/solar.cpp23
11 files changed, 1762 insertions, 575 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3f2be49..22c1ea6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,8 +6,7 @@ add_executable(solar
output.cpp
output_lr0.cpp
output_slr.cpp
- parser.cpp
- parser_state.cpp
+ parse.cpp
solar.cpp
)
set_target_properties(solar PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall")
diff --git a/src/lex.cpp b/src/lex.cpp
index 63549c9..c5ae330 100644
--- a/src/lex.cpp
+++ b/src/lex.cpp
@@ -101,20 +101,21 @@ void lex_t::consume(bool consume_needspace) {
needspace = consume_needspace;
}
-int lex_t::io_error(parser_value_t *value) {
- value->error = "I/O error";
+int lex_t::io_error(parse_token_value_t *value) {
+ //value->error = "I/O error";
+ (void)value;
return -1;
}
-int lex_t::syntax_error(parser_value_t *value) {
+int lex_t::syntax_error(parse_token_value_t *value) {
if (std::ferror(file))
return io_error(value);
- value->error = "syntax error";
+ //value->error = "syntax error";
return -1;
}
-int lex_t::consume_comment(parser_value_t *value) {
+int lex_t::consume_comment(parse_token_value_t *value) {
char prev = 0;
while (next(true)) {
@@ -130,20 +131,20 @@ int lex_t::consume_comment(parser_value_t *value) {
if (std::ferror(file))
return io_error(value);
- value->error = "unterminated block comment";
+ //value->error = "unterminated block comment";
return -1;
}
/*
-int lex_t::unterminated_string(parser_value_t *value) {
+int lex_t::unterminated_string(parse_token_value_t *value) {
if (ferror(file))
return io_error(value);
- value->error = "unterminated string";
+ //value->error = "unterminated string";
return -1;
}
-int lex_t::lex_string(parser_value_t *value) {
+int lex_t::lex_string(parse_token_value_t *value) {
char *buf = NULL;
size_t len = 1024;
size_t pos = 0;
@@ -193,7 +194,7 @@ int lex_t::lex_string(parser_value_t *value) {
return TOK_STRING;
}
-int lex_t::lex_number(parser_value_t *value) {
+int lex_t::lex_number(parse_token_value_t *value) {
if (needspace)
return syntax_error(value);
@@ -223,7 +224,7 @@ int lex_t::lex_number(parser_value_t *value) {
return TOK_UINT;
}*/
-int lex_t::lex_keyword(parser_value_t *value) {
+int lex_t::lex_keyword(parse_token_value_t *value) {
if (needspace)
return syntax_error(value);
@@ -247,15 +248,15 @@ int lex_t::lex_keyword(parser_value_t *value) {
return ret->token;
}
-int lex_t::unterminated_block(parser_value_t *value) {
+int lex_t::unterminated_block(parse_token_value_t *value) {
if (ferror(file))
return io_error(value);
- value->error = "unterminated code block";
+ //value->error = "unterminated code block";
return -1;
}
-int lex_t::lex_block(parser_value_t *value) {
+int lex_t::lex_block(parse_token_value_t *value) {
size_t parens = 0;
bool line_comment = false;
bool block_comment = false;
@@ -326,7 +327,7 @@ int lex_t::lex_block(parser_value_t *value) {
return TOK_BLOCK;
}
-int lex_t::lex_symbol(parser_value_t *value) {
+int lex_t::lex_symbol(parse_token_value_t *value) {
if (needspace)
return syntax_error(value);
@@ -361,7 +362,7 @@ int lex_t::lex_symbol(parser_value_t *value) {
return TOK_SYMBOL;
}
-int lex_t::lex(parser_value_t *value) {
+int lex_t::lex(parse_token_value_t *value) {
int token;
while (end > start) {
@@ -416,7 +417,7 @@ int lex_t::lex(parser_value_t *value) {
if (!next(true))
return syntax_error(value);
- value->number = current();
+ value->c = current();
if (!next(true) || current() != '\'')
return syntax_error(value);
diff --git a/src/lex.hpp b/src/lex.hpp
index 7405279..e240e12 100644
--- a/src/lex.hpp
+++ b/src/lex.hpp
@@ -26,7 +26,7 @@
#pragma once
-#include "parser.hpp"
+#include "parse.hpp"
#include <cstdio>
#include <cstring>
@@ -62,17 +62,17 @@ private:
bool next(bool move);
void consume(bool needspace);
- int io_error(parser_value_t *value);
- int syntax_error(parser_value_t *value);
- int consume_comment(parser_value_t *value);
- int unterminated_block(parser_value_t *value);
- //int unterminated_string(parser_value_t *value);
+ int io_error(parse_token_value_t *value);
+ int syntax_error(parse_token_value_t *value);
+ int consume_comment(parse_token_value_t *value);
+ int unterminated_block(parse_token_value_t *value);
+ //int unterminated_string(parse_token_value_t *value);
- //int lex_string(parser_value_t *value);
- //int lex_number(parser_value_t *value);
- int lex_keyword(parser_value_t *value);
- int lex_block(parser_value_t *value);
- int lex_symbol(parser_value_t *value);
+ //int lex_string(parse_token_value_t *value);
+ //int lex_number(parse_token_value_t *value);
+ int lex_keyword(parse_token_value_t *value);
+ int lex_block(parse_token_value_t *value);
+ int lex_symbol(parse_token_value_t *value);
char current() {
return buffer[start + tok_len];
@@ -92,7 +92,7 @@ public:
fclose(file);
}
- int lex(parser_value_t *value);
+ int lex(parse_token_value_t *value);
const location_t & get_location() const {
return loc;
diff --git a/src/parse.cpp b/src/parse.cpp
new file mode 100644
index 0000000..fba7e79
--- /dev/null
+++ b/src/parse.cpp
@@ -0,0 +1,1548 @@
+#include "parse.hpp"
+
+typedef union parse_symbol_value {
+ parse_token_value_t token;
+ std::string * symbol_action;
+ std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * symbol_rhs;
+ solar::rule_t * symbol_rule;
+ solar::symbol_t * symbol_symbol;
+ solar::symbol_t * symbol_term;
+ std::string * symbol_varname;
+} parse_symbol_value_t;
+
+typedef struct parse_context_state {
+ unsigned state;
+ parse_symbol_value_t value;
+} parse_context_state_t;
+
+struct parse_context {
+ unsigned top;
+ parse_context_state_t stack[100];
+};
+
+
+parse_context_t * parse_alloc(void *(*alloc_func)(size_t)) {
+ parse_context_t *parser = (parse_context_t *)alloc_func(sizeof(parse_context_t));
+ parser->top = 0;
+ parser->stack[0].state = 0;
+ return parser;
+}
+
+void parse_free(parse_context_t *parser, void (*free_func)(void *)) {
+ free_func(parser);
+}
+
+static inline void parse_reduce_2(solar::rule_t * rule, __attribute__((unused)) solar::grammar_t * grammar) {
+ if (grammar->rules.empty()) {
+ solar::item_t init("");
+ init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str()));
+ grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()});
+ }
+
+ grammar->rules.push_back(*rule);
+ delete rule;
+}
+
+static inline void parse_reduce_3(std::string * nonterm, std::string * type, __attribute__((unused)) solar::grammar_t * grammar) {
+ grammar->nonterm_types.insert(std::make_pair(*nonterm, *type));
+
+ delete nonterm;
+ delete type;
+}
+
+static inline void parse_reduce_4(solar::symbol_t * term, std::string * type, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) {
+ grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name)));
+
+ delete term;
+ delete type;
+ delete name;
+}
+
+static inline void parse_reduce_5(std::string * block, __attribute__((unused)) solar::grammar_t * grammar) {
+ grammar->source_block = *block;
+ delete block;
+}
+
+static inline void parse_reduce_6(std::string * block, __attribute__((unused)) solar::grammar_t * grammar) {
+ grammar->header_block = *block;
+ delete block;
+}
+
+static inline void parse_reduce_7(std::string * type, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) {
+ grammar->extra_args.push_back(std::make_pair(*type, *name));
+
+ delete type;
+ delete name;
+}
+
+static inline solar::rule_t * parse_reduce_8(std::string * lhs, std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, std::string * action, __attribute__((unused)) solar::grammar_t * grammar) {
+ auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action};
+
+ delete lhs;
+ delete rhs;
+ delete action;
+
+ return ret;
+}
+
+static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_9(__attribute__((unused)) solar::grammar_t * grammar) {
+ return new std::pair<std::vector<solar::symbol_t>, std::vector<std::string>>();
+}
+
+static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_10(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, __attribute__((unused)) solar::grammar_t * grammar) {
+ rhs->first.push_back(*sym);
+ rhs->second.emplace_back();
+ delete sym;
+
+ return rhs;
+}
+
+static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_11(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, std::string * var, __attribute__((unused)) solar::grammar_t * grammar) {
+ rhs->first.push_back(*sym);
+ rhs->second.push_back(*var);
+
+ delete sym;
+ delete var;
+
+ return rhs;
+}
+
+static inline std::string * parse_reduce_12(__attribute__((unused)) solar::grammar_t * grammar) {
+ return new std::string;
+}
+
+static inline std::string * parse_reduce_13(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return v;
+}
+
+static inline solar::symbol_t * parse_reduce_14(solar::symbol_t * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return v;
+}
+
+static inline solar::symbol_t * parse_reduce_15(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_nonterm(*v));
+ delete v;
+ return ret;
+}
+
+static inline solar::symbol_t * parse_reduce_16(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_term(*v));
+ delete v;
+ return ret;
+}
+
+static inline solar::symbol_t * parse_reduce_17(char v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return new solar::symbol_t(solar::symbol_t::make_char(v));
+}
+
+static inline std::string * parse_reduce_18(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return v;
+}
+
+static inline std::string * parse_reduce_19(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return v;
+}
+
+static inline std::string * parse_reduce_20(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) {
+ return v;
+}
+
+int parse_push(parse_context_t *parser, int token, const parse_token_value_t *value, __attribute__((unused)) solar::grammar_t * grammar) {
+ while (1) {
+ switch (parser->stack[parser->top].state) {
+ case 0:
+ switch (token) {
+ case 0:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 1:
+ switch (token) {
+ case 0:
+ return 0;
+
+ case TOK_EXTRA_ARG:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 3;
+ return 1;
+
+ case TOK_HEADER:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 4;
+ return 1;
+
+ case TOK_SOURCE:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 5;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 6;
+ return 1;
+
+ case TOK_TYPE:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 7;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 2:
+ switch (token) {
+ case 0:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 2;
+ parse_reduce_2(parser->stack[parser->top + 1].value.symbol_rule, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 3:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 8;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 4:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 9;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 5:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 10;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 6:
+ switch (token) {
+ case '|':
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 11;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 7:
+ switch (token) {
+ case TOK_CHAR:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 13;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 14;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 15;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 8:
+ switch (token) {
+ case TOK_SYMBOL:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 17;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 18;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 19;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 9:
+ switch (token) {
+ case 0:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 3;
+ parse_reduce_6(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 10:
+ switch (token) {
+ case 0:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 3;
+ parse_reduce_5(parser->stack[parser->top + 2].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 11:
+ switch (token) {
+ case '=':
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 20;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 12:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 21;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 13:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case '(':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case ';':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_17(parser->stack[parser->top + 0].value.token.c, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 14:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 22;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 15:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case '(':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ case ';':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_term = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 7:
+ parser->stack[++parser->top].state = 12;
+ break;
+ case 23:
+ parser->stack[++parser->top].state = 27;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 16:
+ switch (token) {
+ case 0:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 4;
+ parse_reduce_7(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 17:
+ switch (token) {
+ case 0:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case ')':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 18:
+ switch (token) {
+ case 0:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case ')':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 19:
+ switch (token) {
+ case 0:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ case ')':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_varname = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar);
+ switch (parser->stack[parser->top].state) {
+ case 8:
+ parser->stack[++parser->top].state = 16;
+ break;
+ case 21:
+ parser->stack[++parser->top].state = 24;
+ break;
+ case 31:
+ parser->stack[++parser->top].state = 32;
+ break;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 20:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_9(grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_CHAR:
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_9(grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_9(grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_9(grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case ';':
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_9(grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 21:
+ switch (token) {
+ case TOK_SYMBOL:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 17;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 18;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 19;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 22:
+ switch (token) {
+ case 0:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 4;
+ parse_reduce_3(parser->stack[parser->top + 2].value.token.str, parser->stack[parser->top + 3].value.token.str, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 23:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 28;
+ return 1;
+
+ case TOK_CHAR:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 13;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 29;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 15;
+ return 1;
+
+ case ';':
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 30;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 24:
+ switch (token) {
+ case 0:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 5;
+ parse_reduce_4(parser->stack[parser->top + 2].value.symbol_term, parser->stack[parser->top + 3].value.token.str, parser->stack[parser->top + 4].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 1;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 25:
+ switch (token) {
+ case 0:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rule = parse_reduce_8(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar);
+ parser->stack[++parser->top].state = 2;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 26:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 2;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 2;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 2;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 2;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case '(':
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 31;
+ return 1;
+
+ case ';':
+ parser->top -= 2;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 27:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case '(':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case ';':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_term, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 28:
+ switch (token) {
+ case 0:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_13(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 29:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case '(':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ case ';':
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_symbol = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar);
+ parser->stack[++parser->top].state = 26;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 30:
+ switch (token) {
+ case 0:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_EXTRA_ARG:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_HEADER:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_SOURCE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ case TOK_TYPE:
+ parser->top -= 1;
+ parser->stack[parser->top].value.symbol_action = parse_reduce_12(grammar);
+ parser->stack[++parser->top].state = 25;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 31:
+ switch (token) {
+ case TOK_SYMBOL:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 17;
+ return 1;
+
+ case TOK_SYMBOL_LC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 18;
+ return 1;
+
+ case TOK_SYMBOL_UC:
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 19;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 32:
+ switch (token) {
+ case ')':
+ parser->stack[parser->top].value.token = *value;
+ parser->stack[++parser->top].state = 33;
+ return 1;
+
+ default:
+ return -1;
+ }
+ break;
+
+ case 33:
+ switch (token) {
+ case TOK_BLOCK:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_CHAR:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_LC:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case TOK_SYMBOL_UC:
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ case ';':
+ parser->top -= 5;
+ parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar);
+ parser->stack[++parser->top].state = 23;
+ break;
+
+ default:
+ return -1;
+ }
+ break;
+
+ }
+ }
+}
diff --git a/src/parse.hpp b/src/parse.hpp
new file mode 100644
index 0000000..567a38c
--- /dev/null
+++ b/src/parse.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+
+#include "grammar.hpp"
+
+enum parse_token_t {
+ TOK_BLOCK = 256,
+ TOK_CHAR = 257,
+ TOK_EXTRA_ARG = 258,
+ TOK_HEADER = 259,
+ TOK_SOURCE = 260,
+ TOK_SYMBOL = 261,
+ TOK_SYMBOL_LC = 262,
+ TOK_SYMBOL_UC = 263,
+ TOK_TYPE = 264,
+};
+
+typedef struct parse_token_value {
+ char c;
+ std::string * str;
+} parse_token_value_t;
+
+typedef struct parse_context parse_context_t;
+
+parse_context_t * parse_alloc(void *(*alloc_func)(size_t));
+void parse_free(parse_context_t *parser, void (*free_func)(void *));
+
+int parse_push(parse_context_t *parser, int token, const parse_token_value_t *value, __attribute__((unused)) solar::grammar_t * grammar);
diff --git a/src/parse.y b/src/parse.y
new file mode 100644
index 0000000..46f5ff6
--- /dev/null
+++ b/src/parse.y
@@ -0,0 +1,143 @@
+%type SYMBOL {std::string *} str
+%type SYMBOL_UC {std::string *} str
+%type SYMBOL_LC {std::string *} str
+%type BLOCK {std::string *} str
+%type CHAR {char} c
+
+%type rule {solar::rule_t *}
+%type rhs {std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> *}
+%type action {std::string *}
+%type symbol {solar::symbol_t *}
+%type term {solar::symbol_t *}
+%type varname {std::string *}
+
+
+%header {
+#include "grammar.hpp"
+}
+
+%extra_arg {__attribute__((unused)) solar::grammar_t *} grammar
+
+
+grammar |=;
+
+grammar |= grammar rule(rule) {
+ if (grammar->rules.empty()) {
+ solar::item_t init("");
+ init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str()));
+ grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()});
+ }
+
+ grammar->rules.push_back(*rule);
+ delete rule;
+}
+
+grammar |= grammar TYPE SYMBOL_LC(nonterm) BLOCK(type) {
+ grammar->nonterm_types.insert(std::make_pair(*nonterm, *type));
+
+ delete nonterm;
+ delete type;
+}
+
+grammar |= grammar TYPE term(term) BLOCK(type) varname(name) {
+ grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name)));
+
+ delete term;
+ delete type;
+ delete name;
+}
+
+grammar |= grammar SOURCE BLOCK(block) {
+ grammar->source_block = *block;
+ delete block;
+}
+
+grammar |= grammar HEADER BLOCK(block) {
+ grammar->header_block = *block;
+ delete block;
+}
+
+grammar |= grammar EXTRA_ARG BLOCK(type) varname(name) {
+ grammar->extra_args.push_back(std::make_pair(*type, *name));
+
+ delete type;
+ delete name;
+}
+
+
+rule |= SYMBOL_LC(lhs) '|' '=' rhs(rhs) action(action) {
+ auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action};
+
+ delete lhs;
+ delete rhs;
+ delete action;
+
+ return ret;
+}
+
+
+rhs |= {
+ return new std::pair<std::vector<solar::symbol_t>, std::vector<std::string>>();
+}
+
+rhs |= rhs(rhs) symbol(sym) {
+ rhs->first.push_back(*sym);
+ rhs->second.emplace_back();
+ delete sym;
+
+ return rhs;
+}
+
+rhs |= rhs(rhs) symbol(sym) '(' varname(var) ')' {
+ rhs->first.push_back(*sym);
+ rhs->second.push_back(*var);
+
+ delete sym;
+ delete var;
+
+ return rhs;
+}
+
+
+action |= ';' {
+ return new std::string;
+}
+
+action |= BLOCK(v) {
+ return v;
+}
+
+
+symbol |= term(v) {
+ return v;
+}
+
+symbol |= SYMBOL_LC(v) {
+ solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_nonterm(*v));
+ delete v;
+ return ret;
+}
+
+
+term |= SYMBOL_UC(v) {
+ solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_term(*v));
+ delete v;
+ return ret;
+}
+
+term |= CHAR(v) {
+ return new solar::symbol_t(solar::symbol_t::make_char(v));
+}
+
+
+varname |= SYMBOL_LC(v) {
+ return v;
+}
+
+varname |= SYMBOL_UC(v) {
+ return v;
+}
+
+varname |= SYMBOL(v) {
+ return v;
+}
diff --git a/src/parser.cpp b/src/parser.cpp
deleted file mode 100644
index ce408eb..0000000
--- a/src/parser.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#include "parser.hpp"
-
-#include <cstdlib>
-
-
-namespace solar {
-
-enum parser_state {
- STATE_INIT,
- STATE_RULE_BAR,
- STATE_RULE_EQUAL,
- STATE_RULE,
- STATE_RULE_VAR_PRE,
- STATE_RULE_VAR,
- STATE_RULE_VAR_POST,
- STATE_TYPE,
- STATE_TYPE_NONTERM,
- STATE_TYPE_TERM,
- STATE_TYPE_TERM_BLOCK,
- STATE_HEADER,
- STATE_SOURCE,
- STATE_EXTRA_ARG,
- STATE_EXTRA_ARG_NAME,
-};
-
-struct parser {
- parser_state state;
-};
-
-parser_t * parser_alloc(void) {
- parser_t *parser = (parser_t *)std::malloc(sizeof(parser_t));
- parser->state = STATE_INIT;
-
- return parser;
-}
-
-int parser_push(parser_t *parser, int token, const parser_value_t *value, parser_state_t *state) {
- switch (parser->state) {
- case STATE_INIT:
- switch (token) {
- case TOK_SYMBOL_LC:
- parser->state = STATE_RULE_BAR;
- state->new_rule(*value->str);
- delete value->str;
- return 1;
-
- case TOK_TYPE:
- 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 TOK_EXTRA_ARG:
- parser->state = STATE_EXTRA_ARG;
- return 1;
-
- case 0:
- return 0;
- }
-
- break;
-
- case STATE_RULE_BAR:
- if (token == '|') {
- parser->state = STATE_RULE_EQUAL;
- return 1;
- }
-
- break;
-
- case STATE_RULE_EQUAL:
- if (token == '=') {
- parser->state = STATE_RULE;
- return 1;
- }
-
- break;
-
- case STATE_RULE:
- switch (token) {
- case TOK_SYMBOL_LC:
- state->add_rule_nonterminal(*value->str);
- delete value->str;
- return 1;
-
- case TOK_SYMBOL_UC:
- state->add_rule_terminal(*value->str);
- delete value->str;
- return 1;
-
- case TOK_CHAR:
- state->add_rule_terminal(value->number);
- return 1;
-
- case TOK_BLOCK:
- state->add_rule(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
-
- case '(':
- parser->state = STATE_RULE_VAR_PRE;
- return 1;
-
- case ';':
- state->add_rule();
- parser->state = STATE_INIT;
- return 1;
- }
-
- break;
-
- case STATE_RULE_VAR_PRE:
- switch (token) {
- case TOK_SYMBOL:
- case TOK_SYMBOL_UC:
- case TOK_SYMBOL_LC:
- state->add_rule_var(*value->str);
- delete value->str;
- parser->state = STATE_RULE_VAR;
- return 1;
- }
-
- break;
-
- case STATE_RULE_VAR:
- if (token == ')') {
- parser->state = STATE_RULE;
- return 1;
- }
-
- break;
-
- case STATE_RULE_VAR_POST:
- switch (token) {
- case TOK_SYMBOL_LC:
- state->add_rule_nonterminal(*value->str);
- delete value->str;
- return 1;
-
- case TOK_SYMBOL_UC:
- state->add_rule_terminal(*value->str);
- delete value->str;
- return 1;
-
- case TOK_CHAR:
- state->add_rule_terminal(value->number);
- return 1;
-
- case TOK_BLOCK:
- state->add_rule(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
-
- case ';':
- state->add_rule();
- parser->state = STATE_INIT;
- return 1;
- }
-
- break;
-
- case STATE_TYPE:
- switch (token) {
- case TOK_SYMBOL_LC:
- state->add_type_nonterminal(*value->str);
- delete value->str;
- parser->state = STATE_TYPE_NONTERM;
- return 1;
-
- case TOK_SYMBOL_UC:
- state->add_type_terminal(*value->str);
- delete value->str;
- parser->state = STATE_TYPE_TERM;
- return 1;
- }
-
- break;
-
- case STATE_TYPE_NONTERM:
- if (token == TOK_BLOCK) {
- state->set_type_nonterminal(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
- }
-
- break;
-
- case STATE_TYPE_TERM:
- if (token == TOK_BLOCK) {
- state->set_type_terminal(*value->str);
- delete value->str;
- parser->state = STATE_TYPE_TERM_BLOCK;
- return 1;
- }
-
- break;
-
- case STATE_TYPE_TERM_BLOCK:
- switch (token) {
- case TOK_SYMBOL:
- case TOK_SYMBOL_UC:
- case TOK_SYMBOL_LC:
- state->set_type_terminal_name(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
- }
- break;
-
- case STATE_HEADER:
- if (token == TOK_BLOCK) {
- state->set_header_block(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
- }
-
- break;
-
- case STATE_SOURCE:
- if (token == TOK_BLOCK) {
- state->set_source_block(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
- }
-
- break;
-
- case STATE_EXTRA_ARG:
- if (token == TOK_BLOCK) {
- state->add_extra_arg(*value->str);
- delete value->str;
- parser->state = STATE_EXTRA_ARG_NAME;
- return 1;
- }
- break;
-
- case STATE_EXTRA_ARG_NAME:
- switch (token) {
- case TOK_SYMBOL:
- case TOK_SYMBOL_UC:
- case TOK_SYMBOL_LC:
- state->set_extra_arg_name(*value->str);
- delete value->str;
- parser->state = STATE_INIT;
- return 1;
- }
- }
-
- switch (token) {
- case TOK_SYMBOL:
- case TOK_SYMBOL_UC:
- case TOK_SYMBOL_LC:
- case TOK_CHAR:
- case TOK_BLOCK:
- delete value->str;;
- }
-
- return -1;
-}
-
-void parser_free(parser_t *parser) {
- std::free(parser);
-}
-
-}
diff --git a/src/parser.hpp b/src/parser.hpp
deleted file mode 100644
index cc139fa..0000000
--- a/src/parser.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#pragma once
-
-#include "parser_state.hpp"
-
-#include <cstdint>
-
-
-namespace solar {
-
-enum parser_token_t {
- TOK_SYMBOL = 256,
- TOK_SYMBOL_UC,
- TOK_SYMBOL_LC,
- TOK_BLOCK,
- TOK_CHAR,
- TOK_TYPE,
- TOK_SOURCE,
- TOK_HEADER,
- TOK_EXTRA_ARG,
-};
-
-typedef struct parser_value {
- std::string *str;
- uint64_t number;
- const char *error;
-} parser_value_t;
-
-
-typedef struct parser parser_t;
-
-
-parser_t * parser_alloc(void);
-int parser_push(parser_t *parser, int token, const parser_value_t *value, parser_state_t *state);
-void parser_free(parser_t *parser);
-
-}
diff --git a/src/parser_state.cpp b/src/parser_state.cpp
deleted file mode 100644
index 7ecffd9..0000000
--- a/src/parser_state.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#include "parser_state.hpp"
-
-
-namespace solar {
-
-void parser_state_t::new_rule(const std::string &nonterm) {
- if (grammar.rules.empty()) {
- // start rule
- add_rule_nonterminal(nonterm);
- add_rule();
- }
-
- current = item_t(nonterm);
- current_vars = std::vector<std::string>();
-}
-
-void parser_state_t::add_rule_nonterminal(const std::string &nonterm) {
- current.get_rhs().emplace_back(symbol_t::make_nonterm(nonterm));
- current_vars.emplace_back();
-}
-
-void parser_state_t::add_rule_terminal(const std::string &term) {
- current.get_rhs().emplace_back(symbol_t::make_term(term));
- current_vars.emplace_back();
-}
-
-void parser_state_t::add_rule_terminal(unsigned char term) {
- current.get_rhs().emplace_back(symbol_t::make_char(term));
- current_vars.emplace_back();
-}
-
-void parser_state_t::add_rule(const std::string &action) {
- grammar.rules.emplace_back(rule_t{std::move(current), std::move(current_vars), action});
-}
-
-void parser_state_t::add_rule_var(const std::string &var) {
- current_vars.back() = var;
-}
-
-void parser_state_t::add_type_nonterminal(const std::string &nonterm) {
- current_var = nonterm;
-}
-
-void parser_state_t::add_type_terminal(const std::string &term) {
- current_var = term;
-}
-
-void parser_state_t::set_type_nonterminal(const std::string &type) {
- grammar.nonterm_types.insert(std::make_pair(current_var, type));
-}
-
-void parser_state_t::set_type_terminal(const std::string &type) {
- current_type = type;
-}
-
-void parser_state_t::set_type_terminal_name(const std::string &name) {
- grammar.term_types.insert(std::make_pair(symbol_t::make_term(current_var.c_str()), std::make_pair(current_type, name)));
-}
-
-}
diff --git a/src/parser_state.hpp b/src/parser_state.hpp
deleted file mode 100644
index c1bbdda..0000000
--- a/src/parser_state.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Copyright (c) 2015, Matthias Schiffer <mschiffer@universe-factory.net>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#pragma once
-
-#include "grammar.hpp"
-
-
-namespace solar {
-
-class parser_state_t {
-private:
- grammar_t grammar;
-
- item_t current;
- std::vector<std::string> current_vars;
- std::string current_var;
- std::string current_type;
-
- std::string current_extra_arg;
-
-public:
- parser_state_t() : current("") {}
-
- const grammar_t & get_grammar() const {
- return grammar;
- }
-
- void set_header_block(const std::string &value) {
- grammar.header_block = value;
- }
-
- void set_source_block(const std::string &value) {
- grammar.source_block = value;
- }
-
- void add_extra_arg(const std::string &type) {
- current_extra_arg = type;
- }
-
- void set_extra_arg_name(const std::string &name) {
- grammar.extra_args.emplace_back(current_extra_arg, name);
- }
-
-
- void new_rule(const std::string &nonterm);
- void add_rule_nonterminal(const std::string &nonterm);
- void add_rule_terminal(const std::string &term);
- void add_rule_terminal(unsigned char term);
- void add_rule(const std::string &action = "");
- void add_rule_var(const std::string &var);
-
- void add_type_nonterminal(const std::string &nonterm);
- void add_type_terminal(const std::string &term);
- void set_type_nonterminal(const std::string &type);
- void set_type_terminal(const std::string &type);
- void set_type_terminal_name(const std::string &name);
-};
-
-}
diff --git a/src/solar.cpp b/src/solar.cpp
index e7eb00b..c0491aa 100644
--- a/src/solar.cpp
+++ b/src/solar.cpp
@@ -25,18 +25,19 @@
#include "lex.hpp"
-#include "parser.hpp"
+#include "parse.hpp"
#include "generator_slr.hpp"
#include "output_slr.hpp"
-
#include <cstdio>
+#include <cstdlib>
+#include <iostream>
#include <memory>
namespace solar {
-bool read_grammar(const char *filename, parser_state_t *state) {
+bool read_grammar(const char *filename, grammar_t *grammar) {
FILE *file = fopen(filename, "r");
if (!file) {
std::fprintf(stderr, "unable to open file %s\n", filename);
@@ -44,21 +45,21 @@ bool read_grammar(const char *filename, parser_state_t *state) {
}
std::unique_ptr<lex_t> lexer(new lex_t(file));
- parser_t *parser = parser_alloc();
+ parse_context_t *parser = parse_alloc(std::malloc);
int ret;
do {
int token;
- parser_value_t value;
+ parse_token_value_t value;
token = lexer->lex(&value);
if (token < 0) {
- std::fprintf(stderr, "error: %s at %s:%i:%i\n", value.error, filename,
+ std::fprintf(stderr, "error at %s:%i:%i\n", filename,
lexer->get_location().first_line, lexer->get_location().first_column);
return false;
}
- ret = parser_push(parser, token, &value, state);
+ ret = parse_push(parser, token, &value, grammar);
} while (ret > 0);
if (ret < 0) {
@@ -67,7 +68,7 @@ bool read_grammar(const char *filename, parser_state_t *state) {
return false;
}
- parser_free(parser);
+ parse_free(parser, std::free);
return true;
}
@@ -83,11 +84,11 @@ int main(int argc, char *argv[]) {
return 1;
}
- parser_state_t state;
- if (!read_grammar(argv[1], &state))
+ grammar_t grammar;
+ if (!read_grammar(argv[1], &grammar))
return 1;
- generator_slr_t generator(state.get_grammar());
+ generator_slr_t generator(grammar);
output_slr_t output(&generator, argv[3], argv[2]);
output.write();