diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-06 00:22:44 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-06 00:22:44 +0200 |
commit | 6fb60a72012f97f846477eb370d1a0706b1b4bc2 (patch) | |
tree | 5cc40d0af6a14f3c2b57434419b2fb73bbacf2ac /src/generator.hpp | |
parent | 696d94d796f76d1d83c740b184f0cf8b9cbfc9d3 (diff) | |
download | solar-6fb60a72012f97f846477eb370d1a0706b1b4bc2.tar solar-6fb60a72012f97f846477eb370d1a0706b1b4bc2.zip |
generator: detect LR(0) conflicts
Diffstat (limited to 'src/generator.hpp')
-rw-r--r-- | src/generator.hpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/generator.hpp b/src/generator.hpp index 8178bbd..47ef6bf 100644 --- a/src/generator.hpp +++ b/src/generator.hpp @@ -28,6 +28,7 @@ #include "item.hpp" +#include <stdexcept> #include <set> #include <map> @@ -35,6 +36,13 @@ namespace solar { class generator_t { +public: + class conflict_error : public std::runtime_error { + public: + explicit conflict_error(const std::string& what_arg) : std::runtime_error(what_arg) {} + explicit conflict_error(const char* what_arg) : std::runtime_error(what_arg) {} + }; + private: std::vector<std::pair<item_t, std::string>> rules; std::map<item_t, size_t> rule_ids; @@ -49,6 +57,8 @@ private: 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); @@ -56,6 +66,27 @@ private: return itemsets.emplace(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.emplace(from, to); + } + + void add_shift(size_t from, const symbol_t &sym, size_t to) { + if (reductions.count(from)) + throw conflict_error("shift/reduce conflict"); + + shift_conflicts.insert(from); + shifts.emplace(std::make_pair(from, sym), to); + } + + void add_goto(size_t from, const std::string &nonterm, size_t to) { + gotos.emplace(std::make_pair(from, nonterm), to); + } + void generate_itemsets(); public: |