aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-09-11 16:31:54 +0800
committercrupest <crupest@outlook.com>2021-09-11 16:31:54 +0800
commit4511eab66574b8047376a1f612e84e57d2040a95 (patch)
treedd789dc75ee242f776de5613d0c52453c6f36414
parent9e4a90f53ed4260ee8b27c326f0c7e11036e733f (diff)
downloadcru-4511eab66574b8047376a1f612e84e57d2040a95.tar.gz
cru-4511eab66574b8047376a1f612e84e57d2040a95.tar.bz2
cru-4511eab66574b8047376a1f612e84e57d2040a95.zip
...
-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