generator: move LR(0)-specific code to generator_lr0_t
This commit is contained in:
parent
5887ec38e1
commit
35c02202fd
6 changed files with 50 additions and 29 deletions
|
@ -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;
|
||||
|
||||
{
|
||||
|
@ -136,8 +136,6 @@ generator_t::generator_t(const grammar_t &grammar0) : grammar(grammar0) {
|
|||
|
||||
rule_ids.insert(std::make_pair(rule, i));
|
||||
}
|
||||
|
||||
generate_itemsets();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,11 +56,8 @@ private:
|
|||
std::map<std::set<item_t>, size_t> itemsets;
|
||||
|
||||
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::set<size_t> shift_conflicts;
|
||||
|
||||
|
||||
void close_set(std::set<item_t> *set);
|
||||
std::set<item_t> get_set(const std::string &nonterm);
|
||||
|
@ -69,20 +66,10 @@ private:
|
|||
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) {
|
||||
if (reductions.count(from))
|
||||
if (has_reduce_conflict(from, sym))
|
||||
throw conflict_error("shift/reduce conflict");
|
||||
|
||||
shift_conflicts.insert(from);
|
||||
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));
|
||||
}
|
||||
|
||||
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:
|
||||
const grammar_t & get_grammar() const {
|
||||
|
@ -109,10 +100,6 @@ public:
|
|||
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 {
|
||||
return shifts;
|
||||
}
|
||||
|
@ -121,8 +108,9 @@ public:
|
|||
return gotos;
|
||||
}
|
||||
|
||||
protected:
|
||||
generator_t(const grammar_t &grammar0);
|
||||
virtual ~generator_t() {}
|
||||
|
||||
void generate();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,3 +25,25 @@
|
|||
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,21 @@
|
|||
namespace solar {
|
||||
|
||||
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:
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
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_"),
|
||||
token_prefix_str("TOK_"),
|
||||
stack_size(100),
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "generator.hpp"
|
||||
#include "generator_lr0.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
|
@ -39,7 +39,7 @@ private:
|
|||
std::string token_prefix_str;
|
||||
unsigned stack_size;
|
||||
|
||||
const generator_t *generator;
|
||||
const generator_lr0_t *generator;
|
||||
|
||||
std::string header_filename;
|
||||
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
void emit_source();
|
||||
|
||||
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();
|
||||
|
||||
void write();
|
||||
|
|
Reference in a new issue