Compare commits
10 commits
59db91599c
...
ba8f9797cb
Author | SHA1 | Date | |
---|---|---|---|
ba8f9797cb | |||
30c2141182 | |||
96d6221449 | |||
3cab65c9f0 | |||
a6cf9b0956 | |||
3818c8c528 | |||
4ed7d5a1b2 | |||
6597de68e4 | |||
a2a663dafd | |||
9cbf364a46 |
14 changed files with 833 additions and 511 deletions
|
@ -72,7 +72,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_arg(const std::string &str, const std::string &name, bool func = false) {
|
void add_arg(const std::string &str, const std::string &name, bool func = false) {
|
||||||
add_arg(std::make_pair(str, name), func);
|
add_arg({str, name}, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
function_t(const std::string &type, const std::string &name) : type_name({type + ' ' + name, name}, true) {}
|
function_t(const std::string &type, const std::string &name) : type_name({type + ' ' + name, name}, true) {}
|
||||||
|
|
|
@ -87,7 +87,7 @@ void generator_t::generate() {
|
||||||
item_t shifted = item;
|
item_t shifted = item;
|
||||||
shifted.shift();
|
shifted.shift();
|
||||||
|
|
||||||
std::set<item_t> &set = new_sets.insert(std::make_pair(sym, empty_set)).first->second;
|
std::set<item_t> &set = new_sets.insert({sym, empty_set}).first->second;
|
||||||
set.insert(std::move(shifted));
|
set.insert(std::move(shifted));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +122,11 @@ generator_t::generator_t(const grammar_t &grammar0) : grammar(grammar0) {
|
||||||
item_t rule = grammar.rules[i].item;
|
item_t rule = grammar.rules[i].item;
|
||||||
|
|
||||||
nonterminals.insert(rule.get_lhs());
|
nonterminals.insert(rule.get_lhs());
|
||||||
nonterms.insert(std::make_pair(rule.get_lhs(), i));
|
nonterms.insert({rule.get_lhs(), i});
|
||||||
|
|
||||||
while (rule.has_next()) {
|
while (rule.has_next()) {
|
||||||
const symbol_t &sym = rule.get_next_symbol();
|
const symbol_t &sym = rule.get_next_symbol();
|
||||||
items.insert(std::make_pair(sym, rule));
|
items.insert({sym, rule});
|
||||||
|
|
||||||
if (sym.get_type() != SYMBOL_TYPE_NONTERM)
|
if (sym.get_type() != SYMBOL_TYPE_NONTERM)
|
||||||
terminals.insert(sym);
|
terminals.insert(sym);
|
||||||
|
@ -134,7 +134,7 @@ generator_t::generator_t(const grammar_t &grammar0) : grammar(grammar0) {
|
||||||
rule.shift();
|
rule.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
rule_ids.insert(std::make_pair(rule, i));
|
rule_ids.insert({rule, i});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,18 +63,18 @@ private:
|
||||||
std::set<item_t> get_set(const std::string &nonterm);
|
std::set<item_t> get_set(const std::string &nonterm);
|
||||||
|
|
||||||
std::pair<std::map<std::set<item_t>, size_t>::iterator, bool> add_set(const std::set<item_t> &set) {
|
std::pair<std::map<std::set<item_t>, size_t>::iterator, bool> add_set(const std::set<item_t> &set) {
|
||||||
return itemsets.insert(std::make_pair(set, itemsets.size()));
|
return itemsets.insert({set, itemsets.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_shift(size_t from, const symbol_t &sym, size_t to) {
|
void add_shift(size_t from, const symbol_t &sym, size_t to) {
|
||||||
if (has_reduce_conflict(from, sym))
|
if (has_reduce_conflict(from, sym))
|
||||||
throw conflict_error("shift/reduce conflict");
|
throw conflict_error("shift/reduce conflict");
|
||||||
|
|
||||||
shifts.insert(std::make_pair(std::make_pair(from, sym), to));
|
shifts.insert({{from, sym}, to});
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_goto(size_t from, const std::string &nonterm, size_t to) {
|
void add_goto(size_t from, const std::string &nonterm, size_t to) {
|
||||||
gotos.insert(std::make_pair(std::make_pair(from, nonterm), to));
|
gotos.insert({{from, nonterm}, to});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -39,11 +39,11 @@ void generator_lr0_t::add_reduction(size_t from, size_t rule) {
|
||||||
throw conflict_error("reduce/reduce conflict");
|
throw conflict_error("reduce/reduce conflict");
|
||||||
|
|
||||||
for (const symbol_t &sym : get_terminals()) {
|
for (const symbol_t &sym : get_terminals()) {
|
||||||
if (get_shifts().count(std::make_pair(from, sym)))
|
if (get_shifts().count({from, sym}))
|
||||||
throw conflict_error("shift/reduce conflict");
|
throw conflict_error("shift/reduce conflict");
|
||||||
}
|
}
|
||||||
|
|
||||||
reductions.insert(std::make_pair(from, rule));
|
reductions.insert({from, rule});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ void generator_slr_t::generate_first_sets() {
|
||||||
std::set<item_t> items;
|
std::set<item_t> items;
|
||||||
|
|
||||||
for (const std::string &nonterm : get_nonterminals())
|
for (const std::string &nonterm : get_nonterminals())
|
||||||
first_sets.insert(std::make_pair(nonterm, std::set<symbol_t>()));
|
first_sets.insert({nonterm, std::set<symbol_t>()});
|
||||||
|
|
||||||
for (const rule_t &rule : get_grammar().rules)
|
for (const rule_t &rule : get_grammar().rules)
|
||||||
items.insert(rule.item);
|
items.insert(rule.item);
|
||||||
|
@ -74,7 +74,7 @@ void generator_slr_t::generate_follow_sets() {
|
||||||
generate_first_sets();
|
generate_first_sets();
|
||||||
|
|
||||||
for (const std::string &nonterm : get_nonterminals())
|
for (const std::string &nonterm : get_nonterminals())
|
||||||
follow_sets.insert(std::make_pair(nonterm, std::set<symbol_t>()));
|
follow_sets.insert({nonterm, std::set<symbol_t>()});
|
||||||
|
|
||||||
follow_sets[""].insert(symbol_t::empty());
|
follow_sets[""].insert(symbol_t::empty());
|
||||||
|
|
||||||
|
@ -126,16 +126,16 @@ void generator_slr_t::generate_follow_sets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generator_slr_t::has_reduce_conflict(size_t from, const symbol_t &sym) {
|
bool generator_slr_t::has_reduce_conflict(size_t from, const symbol_t &sym) {
|
||||||
return reductions.count(std::make_pair(from, sym));
|
return reductions.count({from, sym});
|
||||||
}
|
}
|
||||||
|
|
||||||
void generator_slr_t::add_reduction(size_t from, size_t rule) {
|
void generator_slr_t::add_reduction(size_t from, size_t rule) {
|
||||||
const item_t &item = get_grammar().rules[rule].item;
|
const item_t &item = get_grammar().rules[rule].item;
|
||||||
for (const symbol_t sym : follow_sets[item.get_lhs()]) {
|
for (const symbol_t sym : follow_sets[item.get_lhs()]) {
|
||||||
if (get_shifts().count(std::make_pair(from, sym)))
|
if (get_shifts().count({from, sym}))
|
||||||
throw conflict_error("shift/reduce conflict");
|
throw conflict_error("shift/reduce conflict");
|
||||||
|
|
||||||
if (!reductions.insert(std::make_pair(std::make_pair(from, sym), rule)).second)
|
if (!reductions.insert({{from, sym}, rule}).second)
|
||||||
throw conflict_error("reduce/reduce conflict");
|
throw conflict_error("reduce/reduce conflict");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,18 +43,19 @@ struct grammar_t {
|
||||||
|
|
||||||
std::string header_block;
|
std::string header_block;
|
||||||
std::string source_block;
|
std::string source_block;
|
||||||
|
std::vector<std::string> ns;
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> extra_args;
|
std::vector<std::pair<std::string, std::string>> extra_args;
|
||||||
|
|
||||||
|
|
||||||
void add_rule(const rule_t &rule) {
|
void add_rule(const item_t &item, const std::vector<std::pair<std::string, bool>> &variables, const std::string &action) {
|
||||||
if (rules.empty()) {
|
if (rules.empty()) {
|
||||||
item_t init("");
|
item_t init("");
|
||||||
init.get_rhs().push_back(symbol_t::make_nonterm(rule.item.get_lhs()));
|
init.get_rhs().push_back(symbol_t::make_nonterm(item.get_lhs()));
|
||||||
rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::pair<std::string, bool>>(), std::string()});
|
rules.push_back({std::move(init), std::vector<std::pair<std::string, bool>>(), std::string()});
|
||||||
}
|
}
|
||||||
|
|
||||||
rules.push_back(rule);
|
rules.push_back({item, variables, action});
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & get_nonterm_type(const std::string &sym) const {
|
const std::string & get_nonterm_type(const std::string &sym) const {
|
||||||
|
|
|
@ -309,6 +309,7 @@ int lex_t::lex(parse_token_value_t *value) {
|
||||||
case '=':
|
case '=':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
|
case '.':
|
||||||
token = current();
|
token = current();
|
||||||
next(true);
|
next(true);
|
||||||
consume(false);
|
consume(false);
|
||||||
|
|
|
@ -32,13 +32,13 @@ namespace solar {
|
||||||
output_common_t::output_common_t(const generator_t *generator0, const std::string &prefix0, const std::string &token_prefix0) :
|
output_common_t::output_common_t(const generator_t *generator0, const std::string &prefix0, const std::string &token_prefix0) :
|
||||||
generator(generator0), prefix(prefix0), token_prefix(token_prefix0) {
|
generator(generator0), prefix(prefix0), token_prefix(token_prefix0) {
|
||||||
for (const std::string &nonterm : generator->get_nonterminals())
|
for (const std::string &nonterm : generator->get_nonterminals())
|
||||||
symbol_values.insert(std::make_pair(symbol_t::make_nonterm(nonterm.c_str()), "symbol_" + nonterm));
|
symbol_values.insert({symbol_t::make_nonterm(nonterm.c_str()), "symbol_" + nonterm});
|
||||||
|
|
||||||
for (const symbol_t &term : generator->get_terminals()) {
|
for (const symbol_t &term : generator->get_terminals()) {
|
||||||
if (term.get_type() == SYMBOL_TYPE_TERM)
|
if (term.get_type() == SYMBOL_TYPE_TERM)
|
||||||
tokens.insert(std::make_pair(token_prefix + term.get_value(), tokens.size()));
|
tokens.insert({token_prefix + term.get_value(), tokens.size()});
|
||||||
|
|
||||||
symbol_values.insert(std::make_pair(term, "token." + generator->get_grammar().get_term_type(term).second));
|
symbol_values.insert({term, "token." + generator->get_grammar().get_term_type(term).second});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ void output_header_t::emit_token_value() {
|
||||||
for (const symbol_t &term : get_generator()->get_terminals()) {
|
for (const symbol_t &term : get_generator()->get_terminals()) {
|
||||||
const auto &type = get_generator()->get_grammar().get_term_type(term);
|
const auto &type = get_generator()->get_grammar().get_term_type(term);
|
||||||
if (!type.first.empty())
|
if (!type.first.empty())
|
||||||
token_values.insert(std::make_pair(type.second, type.first));
|
token_values.insert({type.second, type.first});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &value : token_values)
|
for (const auto &value : token_values)
|
||||||
|
@ -67,6 +67,13 @@ void output_header_t::write() {
|
||||||
write_line();
|
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();
|
emit_tokens();
|
||||||
write_line();
|
write_line();
|
||||||
|
|
||||||
|
@ -80,6 +87,13 @@ void output_header_t::write() {
|
||||||
write_line_(sig_free());
|
write_line_(sig_free());
|
||||||
write_line();
|
write_line();
|
||||||
write_line_(sig_push());
|
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("}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,11 +142,11 @@ void output_source_t::emit_gotos(const std::string &lhs) {
|
||||||
std::map<unsigned, std::set<unsigned>> gotos;
|
std::map<unsigned, std::set<unsigned>> gotos;
|
||||||
|
|
||||||
for (size_t state = 0; state < get_generator()->get_state_count(); state++) {
|
for (size_t state = 0; state < get_generator()->get_state_count(); state++) {
|
||||||
auto it = get_generator()->get_gotos().find(std::make_pair(state, lhs));
|
auto it = get_generator()->get_gotos().find({state, lhs});
|
||||||
if (it == get_generator()->get_gotos().end())
|
if (it == get_generator()->get_gotos().end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::set<unsigned> &states = gotos.insert(std::make_pair(it->second, std::set<unsigned>())).first->second;
|
std::set<unsigned> &states = gotos.insert({it->second, std::set<unsigned>()}).first->second;
|
||||||
states.insert(state);
|
states.insert(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +213,13 @@ void output_source_t::write() {
|
||||||
write_line();
|
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();
|
emit_types();
|
||||||
write_line();
|
write_line();
|
||||||
|
|
||||||
|
@ -229,6 +236,13 @@ void output_source_t::write() {
|
||||||
write_line();
|
write_line();
|
||||||
|
|
||||||
emit_push();
|
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("}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,11 @@ void output_source_slr_t::emit_state_shift(unsigned state) {
|
||||||
std::map<unsigned, std::set<symbol_t>> shifts;
|
std::map<unsigned, std::set<symbol_t>> shifts;
|
||||||
|
|
||||||
for (const symbol_t &token : get_generator()->get_terminals()) {
|
for (const symbol_t &token : get_generator()->get_terminals()) {
|
||||||
auto it = get_generator()->get_shifts().find(std::make_pair(state, token));
|
auto it = get_generator()->get_shifts().find({state, token});
|
||||||
if (it == get_generator()->get_shifts().end())
|
if (it == get_generator()->get_shifts().end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::set<symbol_t> &symbols = shifts.insert(std::make_pair(it->second, std::set<symbol_t>())).first->second;
|
std::set<symbol_t> &symbols = shifts.insert({it->second, std::set<symbol_t>()}).first->second;
|
||||||
symbols.insert(token);
|
symbols.insert(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ void output_source_slr_t::emit_state_reduce_code(const item_t &item, unsigned ru
|
||||||
write_line_("result.symbol_", item.get_lhs(), " = ", call(reduce_func));
|
write_line_("result.symbol_", item.get_lhs(), " = ", call(reduce_func));
|
||||||
|
|
||||||
for (unsigned i = 0; i < vars.size(); i++) {
|
for (unsigned i = 0; i < vars.size(); i++) {
|
||||||
if (!vars[i].second)
|
if (vars[i].second)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto it = get_generator()->get_grammar().destructors.find(rhs[i]);
|
auto it = get_generator()->get_grammar().destructors.find(rhs[i]);
|
||||||
|
@ -92,11 +92,11 @@ bool output_source_slr_t::emit_state_reduce(unsigned state) {
|
||||||
std::map<unsigned, std::set<symbol_t>> reductions;
|
std::map<unsigned, std::set<symbol_t>> reductions;
|
||||||
|
|
||||||
for (const symbol_t &token : get_generator()->get_terminals()) {
|
for (const symbol_t &token : get_generator()->get_terminals()) {
|
||||||
auto it = get_generator()->get_reductions().find(std::make_pair(state, token));
|
auto it = get_generator()->get_reductions().find({state, token});
|
||||||
if (it == get_generator()->get_reductions().end())
|
if (it == get_generator()->get_reductions().end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::set<symbol_t> &symbols = reductions.insert(std::make_pair(it->second, std::set<symbol_t>())).first->second;
|
std::set<symbol_t> &symbols = reductions.insert({it->second, std::set<symbol_t>()}).first->second;
|
||||||
symbols.insert(token);
|
symbols.insert(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ bool output_source_slr_t::emit_state_reduce(unsigned state) {
|
||||||
void output_source_slr_t::emit_state(unsigned state) {
|
void output_source_slr_t::emit_state(unsigned state) {
|
||||||
block_t switch_token(this, "switch (token)");
|
block_t switch_token(this, "switch (token)");
|
||||||
|
|
||||||
if (get_generator()->get_shifts().find(std::make_pair(state, symbol_t::make_nonterm(""))) != get_generator()->get_shifts().end()) {
|
if (get_generator()->get_shifts().find({state, symbol_t::make_nonterm("")}) != get_generator()->get_shifts().end()) {
|
||||||
write_case(0);
|
write_case(0);
|
||||||
write_line_("return 0");
|
write_line_("return 0");
|
||||||
write_line();
|
write_line();
|
||||||
|
|
1077
src/parse.cpp
1077
src/parse.cpp
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,8 @@
|
||||||
#include "grammar.hpp"
|
#include "grammar.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace solar {
|
||||||
|
|
||||||
typedef enum parse_token {
|
typedef enum parse_token {
|
||||||
TOK_BLOCK = 256,
|
TOK_BLOCK = 256,
|
||||||
TOK_CHAR = 257,
|
TOK_CHAR = 257,
|
||||||
|
@ -14,7 +16,7 @@ typedef enum parse_token {
|
||||||
} parse_token_t;
|
} parse_token_t;
|
||||||
|
|
||||||
typedef struct parse_token_value {
|
typedef struct parse_token_value {
|
||||||
char c;
|
unsigned char c;
|
||||||
std::string *str;
|
std::string *str;
|
||||||
} parse_token_value_t;
|
} parse_token_value_t;
|
||||||
|
|
||||||
|
@ -23,4 +25,6 @@ typedef struct parse_context parse_context_t;
|
||||||
parse_context_t * parse_alloc(void *(*alloc_func)(size_t));
|
parse_context_t * parse_alloc(void *(*alloc_func)(size_t));
|
||||||
void parse_free(parse_context_t *parser, void (*free_func)(void *));
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
167
src/parse.y
167
src/parse.y
|
@ -1,68 +1,39 @@
|
||||||
|
%namespace solar
|
||||||
|
|
||||||
%header {
|
%header {
|
||||||
#include "grammar.hpp"
|
#include "grammar.hpp"
|
||||||
}
|
}
|
||||||
|
|
||||||
%source {
|
%source {
|
||||||
typedef std::vector<std::pair<std::string, bool>> vars_t;
|
namespace solar {
|
||||||
|
|
||||||
|
typedef std::pair<std::string, bool> var_t;
|
||||||
|
typedef std::vector<var_t> vars_t;
|
||||||
typedef std::pair<std::vector<solar::symbol_t>, vars_t> rhs_t;
|
typedef std::pair<std::vector<solar::symbol_t>, vars_t> rhs_t;
|
||||||
|
|
||||||
|
}
|
||||||
static inline void free_string(std::string *v) {
|
|
||||||
delete v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void free_symbol(solar::symbol_t *v) {
|
|
||||||
delete v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void free_rule(solar::rule_t *v) {
|
%extra_arg {__attribute__((unused)) grammar_t *} grammar
|
||||||
delete v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void free_rhs(rhs_t *v) {
|
|
||||||
delete v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
%type SYMBOL {std::string *} str
|
%type SYMBOL {std::string *} str
|
||||||
%destructor SYMBOL free_string
|
%destructor SYMBOL delete
|
||||||
|
|
||||||
%type SYMBOL_UC {std::string *} str
|
%type SYMBOL_UC {std::string *} str
|
||||||
%destructor SYMBOL_UC free_string
|
%destructor SYMBOL_UC delete
|
||||||
|
|
||||||
%type BLOCK {std::string *} str
|
%type BLOCK {std::string *} str
|
||||||
%destructor BLOCK free_string
|
%destructor BLOCK delete
|
||||||
|
|
||||||
%type SQBLOCK {std::string *} str
|
%type SQBLOCK {std::string *} str
|
||||||
%destructor SQBLOCK free_string
|
%destructor SQBLOCK delete
|
||||||
|
|
||||||
%type STRING {std::string *} str
|
%type STRING {std::string *} str
|
||||||
%destructor STRING free_string
|
%destructor STRING delete
|
||||||
|
|
||||||
%type CHAR {char} c
|
%type CHAR {unsigned char} c
|
||||||
|
|
||||||
|
|
||||||
%type rule {solar::rule_t *}
|
|
||||||
%destructor rule free_rule
|
|
||||||
|
|
||||||
%type rhs {rhs_t *}
|
|
||||||
%destructor rhs free_rhs
|
|
||||||
|
|
||||||
%type action {std::string *}
|
|
||||||
%destructor action free_string
|
|
||||||
|
|
||||||
%type symbol {solar::symbol_t *}
|
|
||||||
%destructor symbol free_symbol
|
|
||||||
|
|
||||||
%type term {solar::symbol_t *}
|
|
||||||
%destructor term free_symbol
|
|
||||||
|
|
||||||
%type varname {std::string *}
|
|
||||||
%destructor varname free_string
|
|
||||||
|
|
||||||
|
|
||||||
%extra_arg {__attribute__((unused)) solar::grammar_t *} grammar
|
|
||||||
|
|
||||||
|
|
||||||
grammar |=;
|
grammar |=;
|
||||||
|
@ -70,15 +41,19 @@ grammar |= grammar directive;
|
||||||
|
|
||||||
|
|
||||||
directive |= "%type" SYMBOL(nonterm) BLOCK(type) {
|
directive |= "%type" SYMBOL(nonterm) BLOCK(type) {
|
||||||
grammar->nonterm_types.insert(std::make_pair(*nonterm, *type));
|
grammar->nonterm_types.insert({*nonterm, *type});
|
||||||
}
|
}
|
||||||
|
|
||||||
directive |= "%type" term(term) BLOCK(type) varname(name) {
|
directive |= "%type" term(term) BLOCK(type) csymbol(name) {
|
||||||
grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name)));
|
grammar->term_types.insert({*term, {*type, *name}});
|
||||||
}
|
}
|
||||||
|
|
||||||
directive |= "%destructor" symbol(sym) varname(name) {
|
directive |= "%destructor" symbol(sym) csymbol(name) {
|
||||||
grammar->destructors.insert(std::make_pair(*sym, *name));
|
grammar->destructors.insert({*sym, *name});
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%namespace" namespace(ns) {
|
||||||
|
grammar->ns = *ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
directive |= "%source" BLOCK(block) {
|
directive |= "%source" BLOCK(block) {
|
||||||
|
@ -89,45 +64,35 @@ directive |= "%header" BLOCK(block) {
|
||||||
grammar->header_block = *block;
|
grammar->header_block = *block;
|
||||||
}
|
}
|
||||||
|
|
||||||
directive |= "%extra_arg" BLOCK(type) varname(name) {
|
directive |= "%extra_arg" BLOCK(type) csymbol(name) {
|
||||||
grammar->extra_args.push_back(std::make_pair(*type, *name));
|
grammar->extra_args.emplace_back(*type, *name);
|
||||||
}
|
}
|
||||||
|
|
||||||
directive |= rule(rule) {
|
directive |= SYMBOL(lhs) "|=" rhs(rhs) action(action) {
|
||||||
grammar->add_rule(*rule);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rule |= SYMBOL(lhs) "|=" rhs(rhs) action(action)
|
%type rhs {rhs_t *}
|
||||||
[new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action}]
|
%destructor rhs delete
|
||||||
|
|
||||||
|
rhs |= [new rhs_t]
|
||||||
|
|
||||||
rhs |= [new rhs_t()]
|
rhs |= rhs(=rhs) symbol(sym) variable(var) {
|
||||||
|
|
||||||
rhs |= rhs(=rhs) symbol(sym) {
|
|
||||||
rhs->first.push_back(*sym);
|
rhs->first.push_back(*sym);
|
||||||
rhs->second.emplace_back();
|
rhs->second.push_back(*var);
|
||||||
|
|
||||||
return rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
rhs |= rhs(=rhs) symbol(sym) '(' varname(var) ')' {
|
|
||||||
rhs->first.push_back(*sym);
|
|
||||||
rhs->second.emplace_back(*var, true);
|
|
||||||
|
|
||||||
return rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
rhs |= rhs(=rhs) symbol(sym) '(' '=' varname(var) ')' {
|
|
||||||
rhs->first.push_back(*sym);
|
|
||||||
rhs->second.emplace_back(*var, false);
|
|
||||||
|
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
rhs |= rhs(=rhs) STRING(str) {
|
rhs |= rhs(=rhs) STRING(str) {
|
||||||
for (char c : *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();
|
rhs->second.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,16 +100,54 @@ rhs |= rhs(=rhs) STRING(str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
action |= ';' [new std::string]
|
%type variable {var_t *}
|
||||||
action |= BLOCK(=v) [v]
|
%destructor variable delete
|
||||||
action |= SQBLOCK(v) [new std::string("return " + *v + ";")]
|
|
||||||
|
variable |= [new var_t]
|
||||||
|
variable |= '(' consume(consume) csymbol(var) ')'
|
||||||
|
[new var_t(*var, consume)]
|
||||||
|
|
||||||
|
|
||||||
symbol |= SYMBOL(v) [new solar::symbol_t(solar::symbol_t::make_nonterm(*v))]
|
%type consume {bool}
|
||||||
symbol |= term(=v) [v]
|
|
||||||
|
|
||||||
term |= SYMBOL_UC(v) [new solar::symbol_t(solar::symbol_t::make_term(*v))]
|
consume |= [false]
|
||||||
term |= CHAR(v) [new solar::symbol_t(solar::symbol_t::make_char(v))]
|
consume |= '=' [true]
|
||||||
|
|
||||||
varname |= SYMBOL_UC(=v) [v]
|
|
||||||
varname |= SYMBOL(=v) [v]
|
%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<std::string> *}
|
||||||
|
%destructor namespace delete
|
||||||
|
|
||||||
|
namespace |= csymbol(v) [new std::vector<std::string> {*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]
|
||||||
|
|
Reference in a new issue