From 35c02202fd782b32feef350a012cd3b55d5b6b12 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 9 Apr 2015 19:14:14 +0200 Subject: generator: move LR(0)-specific code to generator_lr0_t --- src/generator.cpp | 4 +--- src/generator.hpp | 30 +++++++++--------------------- src/generator_lr0.cpp | 22 ++++++++++++++++++++++ src/generator_lr0.hpp | 15 ++++++++++++++- src/output.cpp | 2 +- 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 *set) { } } -void generator_t::generate_itemsets() { +void generator_t::generate() { std::queue, 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, size_t> itemsets; std::map, size_t> shifts; - std::map reductions; std::map, size_t> gotos; - std::set shift_conflicts; - void close_set(std::set *set); std::set 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 & get_reductions() const { - return reductions; - } - const std::map, 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 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 & 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 @@ -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(); -- cgit v1.2.3