summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-04-09 19:14:14 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-04-09 19:14:14 +0200
commit35c02202fd782b32feef350a012cd3b55d5b6b12 (patch)
treec285d3454c69605c735539f7eeae58902de7af09 /src
parent5887ec38e1ff7f23c50140ccbb12debcab281abd (diff)
downloadsolar-35c02202fd782b32feef350a012cd3b55d5b6b12.tar
solar-35c02202fd782b32feef350a012cd3b55d5b6b12.zip
generator: move LR(0)-specific code to generator_lr0_t
Diffstat (limited to 'src')
-rw-r--r--src/generator.cpp4
-rw-r--r--src/generator.hpp30
-rw-r--r--src/generator_lr0.cpp22
-rw-r--r--src/generator_lr0.hpp15
-rw-r--r--src/output.cpp2
-rw-r--r--src/output.hpp6
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();