diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-09 19:14:14 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-09 19:14:14 +0200 |
commit | 35c02202fd782b32feef350a012cd3b55d5b6b12 (patch) | |
tree | c285d3454c69605c735539f7eeae58902de7af09 /src | |
parent | 5887ec38e1ff7f23c50140ccbb12debcab281abd (diff) | |
download | solar-35c02202fd782b32feef350a012cd3b55d5b6b12.tar solar-35c02202fd782b32feef350a012cd3b55d5b6b12.zip |
generator: move LR(0)-specific code to generator_lr0_t
Diffstat (limited to 'src')
-rw-r--r-- | src/generator.cpp | 4 | ||||
-rw-r--r-- | src/generator.hpp | 30 | ||||
-rw-r--r-- | src/generator_lr0.cpp | 22 | ||||
-rw-r--r-- | src/generator_lr0.hpp | 15 | ||||
-rw-r--r-- | src/output.cpp | 2 | ||||
-rw-r--r-- | src/output.hpp | 6 |
6 files changed, 50 insertions, 29 deletions
diff --git a/src/generator.cpp b/src/generator.cpp index 1774448..1a4c79f 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -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(); } } diff --git a/src/generator.hpp b/src/generator.hpp index 1ad70ab..024b630 100644 --- a/src/generator.hpp +++ b/src/generator.hpp @@ -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(); }; } diff --git a/src/generator_lr0.cpp b/src/generator_lr0.cpp index cbf051c..024f5fa 100644 --- a/src/generator_lr0.cpp +++ b/src/generator_lr0.cpp @@ -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)); +} + +} diff --git a/src/generator_lr0.hpp b/src/generator_lr0.hpp index c434ed6..063a518 100644 --- a/src/generator_lr0.hpp +++ b/src/generator_lr0.hpp @@ -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(); + } }; } diff --git a/src/output.cpp b/src/output.cpp index f15aac0..f9ffc1f 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -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), diff --git a/src/output.hpp b/src/output.hpp index e3d5b99..0bff7d3 100644 --- a/src/output.hpp +++ b/src/output.hpp @@ -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(); |