diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-18 00:02:05 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-18 00:02:05 +0200 |
commit | 6597de68e459eb5f6f02d2b0662637b04d2baea1 (patch) | |
tree | a4cad1dd601d6bcbe9ae157741373315d67d3439 | |
parent | a2a663dafd53cbebfa510f6dbd19aed6cc545e32 (diff) | |
download | solar-6597de68e459eb5f6f02d2b0662637b04d2baea1.tar solar-6597de68e459eb5f6f02d2b0662637b04d2baea1.zip |
Add support for C++ namespaces
-rw-r--r-- | src/grammar.hpp | 1 | ||||
-rw-r--r-- | src/output_header.cpp | 14 | ||||
-rw-r--r-- | src/output_source.cpp | 14 | ||||
-rw-r--r-- | src/parse.cpp | 679 | ||||
-rw-r--r-- | src/parse.hpp | 6 | ||||
-rw-r--r-- | src/parse.y | 38 |
6 files changed, 505 insertions, 247 deletions
diff --git a/src/grammar.hpp b/src/grammar.hpp index cc982b6..6e766c7 100644 --- a/src/grammar.hpp +++ b/src/grammar.hpp @@ -43,6 +43,7 @@ struct grammar_t { std::string header_block; std::string source_block; + std::vector<std::string> ns; std::vector<std::pair<std::string, std::string>> extra_args; diff --git a/src/output_header.cpp b/src/output_header.cpp index c947d9c..e403cfc 100644 --- a/src/output_header.cpp +++ b/src/output_header.cpp @@ -67,6 +67,13 @@ void output_header_t::write() { write_line(); } + if (!get_generator()->get_grammar().ns.empty()) { + for (const std::string &ns : get_generator()->get_grammar().ns) + write_line("namespace ", ns, " {"); + + write_line(); + } + emit_tokens(); write_line(); @@ -80,6 +87,13 @@ void output_header_t::write() { write_line_(sig_free()); write_line(); write_line_(sig_push()); + + if (!get_generator()->get_grammar().ns.empty()) { + write_line(); + + for (size_t i = 0; i < get_generator()->get_grammar().ns.size(); i++) + write_line("}"); + } } }; diff --git a/src/output_source.cpp b/src/output_source.cpp index 7000ef9..576ecbc 100644 --- a/src/output_source.cpp +++ b/src/output_source.cpp @@ -213,6 +213,13 @@ void output_source_t::write() { write_line(); } + if (!get_generator()->get_grammar().ns.empty()) { + for (const std::string &ns : get_generator()->get_grammar().ns) + write_line("namespace ", ns, " {"); + + write_line(); + } + emit_types(); write_line(); @@ -229,6 +236,13 @@ void output_source_t::write() { write_line(); emit_push(); + + if (!get_generator()->get_grammar().ns.empty()) { + write_line(); + + for (size_t i = 0; i < get_generator()->get_grammar().ns.size(); i++) + write_line("}"); + } } } diff --git a/src/parse.cpp b/src/parse.cpp index 3afda25..ad1f687 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -1,16 +1,23 @@ #include "parse.hpp" +namespace solar { + typedef std::vector<std::pair<std::string, bool>> vars_t; typedef std::pair<std::vector<solar::symbol_t>, vars_t> rhs_t; +} + + +namespace solar { typedef union parse_symbol_value { parse_token_value_t token; std::string *symbol_action; + std::vector<std::string> *symbol_namespace; rhs_t *symbol_rhs; - solar::symbol_t *symbol_symbol; - solar::symbol_t *symbol_term; + symbol_t *symbol_symbol; + symbol_t *symbol_term; std::string *symbol_varname; } parse_symbol_value_t; @@ -37,94 +44,105 @@ void parse_free(parse_context_t *parser, void (*free_func)(void *)) { } -static inline void parse_reduce_3(std::string *nonterm, std::string *type, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_3(std::string *nonterm, std::string *type, __attribute__((unused)) grammar_t *grammar) { grammar->nonterm_types.insert(std::make_pair(*nonterm, *type)); } -static inline void parse_reduce_4(solar::symbol_t *term, std::string *type, std::string *name, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_4(symbol_t *term, std::string *type, std::string *name, __attribute__((unused)) grammar_t *grammar) { grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name))); } -static inline void parse_reduce_5(solar::symbol_t *sym, std::string *name, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_5(symbol_t *sym, std::string *name, __attribute__((unused)) grammar_t *grammar) { grammar->destructors.insert(std::make_pair(*sym, *name)); } -static inline void parse_reduce_6(std::string *block, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_6(std::vector<std::string> *ns, __attribute__((unused)) grammar_t *grammar) { + grammar->ns = *ns; +} + +static inline void parse_reduce_7(std::string *block, __attribute__((unused)) grammar_t *grammar) { grammar->source_block = *block; } -static inline void parse_reduce_7(std::string *block, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_8(std::string *block, __attribute__((unused)) grammar_t *grammar) { grammar->header_block = *block; } -static inline void parse_reduce_8(std::string *type, std::string *name, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_9(std::string *type, std::string *name, __attribute__((unused)) grammar_t *grammar) { grammar->extra_args.push_back(std::make_pair(*type, *name)); } -static inline void parse_reduce_9(std::string *lhs, rhs_t *rhs, std::string *action, __attribute__((unused)) solar::grammar_t *grammar) { - grammar->add_rule({solar::item_t(*lhs, rhs->first), rhs->second, *action}); +static inline void parse_reduce_10(std::string *lhs, rhs_t *rhs, std::string *action, __attribute__((unused)) grammar_t *grammar) { + grammar->add_rule({item_t(*lhs, rhs->first), rhs->second, *action}); } -static inline void parse_reduce_10(std::string *lhs, unsigned char c1, unsigned char c2, __attribute__((unused)) solar::grammar_t *grammar) { +static inline void parse_reduce_11(std::string *lhs, unsigned char c1, unsigned char c2, __attribute__((unused)) grammar_t *grammar) { vars_t vars; vars.emplace_back(); for (unsigned int c = c1; c <= c2; c++) - grammar->add_rule({solar::item_t(*lhs, {solar::symbol_t::make_char(c)}), vars, std::string()}); + grammar->add_rule({item_t(*lhs, {symbol_t::make_char(c)}), vars, std::string()}); } -static inline rhs_t * parse_reduce_11(__attribute__((unused)) solar::grammar_t *grammar) {return new rhs_t();} +static inline rhs_t * parse_reduce_12(__attribute__((unused)) grammar_t *grammar) {return new rhs_t();} -static inline rhs_t * parse_reduce_12(rhs_t *rhs, solar::symbol_t *sym, __attribute__((unused)) solar::grammar_t *grammar) { +static inline rhs_t * parse_reduce_13(rhs_t *rhs, symbol_t *sym, __attribute__((unused)) grammar_t *grammar) { rhs->first.push_back(*sym); rhs->second.emplace_back(); return rhs; } -static inline rhs_t * parse_reduce_13(rhs_t *rhs, solar::symbol_t *sym, std::string *var, __attribute__((unused)) solar::grammar_t *grammar) { +static inline rhs_t * parse_reduce_14(rhs_t *rhs, symbol_t *sym, std::string *var, __attribute__((unused)) grammar_t *grammar) { rhs->first.push_back(*sym); rhs->second.emplace_back(*var, true); return rhs; } -static inline rhs_t * parse_reduce_14(rhs_t *rhs, solar::symbol_t *sym, std::string *var, __attribute__((unused)) solar::grammar_t *grammar) { +static inline rhs_t * parse_reduce_15(rhs_t *rhs, symbol_t *sym, std::string *var, __attribute__((unused)) grammar_t *grammar) { rhs->first.push_back(*sym); rhs->second.emplace_back(*var, false); return rhs; } -static inline rhs_t * parse_reduce_15(rhs_t *rhs, std::string *str, __attribute__((unused)) solar::grammar_t *grammar) { +static inline rhs_t * parse_reduce_16(rhs_t *rhs, std::string *str, __attribute__((unused)) grammar_t *grammar) { for (char c : *str) { - rhs->first.push_back(solar::symbol_t::make_char(c)); + rhs->first.push_back(symbol_t::make_char(c)); rhs->second.emplace_back(); } return rhs; } -static inline std::string * parse_reduce_16(__attribute__((unused)) solar::grammar_t *grammar) {return new std::string;} +static inline std::string * parse_reduce_17(__attribute__((unused)) grammar_t *grammar) {return new std::string;} + +static inline std::string * parse_reduce_18(std::string *v, __attribute__((unused)) grammar_t *grammar) {return v;} -static inline std::string * parse_reduce_17(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return v;} +static inline std::string * parse_reduce_19(std::string *v, __attribute__((unused)) grammar_t *grammar) {return new std::string("return " + *v + ";");} -static inline std::string * parse_reduce_18(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return new std::string("return " + *v + ";");} +static inline std::vector<std::string> * parse_reduce_20(std::string *v, __attribute__((unused)) grammar_t *grammar) {return new std::vector<std::string> {*v};} -static inline solar::symbol_t * parse_reduce_19(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return new solar::symbol_t(solar::symbol_t::make_nonterm(*v));} +static inline std::vector<std::string> * parse_reduce_21(std::vector<std::string> *ns, std::string *v, __attribute__((unused)) grammar_t *grammar) { + ns->push_back(*v); + return ns; +} + +static inline symbol_t * parse_reduce_22(std::string *v, __attribute__((unused)) grammar_t *grammar) {return new symbol_t(symbol_t::make_nonterm(*v));} -static inline solar::symbol_t * parse_reduce_20(solar::symbol_t *v, __attribute__((unused)) solar::grammar_t *grammar) {return v;} +static inline symbol_t * parse_reduce_23(symbol_t *v, __attribute__((unused)) grammar_t *grammar) {return v;} -static inline solar::symbol_t * parse_reduce_21(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return new solar::symbol_t(solar::symbol_t::make_term(*v));} +static inline symbol_t * parse_reduce_24(std::string *v, __attribute__((unused)) grammar_t *grammar) {return new symbol_t(symbol_t::make_term(*v));} -static inline solar::symbol_t * parse_reduce_22(unsigned char v, __attribute__((unused)) solar::grammar_t *grammar) {return new solar::symbol_t(solar::symbol_t::make_char(v));} +static inline symbol_t * parse_reduce_25(unsigned char v, __attribute__((unused)) grammar_t *grammar) {return new symbol_t(symbol_t::make_char(v));} -static inline std::string * parse_reduce_23(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return v;} +static inline std::string * parse_reduce_26(std::string *v, __attribute__((unused)) grammar_t *grammar) {return v;} -static inline std::string * parse_reduce_24(std::string *v, __attribute__((unused)) solar::grammar_t *grammar) {return v;} +static inline std::string * parse_reduce_27(std::string *v, __attribute__((unused)) grammar_t *grammar) {return v;} -static int parse_do_push(parse_context_t *parser, int token, __attribute__((unused)) solar::grammar_t *grammar) { +static int parse_do_push(parse_context_t *parser, int token, __attribute__((unused)) grammar_t *grammar) { parse_symbol_value_t result; while (1) { @@ -187,14 +205,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus parser->stack[++parser->top].state = 8; return 1; - case 's': + case 'n': parser->stack[++parser->top].state = 9; return 1; - case 't': + case 's': parser->stack[++parser->top].state = 10; return 1; + case 't': + parser->stack[++parser->top].state = 11; + return 1; + default: return -1; } @@ -203,7 +225,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 5: switch (token) { case '=': - parser->stack[++parser->top].state = 11; + parser->stack[++parser->top].state = 12; return 1; default: @@ -214,7 +236,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 6: switch (token) { case 'e': - parser->stack[++parser->top].state = 12; + parser->stack[++parser->top].state = 13; return 1; default: @@ -225,7 +247,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 7: switch (token) { case 'x': - parser->stack[++parser->top].state = 13; + parser->stack[++parser->top].state = 14; return 1; default: @@ -236,7 +258,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 8: switch (token) { case 'e': - parser->stack[++parser->top].state = 14; + parser->stack[++parser->top].state = 15; return 1; default: @@ -246,8 +268,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 9: switch (token) { - case 'o': - parser->stack[++parser->top].state = 15; + case 'a': + parser->stack[++parser->top].state = 16; return 1; default: @@ -257,8 +279,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 10: switch (token) { - case 'y': - parser->stack[++parser->top].state = 16; + case 'o': + parser->stack[++parser->top].state = 17; return 1; default: @@ -268,21 +290,32 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 11: switch (token) { - case '(': + case 'y': parser->stack[++parser->top].state = 18; return 1; default: - result.symbol_rhs = parse_reduce_11(grammar); - parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; - parser->stack[++parser->top].state = 17; + return -1; } break; case 12: switch (token) { - case 's': + case '(': + parser->stack[++parser->top].state = 20; + return 1; + + default: + result.symbol_rhs = parse_reduce_12(grammar); + parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; parser->stack[++parser->top].state = 19; + } + break; + + case 13: + switch (token) { + case 's': + parser->stack[++parser->top].state = 21; return 1; default: @@ -290,10 +323,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 13: + case 14: switch (token) { case 't': - parser->stack[++parser->top].state = 20; + parser->stack[++parser->top].state = 22; return 1; default: @@ -301,10 +334,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 14: + case 15: switch (token) { case 'a': - parser->stack[++parser->top].state = 21; + parser->stack[++parser->top].state = 23; return 1; default: @@ -312,10 +345,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 15: + case 16: + switch (token) { + case 'm': + parser->stack[++parser->top].state = 24; + return 1; + + default: + return -1; + } + break; + + case 17: switch (token) { case 'u': - parser->stack[++parser->top].state = 22; + parser->stack[++parser->top].state = 25; return 1; default: @@ -323,10 +367,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 16: + case 18: switch (token) { case 'p': - parser->stack[++parser->top].state = 23; + parser->stack[++parser->top].state = 26; return 1; default: @@ -334,34 +378,34 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 17: + case 19: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 27; + parser->stack[++parser->top].state = 30; return 1; case TOK_CHAR: - parser->stack[++parser->top].state = 28; + parser->stack[++parser->top].state = 31; return 1; case TOK_SQBLOCK: - parser->stack[++parser->top].state = 29; + parser->stack[++parser->top].state = 32; return 1; case TOK_STRING: - parser->stack[++parser->top].state = 30; + parser->stack[++parser->top].state = 33; return 1; case TOK_SYMBOL: - parser->stack[++parser->top].state = 31; + parser->stack[++parser->top].state = 34; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 32; + parser->stack[++parser->top].state = 35; return 1; case ';': - parser->stack[++parser->top].state = 33; + parser->stack[++parser->top].state = 36; return 1; default: @@ -369,10 +413,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 18: + case 20: switch (token) { case TOK_CHAR: - parser->stack[++parser->top].state = 34; + parser->stack[++parser->top].state = 37; return 1; default: @@ -380,10 +424,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 19: + case 21: switch (token) { case 't': - parser->stack[++parser->top].state = 35; + parser->stack[++parser->top].state = 38; return 1; default: @@ -391,10 +435,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 20: + case 22: switch (token) { case 'r': - parser->stack[++parser->top].state = 36; + parser->stack[++parser->top].state = 39; return 1; default: @@ -402,10 +446,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 21: + case 23: switch (token) { case 'd': - parser->stack[++parser->top].state = 37; + parser->stack[++parser->top].state = 40; return 1; default: @@ -413,10 +457,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 22: + case 24: + switch (token) { + case 'e': + parser->stack[++parser->top].state = 41; + return 1; + + default: + return -1; + } + break; + + case 25: switch (token) { case 'r': - parser->stack[++parser->top].state = 38; + parser->stack[++parser->top].state = 42; return 1; default: @@ -424,10 +479,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 23: + case 26: switch (token) { case 'e': - parser->stack[++parser->top].state = 39; + parser->stack[++parser->top].state = 43; return 1; default: @@ -435,11 +490,11 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 24: + case 27: switch (token) { default: parser->top -= 5; - parse_reduce_9(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); + parse_reduce_10(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); delete(parser->stack[parser->top + 0].value.token.str); delete(parser->stack[parser->top + 3].value.symbol_rhs); delete(parser->stack[parser->top + 4].value.symbol_action); @@ -447,147 +502,147 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 25: + case 28: switch (token) { case '(': - parser->stack[++parser->top].state = 40; + parser->stack[++parser->top].state = 44; return 1; default: parser->top -= 2; - result.symbol_rhs = parse_reduce_12(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar); + result.symbol_rhs = parse_reduce_13(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar); delete(parser->stack[parser->top + 1].value.symbol_symbol); parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; - parser->stack[++parser->top].state = 17; + parser->stack[++parser->top].state = 19; } break; - case 26: + case 29: switch (token) { default: parser->top -= 1; - result.symbol_symbol = parse_reduce_20(parser->stack[parser->top + 0].value.symbol_term, grammar); + result.symbol_symbol = parse_reduce_23(parser->stack[parser->top + 0].value.symbol_term, grammar); parser->stack[parser->top].value.symbol_symbol = result.symbol_symbol; switch (parser->stack[parser->top].state) { - case 17: - parser->stack[++parser->top].state = 25; + case 19: + parser->stack[++parser->top].state = 28; break; - case 75: - parser->stack[++parser->top].state = 77; + case 84: + parser->stack[++parser->top].state = 88; break; } } break; - case 27: + case 30: switch (token) { default: parser->top -= 1; - result.symbol_action = parse_reduce_17(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_action = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar); parser->stack[parser->top].value.symbol_action = result.symbol_action; - parser->stack[++parser->top].state = 24; + parser->stack[++parser->top].state = 27; } break; - case 28: + case 31: switch (token) { default: parser->top -= 1; - result.symbol_term = parse_reduce_22(parser->stack[parser->top + 0].value.token.c, grammar); + result.symbol_term = parse_reduce_25(parser->stack[parser->top + 0].value.token.c, grammar); parser->stack[parser->top].value.symbol_term = result.symbol_term; switch (parser->stack[parser->top].state) { - case 17: - case 75: - parser->stack[++parser->top].state = 26; + case 19: + case 84: + parser->stack[++parser->top].state = 29; break; - case 39: - parser->stack[++parser->top].state = 46; + case 43: + parser->stack[++parser->top].state = 51; break; } } break; - case 29: + case 32: switch (token) { default: parser->top -= 1; - result.symbol_action = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_action = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar); delete(parser->stack[parser->top + 0].value.token.str); parser->stack[parser->top].value.symbol_action = result.symbol_action; - parser->stack[++parser->top].state = 24; + parser->stack[++parser->top].state = 27; } break; - case 30: + case 33: switch (token) { default: parser->top -= 2; - result.symbol_rhs = parse_reduce_15(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.token.str, grammar); + result.symbol_rhs = parse_reduce_16(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.token.str, grammar); delete(parser->stack[parser->top + 1].value.token.str); parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; - parser->stack[++parser->top].state = 17; + parser->stack[++parser->top].state = 19; } break; - case 31: + case 34: switch (token) { default: parser->top -= 1; - result.symbol_symbol = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_symbol = parse_reduce_22(parser->stack[parser->top + 0].value.token.str, grammar); delete(parser->stack[parser->top + 0].value.token.str); parser->stack[parser->top].value.symbol_symbol = result.symbol_symbol; switch (parser->stack[parser->top].state) { - case 17: - parser->stack[++parser->top].state = 25; + case 19: + parser->stack[++parser->top].state = 28; break; - case 75: - parser->stack[++parser->top].state = 77; + case 84: + parser->stack[++parser->top].state = 88; break; } } break; - case 32: + case 35: switch (token) { default: parser->top -= 1; - result.symbol_term = parse_reduce_21(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_term = parse_reduce_24(parser->stack[parser->top + 0].value.token.str, grammar); delete(parser->stack[parser->top + 0].value.token.str); parser->stack[parser->top].value.symbol_term = result.symbol_term; switch (parser->stack[parser->top].state) { - case 17: - case 75: - parser->stack[++parser->top].state = 26; + case 19: + case 84: + parser->stack[++parser->top].state = 29; break; - case 39: - parser->stack[++parser->top].state = 46; + case 43: + parser->stack[++parser->top].state = 51; break; } } break; - case 33: + case 36: switch (token) { default: parser->top -= 1; - result.symbol_action = parse_reduce_16(grammar); + result.symbol_action = parse_reduce_17(grammar); parser->stack[parser->top].value.symbol_action = result.symbol_action; - parser->stack[++parser->top].state = 24; + parser->stack[++parser->top].state = 27; } break; - case 34: + case 37: switch (token) { case '.': - parser->stack[++parser->top].state = 41; + parser->stack[++parser->top].state = 45; return 1; default: @@ -595,10 +650,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 35: + case 38: switch (token) { case 'r': - parser->stack[++parser->top].state = 42; + parser->stack[++parser->top].state = 46; return 1; default: @@ -606,10 +661,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 36: + case 39: switch (token) { case 'a': - parser->stack[++parser->top].state = 43; + parser->stack[++parser->top].state = 47; return 1; default: @@ -617,10 +672,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 37: + case 40: switch (token) { case 'e': - parser->stack[++parser->top].state = 44; + parser->stack[++parser->top].state = 48; return 1; default: @@ -628,10 +683,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 38: + case 41: + switch (token) { + case 's': + parser->stack[++parser->top].state = 49; + return 1; + + default: + return -1; + } + break; + + case 42: switch (token) { case 'c': - parser->stack[++parser->top].state = 45; + parser->stack[++parser->top].state = 50; return 1; default: @@ -639,18 +705,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 39: + case 43: switch (token) { case TOK_CHAR: - parser->stack[++parser->top].state = 28; + parser->stack[++parser->top].state = 31; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 32; + parser->stack[++parser->top].state = 35; return 1; case TOK_SYMBOL: - parser->stack[++parser->top].state = 47; + parser->stack[++parser->top].state = 52; return 1; default: @@ -658,18 +724,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 40: + case 44: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 54; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 55; return 1; case '=': - parser->stack[++parser->top].state = 51; + parser->stack[++parser->top].state = 56; return 1; default: @@ -677,10 +743,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 41: + case 45: switch (token) { case '.': - parser->stack[++parser->top].state = 52; + parser->stack[++parser->top].state = 57; return 1; default: @@ -688,10 +754,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 42: + case 46: switch (token) { case 'u': - parser->stack[++parser->top].state = 53; + parser->stack[++parser->top].state = 58; return 1; default: @@ -699,10 +765,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 43: + case 47: switch (token) { case '_': - parser->stack[++parser->top].state = 54; + parser->stack[++parser->top].state = 59; return 1; default: @@ -710,10 +776,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 44: + case 48: switch (token) { case 'r': - parser->stack[++parser->top].state = 55; + parser->stack[++parser->top].state = 60; return 1; default: @@ -721,10 +787,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 45: + case 49: + switch (token) { + case 'p': + parser->stack[++parser->top].state = 61; + return 1; + + default: + return -1; + } + break; + + case 50: switch (token) { case 'e': - parser->stack[++parser->top].state = 56; + parser->stack[++parser->top].state = 62; return 1; default: @@ -732,10 +809,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 46: + case 51: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 57; + parser->stack[++parser->top].state = 63; return 1; default: @@ -743,10 +820,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 47: + case 52: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 58; + parser->stack[++parser->top].state = 64; return 1; default: @@ -754,10 +831,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 48: + case 53: switch (token) { case ')': - parser->stack[++parser->top].state = 59; + parser->stack[++parser->top].state = 65; return 1; default: @@ -765,76 +842,92 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 49: + case 54: switch (token) { default: parser->top -= 1; - result.symbol_varname = parse_reduce_24(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_varname = parse_reduce_27(parser->stack[parser->top + 0].value.token.str, grammar); parser->stack[parser->top].value.symbol_varname = result.symbol_varname; switch (parser->stack[parser->top].state) { - case 40: - parser->stack[++parser->top].state = 48; + case 44: + parser->stack[++parser->top].state = 53; + break; + + case 56: + parser->stack[++parser->top].state = 66; break; - case 51: - parser->stack[++parser->top].state = 60; + case 63: + parser->stack[++parser->top].state = 73; break; - case 57: - parser->stack[++parser->top].state = 66; + case 82: + parser->stack[++parser->top].state = 87; break; - case 76: - parser->stack[++parser->top].state = 78; + case 85: + parser->stack[++parser->top].state = 89; break; - case 77: - parser->stack[++parser->top].state = 79; + case 88: + parser->stack[++parser->top].state = 91; + break; + + case 92: + parser->stack[++parser->top].state = 93; break; } } break; - case 50: + case 55: switch (token) { default: parser->top -= 1; - result.symbol_varname = parse_reduce_23(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_varname = parse_reduce_26(parser->stack[parser->top + 0].value.token.str, grammar); parser->stack[parser->top].value.symbol_varname = result.symbol_varname; switch (parser->stack[parser->top].state) { - case 40: - parser->stack[++parser->top].state = 48; + case 44: + parser->stack[++parser->top].state = 53; break; - case 51: - parser->stack[++parser->top].state = 60; + case 56: + parser->stack[++parser->top].state = 66; break; - case 57: - parser->stack[++parser->top].state = 66; + case 63: + parser->stack[++parser->top].state = 73; + break; + + case 82: + parser->stack[++parser->top].state = 87; break; - case 76: - parser->stack[++parser->top].state = 78; + case 85: + parser->stack[++parser->top].state = 89; break; - case 77: - parser->stack[++parser->top].state = 79; + case 88: + parser->stack[++parser->top].state = 91; + break; + + case 92: + parser->stack[++parser->top].state = 93; break; } } break; - case 51: + case 56: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 54; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 55; return 1; default: @@ -842,10 +935,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 52: + case 57: switch (token) { case '.': - parser->stack[++parser->top].state = 61; + parser->stack[++parser->top].state = 67; return 1; default: @@ -853,10 +946,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 53: + case 58: switch (token) { case 'c': - parser->stack[++parser->top].state = 62; + parser->stack[++parser->top].state = 68; return 1; default: @@ -864,10 +957,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 54: + case 59: switch (token) { case 'a': - parser->stack[++parser->top].state = 63; + parser->stack[++parser->top].state = 69; return 1; default: @@ -875,10 +968,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 55: + case 60: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 64; + parser->stack[++parser->top].state = 70; return 1; default: @@ -886,10 +979,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 56: + case 61: + switch (token) { + case 'a': + parser->stack[++parser->top].state = 71; + return 1; + + default: + return -1; + } + break; + + case 62: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 65; + parser->stack[++parser->top].state = 72; return 1; default: @@ -897,14 +1001,14 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 57: + case 63: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 54; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 55; return 1; default: @@ -912,7 +1016,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 58: + case 64: switch (token) { default: parser->top -= 7; @@ -923,22 +1027,22 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 59: + case 65: switch (token) { default: parser->top -= 5; - result.symbol_rhs = parse_reduce_13(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); + result.symbol_rhs = parse_reduce_14(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); delete(parser->stack[parser->top + 1].value.symbol_symbol); delete(parser->stack[parser->top + 3].value.symbol_varname); parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; - parser->stack[++parser->top].state = 17; + parser->stack[++parser->top].state = 19; } break; - case 60: + case 66: switch (token) { case ')': - parser->stack[++parser->top].state = 67; + parser->stack[++parser->top].state = 74; return 1; default: @@ -946,10 +1050,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 61: + case 67: switch (token) { case TOK_CHAR: - parser->stack[++parser->top].state = 68; + parser->stack[++parser->top].state = 75; return 1; default: @@ -957,10 +1061,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 62: + case 68: switch (token) { case 't': - parser->stack[++parser->top].state = 69; + parser->stack[++parser->top].state = 76; return 1; default: @@ -968,10 +1072,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 63: + case 69: switch (token) { case 'r': - parser->stack[++parser->top].state = 70; + parser->stack[++parser->top].state = 77; return 1; default: @@ -979,27 +1083,38 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 64: + case 70: switch (token) { default: parser->top -= 8; - parse_reduce_7(parser->stack[parser->top + 7].value.token.str, grammar); + parse_reduce_8(parser->stack[parser->top + 7].value.token.str, grammar); delete(parser->stack[parser->top + 7].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 65: + case 71: + switch (token) { + case 'c': + parser->stack[++parser->top].state = 78; + return 1; + + default: + return -1; + } + break; + + case 72: switch (token) { default: parser->top -= 8; - parse_reduce_6(parser->stack[parser->top + 7].value.token.str, grammar); + parse_reduce_7(parser->stack[parser->top + 7].value.token.str, grammar); delete(parser->stack[parser->top + 7].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 66: + case 73: switch (token) { default: parser->top -= 8; @@ -1011,22 +1126,22 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 67: + case 74: switch (token) { default: parser->top -= 6; - result.symbol_rhs = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 4].value.symbol_varname, grammar); + result.symbol_rhs = parse_reduce_15(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 4].value.symbol_varname, grammar); delete(parser->stack[parser->top + 1].value.symbol_symbol); delete(parser->stack[parser->top + 4].value.symbol_varname); parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; - parser->stack[++parser->top].state = 17; + parser->stack[++parser->top].state = 19; } break; - case 68: + case 75: switch (token) { case ')': - parser->stack[++parser->top].state = 71; + parser->stack[++parser->top].state = 79; return 1; default: @@ -1034,10 +1149,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 69: + case 76: switch (token) { case 'o': - parser->stack[++parser->top].state = 72; + parser->stack[++parser->top].state = 80; return 1; default: @@ -1045,10 +1160,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 70: + case 77: switch (token) { case 'g': - parser->stack[++parser->top].state = 73; + parser->stack[++parser->top].state = 81; return 1; default: @@ -1056,10 +1171,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 71: + case 78: + switch (token) { + case 'e': + parser->stack[++parser->top].state = 82; + return 1; + + default: + return -1; + } + break; + + case 79: switch (token) { case ';': - parser->stack[++parser->top].state = 74; + parser->stack[++parser->top].state = 83; return 1; default: @@ -1067,10 +1193,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 72: + case 80: switch (token) { case 'r': - parser->stack[++parser->top].state = 75; + parser->stack[++parser->top].state = 84; return 1; default: @@ -1078,10 +1204,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 73: + case 81: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 76; + parser->stack[++parser->top].state = 85; return 1; default: @@ -1089,28 +1215,43 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 74: + case 82: + switch (token) { + case TOK_SYMBOL: + parser->stack[++parser->top].state = 54; + return 1; + + case TOK_SYMBOL_UC: + parser->stack[++parser->top].state = 55; + return 1; + + default: + return -1; + } + break; + + case 83: switch (token) { default: parser->top -= 11; - parse_reduce_10(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 4].value.token.c, parser->stack[parser->top + 8].value.token.c, grammar); + parse_reduce_11(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 4].value.token.c, parser->stack[parser->top + 8].value.token.c, grammar); delete(parser->stack[parser->top + 0].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 75: + case 84: switch (token) { case TOK_CHAR: - parser->stack[++parser->top].state = 28; + parser->stack[++parser->top].state = 31; return 1; case TOK_SYMBOL: - parser->stack[++parser->top].state = 31; + parser->stack[++parser->top].state = 34; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 32; + parser->stack[++parser->top].state = 35; return 1; default: @@ -1118,14 +1259,14 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 76: + case 85: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 54; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 55; return 1; default: @@ -1133,14 +1274,39 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 77: + case 86: + switch (token) { + case ':': + parser->stack[++parser->top].state = 90; + return 1; + + default: + parser->top -= 11; + parse_reduce_6(parser->stack[parser->top + 10].value.symbol_namespace, grammar); + delete(parser->stack[parser->top + 10].value.symbol_namespace); + parser->stack[++parser->top].state = 2; + } + break; + + case 87: + switch (token) { + default: + parser->top -= 1; + result.symbol_namespace = parse_reduce_20(parser->stack[parser->top + 0].value.symbol_varname, grammar); + delete(parser->stack[parser->top + 0].value.symbol_varname); + parser->stack[parser->top].value.symbol_namespace = result.symbol_namespace; + parser->stack[++parser->top].state = 86; + } + break; + + case 88: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 54; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 55; return 1; default: @@ -1148,18 +1314,29 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 78: + case 89: switch (token) { default: parser->top -= 12; - parse_reduce_8(parser->stack[parser->top + 10].value.token.str, parser->stack[parser->top + 11].value.symbol_varname, grammar); + parse_reduce_9(parser->stack[parser->top + 10].value.token.str, parser->stack[parser->top + 11].value.symbol_varname, grammar); delete(parser->stack[parser->top + 10].value.token.str); delete(parser->stack[parser->top + 11].value.symbol_varname); parser->stack[++parser->top].state = 2; } break; - case 79: + case 90: + switch (token) { + case ':': + parser->stack[++parser->top].state = 92; + return 1; + + default: + return -1; + } + break; + + case 91: switch (token) { default: parser->top -= 13; @@ -1170,11 +1347,37 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; + case 92: + switch (token) { + case TOK_SYMBOL: + parser->stack[++parser->top].state = 54; + return 1; + + case TOK_SYMBOL_UC: + parser->stack[++parser->top].state = 55; + return 1; + + default: + return -1; + } + break; + + case 93: + switch (token) { + default: + parser->top -= 4; + result.symbol_namespace = parse_reduce_21(parser->stack[parser->top + 0].value.symbol_namespace, parser->stack[parser->top + 3].value.symbol_varname, grammar); + delete(parser->stack[parser->top + 3].value.symbol_varname); + parser->stack[parser->top].value.symbol_namespace = result.symbol_namespace; + parser->stack[++parser->top].state = 86; + } + break; + } } } -int parse_push(parse_context_t *parser, int token, const parse_token_value_t *value, __attribute__((unused)) solar::grammar_t *grammar) { +int parse_push(parse_context_t *parser, int token, const parse_token_value_t *value, __attribute__((unused)) grammar_t *grammar) { int ret = parse_do_push(parser, token, grammar); if (ret > 0) @@ -1182,3 +1385,5 @@ int parse_push(parse_context_t *parser, int token, const parse_token_value_t *va return ret; } + +} diff --git a/src/parse.hpp b/src/parse.hpp index c9fa9ce..5b027cf 100644 --- a/src/parse.hpp +++ b/src/parse.hpp @@ -4,6 +4,8 @@ #include "grammar.hpp" +namespace solar { + typedef enum parse_token { TOK_BLOCK = 256, TOK_CHAR = 257, @@ -23,4 +25,6 @@ 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); +int parse_push(parse_context_t *parser, int token, const parse_token_value_t *value, __attribute__((unused)) grammar_t *grammar); + +} diff --git a/src/parse.y b/src/parse.y index 7b46368..0d9bb05 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,10 +1,16 @@ +%namespace solar + %header { #include "grammar.hpp" } %source { +namespace solar { + typedef std::vector<std::pair<std::string, bool>> vars_t; typedef std::pair<std::vector<solar::symbol_t>, vars_t> rhs_t; + +} } @@ -26,23 +32,26 @@ typedef std::pair<std::vector<solar::symbol_t>, vars_t> rhs_t; %type CHAR {unsigned char} c +%type namespace {std::vector<std::string> *} +%destructor namespace delete + %type rhs {rhs_t *} %destructor rhs delete %type action {std::string *} %destructor action delete -%type symbol {solar::symbol_t *} +%type symbol {symbol_t *} %destructor symbol delete -%type term {solar::symbol_t *} +%type term {symbol_t *} %destructor term delete %type varname {std::string *} %destructor varname delete -%extra_arg {__attribute__((unused)) solar::grammar_t *} grammar +%extra_arg {__attribute__((unused)) grammar_t *} grammar grammar |=; @@ -61,6 +70,10 @@ directive |= "%destructor" symbol(sym) varname(name) { grammar->destructors.insert(std::make_pair(*sym, *name)); } +directive |= "%namespace" namespace(ns) { + grammar->ns = *ns; +} + directive |= "%source" BLOCK(block) { grammar->source_block = *block; } @@ -74,7 +87,7 @@ directive |= "%extra_arg" BLOCK(type) varname(name) { } directive |= SYMBOL(lhs) "|=" rhs(rhs) action(action) { - grammar->add_rule({solar::item_t(*lhs, rhs->first), rhs->second, *action}); + grammar->add_rule({item_t(*lhs, rhs->first), rhs->second, *action}); } directive |= SYMBOL(lhs) "|=" '(' CHAR(c1) "..." CHAR(c2) ')' ';' { @@ -82,7 +95,7 @@ directive |= SYMBOL(lhs) "|=" '(' CHAR(c1) "..." CHAR(c2) ')' ';' { vars.emplace_back(); for (unsigned int c = c1; c <= c2; c++) - grammar->add_rule({solar::item_t(*lhs, {solar::symbol_t::make_char(c)}), vars, std::string()}); + grammar->add_rule({item_t(*lhs, {symbol_t::make_char(c)}), vars, std::string()}); } @@ -111,7 +124,7 @@ rhs |= rhs(=rhs) symbol(sym) '(' '=' varname(var) ')' { rhs |= rhs(=rhs) STRING(str) { for (char c : *str) { - rhs->first.push_back(solar::symbol_t::make_char(c)); + rhs->first.push_back(symbol_t::make_char(c)); rhs->second.emplace_back(); } @@ -124,11 +137,18 @@ action |= BLOCK(=v) [v] action |= SQBLOCK(v) [new std::string("return " + *v + ";")] -symbol |= SYMBOL(v) [new solar::symbol_t(solar::symbol_t::make_nonterm(*v))] +namespace |= varname(v) [new std::vector<std::string> {*v}] +namespace |= namespace(=ns) "::" varname(v) { + ns->push_back(*v); + return ns; +} + + +symbol |= SYMBOL(v) [new symbol_t(symbol_t::make_nonterm(*v))] symbol |= term(=v) [v] -term |= SYMBOL_UC(v) [new solar::symbol_t(solar::symbol_t::make_term(*v))] -term |= CHAR(v) [new solar::symbol_t(solar::symbol_t::make_char(v))] +term |= SYMBOL_UC(v) [new symbol_t(symbol_t::make_term(*v))] +term |= CHAR(v) [new symbol_t(symbol_t::make_char(v))] varname |= SYMBOL_UC(=v) [v] varname |= SYMBOL(=v) [v] |