aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/parse/Grammar.hpp3
-rw-r--r--src/parse/Grammar.cpp34
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