diff options
-rw-r--r-- | include/cru/parse/Grammar.hpp | 3 | ||||
-rw-r--r-- | src/parse/Grammar.cpp | 34 |
2 files changed, 37 insertions, 0 deletions
diff --git a/include/cru/parse/Grammar.hpp b/include/cru/parse/Grammar.hpp index dd4741df..5935e703 100644 --- a/include/cru/parse/Grammar.hpp +++ b/include/cru/parse/Grammar.hpp @@ -21,6 +21,9 @@ class Grammar : public Object { Production* CreateProduction(String name, Nonterminal* left, std::vector<Symbol*> right); + bool RemoveSymbol(Symbol* symbol); + bool RemoveProduction(Production* production); + public: // Getters Nonterminal* GetStartSymbol() const { return start_symbol_; } const std::vector<Terminal*>& GetTerminals() const { return terminals_; } diff --git a/src/parse/Grammar.cpp b/src/parse/Grammar.cpp index 8d929212..a2dd14d4 100644 --- a/src/parse/Grammar.cpp +++ b/src/parse/Grammar.cpp @@ -35,4 +35,38 @@ Production* Grammar::CreateProduction(String name, Nonterminal* left, return production; } +bool Grammar::RemoveSymbol(Symbol* symbol) { + for (auto production : productions_) { + if (production->GetLeft() == symbol) return false; + for (auto s : production->GetRight()) { + if (s == symbol) return false; + } + } + + auto i = std::find(symbols_.begin(), symbols_.end(), symbol); + + if (i == symbols_.cend()) return false; + + symbols_.erase(i); + + if (auto t = dynamic_cast<Terminal*>(symbol)) { + terminals_.erase(std::find(terminals_.begin(), terminals_.end(), t)); + } else if (auto n = dynamic_cast<Nonterminal*>(symbol)) { + nonterminals_.erase( + std::find(nonterminals_.begin(), nonterminals_.end(), n)); + } + + delete symbol; + + return true; +} + +bool Grammar::RemoveProduction(Production* production) { + auto i = std::find(productions_.begin(), productions_.end(), production); + if (i == productions_.cend()) return false; + productions_.erase(i); + delete production; + return true; +} + } // namespace cru::parse |