From cf237b04eb5e465090aa6fdf7f4c9efa80d70461 Mon Sep 17 00:00:00 2001 From: Robin Jadoul Date: Wed, 11 Jan 2017 17:49:40 +0100 Subject: [PATCH] Infinite loop, to debug --- include/Parsodus/backendmanager.h | 2 + include/Parsodus/lrtables/LALR1Itemset.h | 24 +++++++++++ include/Parsodus/lrtables/LR1ItemsetBase.h | 20 +++------ parser.example.pds | 12 ++---- src/CMakeLists.txt | 1 + src/lrtables/LALR1Itemset.cpp | 49 ++++++++++++++++++++++ 6 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 include/Parsodus/lrtables/LALR1Itemset.h create mode 100644 src/lrtables/LALR1Itemset.cpp diff --git a/include/Parsodus/backendmanager.h b/include/Parsodus/backendmanager.h index 1bad134..51ac58c 100644 --- a/include/Parsodus/backendmanager.h +++ b/include/Parsodus/backendmanager.h @@ -11,6 +11,7 @@ #include "Parsodus/lrtables/LR0Itemset.h" #include "Parsodus/lrtables/SLR1Itemset.h" #include "Parsodus/lrtables/LR1Itemset.h" +#include "Parsodus/lrtables/LALR1Itemset.h" #include "Parsodus/util/parserType.h" namespace pds { @@ -32,6 +33,7 @@ namespace pds { registerBackend(std::make_unique>>(util::ParserType::LR_0)); registerBackend(std::make_unique>>(util::ParserType::SLR_1)); registerBackend(std::make_unique>>(util::ParserType::LR_1)); + registerBackend(std::make_unique>>(util::ParserType::LALR_1)); } /** diff --git a/include/Parsodus/lrtables/LALR1Itemset.h b/include/Parsodus/lrtables/LALR1Itemset.h new file mode 100644 index 0000000..682e11b --- /dev/null +++ b/include/Parsodus/lrtables/LALR1Itemset.h @@ -0,0 +1,24 @@ +#pragma once +#ifndef PARSODUS_LRTABLES_LALR1ITEMSET_H_TJ1FUOEG +#define PARSODUS_LRTABLES_LALR1ITEMSET_H_TJ1FUOEG + +#include "Parsodus/lrtables/LR1ItemsetBase.h" + +namespace pds { +namespace lr { + +class LALR1Itemset : public LR1ItemsetBase { +public: + LALR1Itemset(); + LALR1Itemset(std::shared_ptr start); + + bool canMerge(const LALR1Itemset& rhs) const; + void merge(const LALR1Itemset& rhs); + +private: +}; + +} /* lr */ +} /* pds */ + +#endif /* PARSODUS_LRTABLES_LALR1ITEMSET_H_TJ1FUOEG */ diff --git a/include/Parsodus/lrtables/LR1ItemsetBase.h b/include/Parsodus/lrtables/LR1ItemsetBase.h index 738770d..108bfa5 100644 --- a/include/Parsodus/lrtables/LR1ItemsetBase.h +++ b/include/Parsodus/lrtables/LR1ItemsetBase.h @@ -24,8 +24,8 @@ public: bool empty() const; std::set getReduces(const Grammar& g, std::string lookahead) const; -private: - std::set m_items; +protected: + std::vector m_items; }; template @@ -34,7 +34,7 @@ LR1ItemsetBase::LR1ItemsetBase() template LR1ItemsetBase::LR1ItemsetBase(std::shared_ptr start) { - m_items.emplace(LR1Item{start, 0, {util::EOF_PLACEHOLDER}}); + m_items.emplace_back(LR1Item{start, 0, {util::EOF_PLACEHOLDER}}); } template @@ -78,13 +78,9 @@ void LR1ItemsetBase::close(const Grammar& g) { } } - std::vector newItems; - for (auto& it : m_items) { - newItems.emplace_back(std::move(it)); - } for (const auto& newItem : toAdd) { bool found = false; - for (auto& oldItem : newItems) { + for (auto& oldItem : m_items) { if (newItem.dotIdx == oldItem.dotIdx && newItem.rule == oldItem.rule) { found = true; oldItem.lookaheads.insert(newItem.lookaheads.begin(), newItem.lookaheads.end()); @@ -92,13 +88,9 @@ void LR1ItemsetBase::close(const Grammar& g) { } } if (!found) { - newItems.push_back(newItem); + m_items.push_back(newItem); } } - m_items.clear(); - for (auto& it : newItems) { - m_items.emplace(std::move(it)); - } } } @@ -108,7 +100,7 @@ Itemset LR1ItemsetBase::succ(std::string sym) const { for (auto& item : m_items) { if (item.dotIdx < item.rule->tail.size()) { if (item.rule->tail[item.dotIdx] == sym) { - sc.m_items.insert(LR1Item{item.rule, item.dotIdx + 1, item.lookaheads}); + sc.m_items.push_back(LR1Item{item.rule, item.dotIdx + 1, item.lookaheads}); } } } diff --git a/parser.example.pds b/parser.example.pds index 79a6999..42367e1 100644 --- a/parser.example.pds +++ b/parser.example.pds @@ -1,12 +1,8 @@ -parser: SLR(1) +parser: lalr(1) lexesis: lexer.lxs terminals: - TERMINAL + A B start: s grammar: - s -> a s - | b - ; - - a → TERMINAL; - b -> a; + s -> x x; + x -> A x | B; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ef09aca..1ca0b7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(Parsodus-tables lrtables/SLR1Itemset.cpp lrtables/LR1Item.cpp lrtables/LR1Itemset.cpp + lrtables/LALR1Itemset.cpp ) # add_library(Parsodus-backends diff --git a/src/lrtables/LALR1Itemset.cpp b/src/lrtables/LALR1Itemset.cpp new file mode 100644 index 0000000..73611e3 --- /dev/null +++ b/src/lrtables/LALR1Itemset.cpp @@ -0,0 +1,49 @@ +#include "Parsodus/lrtables/LALR1Itemset.h" + +#include + +namespace pds { +namespace lr { + +LALR1Itemset::LALR1Itemset() : LR1ItemsetBase() +{} + +LALR1Itemset::LALR1Itemset(std::shared_ptr start) : LR1ItemsetBase(start) +{} + +bool LALR1Itemset::canMerge(const LALR1Itemset& rhs) const { + if (rhs.m_items.size() != m_items.size()) { + return false; + } + + for (auto& rhsIt : rhs.m_items) { + bool ok = false; + for (auto& it : m_items) { + if (it.rule == rhsIt.rule && it.dotIdx == rhsIt.dotIdx) { + ok = true; + break; + } + } + if (!ok) + return false; + } + + return true; +} + +void LALR1Itemset::merge(const LALR1Itemset& rhs) { + for (auto& toMerge : rhs.m_items) { + bool found = false; + for (auto& it : m_items) { + if (it.rule == toMerge.rule && it.dotIdx == toMerge.dotIdx) { + found = true; + it.lookaheads.insert(toMerge.lookaheads.begin(), toMerge.lookaheads.end()); + break; + } + } + assert(found); + } +} + +} /* lr */ +} /* pds */