From e6eef2bda79dcf2abde080943cb8f9808941e331 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 11 Sep 2021 16:52:25 +0800 Subject: ... --- src/parse/Grammar.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/parse/Grammar.cpp') diff --git a/src/parse/Grammar.cpp b/src/parse/Grammar.cpp index a2dd14d4..3cf43237 100644 --- a/src/parse/Grammar.cpp +++ b/src/parse/Grammar.cpp @@ -2,6 +2,8 @@ #include "cru/parse/Symbol.hpp" #include +#include +#include namespace cru::parse { Grammar::Grammar() {} @@ -69,4 +71,35 @@ bool Grammar::RemoveProduction(Production* production) { return true; } +Grammar* Grammar::Clone() const { + Grammar* g = new Grammar(); + + std::unordered_map symbol_map; + + for (auto old_terminal : terminals_) { + auto new_terminal = g->CreateTerminal(old_terminal->GetName()); + symbol_map.emplace(old_terminal, new_terminal); + } + + for (auto old_nonterminal : nonterminals_) { + auto new_nonterminal = g->CreateNonterminal(old_nonterminal->GetName()); + symbol_map.emplace(old_nonterminal, new_nonterminal); + } + + for (auto old_production : productions_) { + std::vector new_right; + std::transform(old_production->GetRight().cbegin(), + old_production->GetRight().cend(), + std::back_inserter(new_right), + [&symbol_map](Symbol* old) { return symbol_map[old]; }); + + g->CreateProduction( + old_production->GetName(), + static_cast(symbol_map[old_production->GetLeft()]), + std::move(new_right)); + } + + return g; +} + } // namespace cru::parse -- cgit v1.2.3