%namespace solar %header { #include "grammar.hpp" } %source { namespace solar { typedef std::pair var_t; typedef std::vector vars_t; typedef std::pair, vars_t> rhs_t; } } %extra_arg {__attribute__((unused)) grammar_t *} grammar %type SYMBOL {std::string *} str %destructor SYMBOL delete %type SYMBOL_UC {std::string *} str %destructor SYMBOL_UC delete %type BLOCK {std::string *} str %destructor BLOCK delete %type SQBLOCK {std::string *} str %destructor SQBLOCK delete %type STRING {std::string *} str %destructor STRING delete %type CHAR {unsigned char} c grammar |=; grammar |= grammar directive; directive |= "%type" SYMBOL(nonterm) BLOCK(type) { grammar->nonterm_types.insert({*nonterm, *type}); } directive |= "%type" term(term) BLOCK(type) csymbol(name) { grammar->term_types.insert({*term, {*type, *name}}); } directive |= "%destructor" symbol(sym) csymbol(name) { grammar->destructors.insert({*sym, *name}); } directive |= "%namespace" namespace(ns) { grammar->ns = *ns; } directive |= "%source" BLOCK(block) { grammar->source_block = *block; } directive |= "%header" BLOCK(block) { grammar->header_block = *block; } directive |= "%extra_arg" BLOCK(type) csymbol(name) { grammar->extra_args.emplace_back(*type, *name); } directive |= SYMBOL(lhs) "|=" rhs(rhs) action(action) { grammar->add_rule(item_t(*lhs, rhs->first), rhs->second, *action); } directive |= SYMBOL(lhs) "|=" '(' CHAR(c1) "..." CHAR(c2) ')' action(action) { for (unsigned int c = c1; c <= c2; c++) grammar->add_rule(item_t(*lhs, {symbol_t::make_char(c)}), vars_t(1), *action); } %type rhs {rhs_t *} %destructor rhs delete rhs |= [new rhs_t] rhs |= rhs(=rhs) symbol(sym) variable(var) { rhs->first.push_back(*sym); rhs->second.push_back(*var); return rhs; } rhs |= rhs(=rhs) STRING(str) { for (char c : *str) { rhs->first.push_back(symbol_t::make_char(c)); rhs->second.emplace_back(); } return rhs; } %type variable {var_t *} %destructor variable delete variable |= [new var_t] variable |= '(' consume(consume) csymbol(var) ')' [new var_t(*var, consume)] %type consume {bool} consume |= [false] consume |= '=' [true] %type action {std::string *} %destructor action delete action |= ';' [new std::string] action |= BLOCK(=v) [v] action |= SQBLOCK(v) [new std::string("return " + *v + ";")] %type namespace {std::vector *} %destructor namespace delete namespace |= csymbol(v) [new std::vector {*v}] namespace |= namespace(=ns) "::" csymbol(v) { ns->push_back(*v); return ns; } %type symbol {symbol_t *} %destructor symbol delete symbol |= SYMBOL(v) [new symbol_t(symbol_t::make_nonterm(*v))] symbol |= term(=v) [v] %type term {symbol_t *} %destructor term delete term |= SYMBOL_UC(v) [new symbol_t(symbol_t::make_term(*v))] term |= CHAR(v) [new symbol_t(symbol_t::make_char(v))] %type csymbol {std::string *} %destructor csymbol delete csymbol |= SYMBOL_UC(=v) [v] csymbol |= SYMBOL(=v) [v]