From b89c3cbebb565411a04cb7a8ec536373db454696 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 14 Jul 2014 10:01:08 +0200
Subject: [PATCH] Composers for grammars

---
 alib2/src/grammar/GrammarToXMLComposer.cpp | 302 +++++++++++++++++++++
 alib2/src/grammar/GrammarToXMLComposer.h   |  13 +
 2 files changed, 315 insertions(+)

diff --git a/alib2/src/grammar/GrammarToXMLComposer.cpp b/alib2/src/grammar/GrammarToXMLComposer.cpp
index 781b5a160f..81ad4b5c3f 100644
--- a/alib2/src/grammar/GrammarToXMLComposer.cpp
+++ b/alib2/src/grammar/GrammarToXMLComposer.cpp
@@ -40,64 +40,157 @@ std::list<sax::Token> GrammarToXMLComposer::compose(const UnknownGrammar& gramma
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const LeftLG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("LeftLG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
 
+	out.push_back(sax::Token("LeftLG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const LeftRG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("LeftRG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
 
+	out.push_back(sax::Token("LeftRG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const RightLG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("RightLG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
 
+	out.push_back(sax::Token("RightLG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const RightRG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("RightRG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("RightRG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const LG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("LG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("LG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const CFG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("CFG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("CFG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const EpsilonFreeCFG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("EpsilonFreeCFG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("EpsilonFreeCFG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const CNF& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("CNF", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("CNF", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const GNF& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("GNF", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("GNF", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const CSG& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("CSG", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("CSG", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const NonContractingGrammar& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("NonContractingGrammar", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("NonContractingGrammar", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
 std::list<sax::Token> GrammarToXMLComposer::compose(const ContextPreservingUnrestrictedGrammar& grammar) const {
 	std::list<sax::Token> out;
+	out.push_back(sax::Token("ContextPreservingUnrestrictedGrammar", sax::Token::TokenType::START_ELEMENT));
+	
+	composeNonterminalAlphabet(out, grammar.getNonterminalAlphabet());
+	composeTerminalAlphabet(out, grammar.getTerminalAlphabet());
+	composeInitialSymbol(out, grammar.getInitialSymbol());
+	composeRules(out, grammar);
+
+	out.push_back(sax::Token("ContextPreservingUnrestrictedGrammar", sax::Token::TokenType::END_ELEMENT));
 	return out;
 }
 
@@ -162,7 +255,210 @@ void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const Unrest
 			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
 
 			composeRuleLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const ContextPreservingUnrestrictedGrammar& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const NonContractingGrammar& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const CSG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const GNF& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
 
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const CNF& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const EpsilonFreeCFG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const CFG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const LG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const RightLG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const RightRG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const LeftLG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
+			composeRuleRHS(out, rhs);
+
+			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
+		}
+	}
+
+	out.push_back(sax::Token("rules", sax::Token::TokenType::END_ELEMENT));
+}
+
+void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const LeftRG& grammar) const {
+	out.push_back(sax::Token("rules", sax::Token::TokenType::START_ELEMENT));
+	for (const auto& rule : grammar.getRules()) {
+
+		for(const auto& rhs : rule.second) {
+			out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
+
+			composeRuleSingleSymbolLHS(out, rule.first);
 			composeRuleRHS(out, rhs);
 
 			out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
@@ -180,6 +476,12 @@ void GrammarToXMLComposer::composeRuleLHS(std::list<sax::Token>& out, const std:
 	out.push_back(sax::Token("lhs", sax::Token::TokenType::END_ELEMENT));
 }
 
+void GrammarToXMLComposer::composeRuleSingleSymbolLHS(std::list<sax::Token>& out, const alphabet::Symbol& symbol) const {
+	out.push_back(sax::Token("lhs", sax::Token::TokenType::START_ELEMENT));
+	out.splice(out.end(), alib::ToXMLComposers::symbolComposer.compose(symbol));
+	out.push_back(sax::Token("lhs", sax::Token::TokenType::END_ELEMENT));
+}
+
 void GrammarToXMLComposer::composeRuleRHS(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols) const {
 	out.push_back(sax::Token("rhs", sax::Token::TokenType::START_ELEMENT));
 	for (const auto& symbol : symbols) {
diff --git a/alib2/src/grammar/GrammarToXMLComposer.h b/alib2/src/grammar/GrammarToXMLComposer.h
index 5cb9860203..489595c1e9 100644
--- a/alib2/src/grammar/GrammarToXMLComposer.h
+++ b/alib2/src/grammar/GrammarToXMLComposer.h
@@ -55,8 +55,21 @@ class GrammarToXMLComposer : public GrammarBase::const_visitor_type {
 	
 	void composeRules(std::list<sax::Token>& out, const UnknownGrammar& grammar) const;
 	void composeRules(std::list<sax::Token>& out, const UnrestrictedGrammar& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const ContextPreservingUnrestrictedGrammar& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const NonContractingGrammar& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const CSG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const GNF& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const CNF& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const EpsilonFreeCFG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const CFG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const LG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const LeftLG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const LeftRG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const RightLG& grammar) const;
+	void composeRules(std::list<sax::Token>& out, const RightRG& grammar) const;
 
 	void composeRuleLHS(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols) const;
+	void composeRuleSingleSymbolLHS(std::list<sax::Token>& out, const alphabet::Symbol& symbols) const;
 	void composeRuleRHS(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols) const;
 public:
 	/**
-- 
GitLab