diff options
author | crupest <crupest@outlook.com> | 2021-09-11 16:31:54 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-09-11 16:31:54 +0800 |
commit | 4511eab66574b8047376a1f612e84e57d2040a95 (patch) | |
tree | dd789dc75ee242f776de5613d0c52453c6f36414 | |
parent | 9e4a90f53ed4260ee8b27c326f0c7e11036e733f (diff) | |
download | cru-4511eab66574b8047376a1f612e84e57d2040a95.tar.gz cru-4511eab66574b8047376a1f612e84e57d2040a95.tar.bz2 cru-4511eab66574b8047376a1f612e84e57d2040a95.zip |
...
-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 |