generator: move LR(0)-specific code to generator_lr0_t

This commit is contained in:
Matthias Schiffer 2015-04-09 19:14:14 +02:00
parent 5887ec38e1
commit 35c02202fd
6 changed files with 50 additions and 29 deletions

View file

@ -62,7 +62,7 @@ void generator_t::close_set(std::set<item_t> *set) {
} }
} }
void generator_t::generate_itemsets() { void generator_t::generate() {
std::queue<std::pair<std::set<item_t>, size_t>> queue; std::queue<std::pair<std::set<item_t>, size_t>> queue;
{ {
@ -136,8 +136,6 @@ generator_t::generator_t(const grammar_t &grammar0) : grammar(grammar0) {
rule_ids.insert(std::make_pair(rule, i)); rule_ids.insert(std::make_pair(rule, i));
} }
generate_itemsets();
} }
} }

View file

@ -56,11 +56,8 @@ private:
std::map<std::set<item_t>, size_t> itemsets; std::map<std::set<item_t>, size_t> itemsets;
std::map<std::pair<size_t, symbol_t>, size_t> shifts; std::map<std::pair<size_t, symbol_t>, size_t> shifts;
std::map<size_t, size_t> reductions;
std::map<std::pair<size_t, std::string>, size_t> gotos; std::map<std::pair<size_t, std::string>, size_t> gotos;
std::set<size_t> shift_conflicts;
void close_set(std::set<item_t> *set); void close_set(std::set<item_t> *set);
std::set<item_t> get_set(const std::string &nonterm); std::set<item_t> get_set(const std::string &nonterm);
@ -69,20 +66,10 @@ private:
return itemsets.insert(std::make_pair(set, itemsets.size())); return itemsets.insert(std::make_pair(set, itemsets.size()));
} }
void add_reduction(size_t from, size_t to) {
if (reductions.count(from))
throw conflict_error("reduce/reduce conflict");
if (shift_conflicts.count(from))
throw conflict_error("shift/reduce conflict");
reductions.insert(std::make_pair(from, to));
}
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 (reductions.count(from)) if (has_reduce_conflict(from, sym))
throw conflict_error("shift/reduce conflict"); throw conflict_error("shift/reduce conflict");
shift_conflicts.insert(from);
shifts.insert(std::make_pair(std::make_pair(from, sym), to)); shifts.insert(std::make_pair(std::make_pair(from, sym), to));
} }
@ -90,7 +77,11 @@ private:
gotos.insert(std::make_pair(std::make_pair(from, nonterm), to)); gotos.insert(std::make_pair(std::make_pair(from, nonterm), to));
} }
void generate_itemsets(); protected:
virtual bool has_reduce_conflict(size_t from, const symbol_t &sym) = 0;
virtual void add_reduction(size_t from, size_t to) = 0;
generator_t(const grammar_t &grammar0);
public: public:
const grammar_t & get_grammar() const { const grammar_t & get_grammar() const {
@ -109,10 +100,6 @@ public:
return itemsets.size(); return itemsets.size();
} }
const std::map<size_t, size_t> & get_reductions() const {
return reductions;
}
const std::map<std::pair<size_t, symbol_t>, size_t> & get_shifts() const { const std::map<std::pair<size_t, symbol_t>, size_t> & get_shifts() const {
return shifts; return shifts;
} }
@ -121,8 +108,9 @@ public:
return gotos; return gotos;
} }
protected: virtual ~generator_t() {}
generator_t(const grammar_t &grammar0);
void generate();
}; };
} }

View file

@ -25,3 +25,25 @@
#include "generator_lr0.hpp" #include "generator_lr0.hpp"
namespace solar {
bool generator_lr0_t::has_reduce_conflict(size_t from, const symbol_t &sym) {
(void)sym;
return reductions.count(from);
}
void generator_lr0_t::add_reduction(size_t from, size_t to) {
if (reductions.count(from))
throw conflict_error("reduce/reduce conflict");
for (const symbol_t &sym : get_terminals()) {
if (get_shifts().count(std::make_pair(from, sym)))
throw conflict_error("shift/reduce conflict");
}
reductions.insert(std::make_pair(from, to));
}
}

View file

@ -32,8 +32,21 @@
namespace solar { namespace solar {
class generator_lr0_t : public generator_t { class generator_lr0_t : public generator_t {
private:
std::map<size_t, size_t> reductions;
protected:
virtual bool has_reduce_conflict(size_t from, const symbol_t &sym);
virtual void add_reduction(size_t from, size_t to);
public: public:
generator_lr0_t(const grammar_t &grammar) : generator_t(grammar) {} const std::map<size_t, size_t> & get_reductions() const {
return reductions;
}
generator_lr0_t(const grammar_t &grammar) : generator_t(grammar) {
generate();
}
}; };
} }

View file

@ -33,7 +33,7 @@
namespace solar { namespace solar {
output_t::output_t(const generator_t *generator0, const char *header, const char *source) output_t::output_t(const generator_lr0_t *generator0, const char *header, const char *source)
: prefix_str("parse_"), : prefix_str("parse_"),
token_prefix_str("TOK_"), token_prefix_str("TOK_"),
stack_size(100), stack_size(100),

View file

@ -26,7 +26,7 @@
#pragma once #pragma once
#include "generator.hpp" #include "generator_lr0.hpp"
#include <cstdio> #include <cstdio>
@ -39,7 +39,7 @@ private:
std::string token_prefix_str; std::string token_prefix_str;
unsigned stack_size; unsigned stack_size;
const generator_t *generator; const generator_lr0_t *generator;
std::string header_filename; std::string header_filename;
@ -73,7 +73,7 @@ private:
void emit_source(); void emit_source();
public: public:
output_t(const generator_t *generator0, const char *header, const char *source); output_t(const generator_lr0_t *generator0, const char *header, const char *source);
~output_t(); ~output_t();
void write(); void write();