Skip to content
Snippets Groups Projects
Commit 0f53ef06 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

string parser can parse all grammars

parent 5f791441
No related branches found
No related tags found
No related merge requests found
......@@ -68,11 +68,66 @@ L0:
token.value = "RIGHT_RG";
token.raw = "RIGHT_RG";
return token;
} else if(in.clear(), in >> "LEFT_RG") {
token.type = TokenType::LEFT_RG;
token.value = "LEFT_RG";
token.raw = "LEFT_RG";
return token;
} else if(in.clear(), in >> "RIGHT_LG") {
token.type = TokenType::RIGHT_LG;
token.value = "RIGHT_LG";
token.raw = "RIGHT_LG";
return token;
} else if(in.clear(), in >> "LEFT_LG") {
token.type = TokenType::LEFT_LG;
token.value = "LEFT_LG";
token.raw = "LEFT_LG";
return token;
} else if(in.clear(), in >> "LG") {
token.type = TokenType::LG;
token.value = "LG";
token.raw = "LG";
return token;
} else if(in.clear(), in >> "CFG") {
token.type = TokenType::CFG;
token.value = "CFG";
token.raw = "CFG";
return token;
} else if(in.clear(), in >> "EPSILON_FREE_CFG") {
token.type = TokenType::EPSILON_FREE_CFG;
token.value = "EPSILON_FREE_CFG";
token.raw = "EPSILON_FREE_CFG";
return token;
} else if(in.clear(), in >> "GNF") {
token.type = TokenType::GNF;
token.value = "GNF";
token.raw = "GNF";
return token;
} else if(in.clear(), in >> "CNF") {
token.type = TokenType::CNF;
token.value = "CNF";
token.raw = "CNF";
return token;
} else if(in.clear(), in >> "CSG") {
token.type = TokenType::CSG;
token.value = "CSG";
token.raw = "CSG";
return token;
} else if(in.clear(), in >> "NON_CONTRACTING_GRAMMAR") {
token.type = TokenType::NON_CONTRACTING_GRAMMAR;
token.value = "NON_CONTRACTING_GRAMMAR";
token.raw = "NON_CONTRACTING_GRAMMAR";
return token;
} else if(in.clear(), in >> "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR") {
token.type = TokenType::CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR;
token.value = "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR";
token.raw = "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR";
return token;
} else if(in.clear(), in >> "UNRESTRICTED_GRAMMAR") {
token.type = TokenType::UNRESTRICTED_GRAMMAR;
token.value = "UNRESTRICTED_GRAMMAR";
token.raw = "UNRESTRICTED_GRAMMAR";
return token;
} else {
in.putback(character);
putback(in, std::move(token));
......
......@@ -25,7 +25,18 @@ public:
EPSILON,
MAPS_TO,
RIGHT_RG,
LEFT_RG,
RIGHT_LG,
LEFT_LG,
LG,
CFG,
EPSILON_FREE_CFG,
GNF,
CNF,
CSG,
NON_CONTRACTING_GRAMMAR,
CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR,
UNRESTRICTED_GRAMMAR,
TEOF,
ERROR,
};
......
This diff is collapsed.
......@@ -28,14 +28,35 @@ class GrammarFromStringParser {
GrammarFromStringLexer m_GrammarLexer;
 
std::set<alphabet::Symbol> parseSet(std::istream& input) const;
std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>> parseCFLikeRules(std::istream& input) const;
template<class T> T parseCFLikeGrammar(std::istream& input) const;
std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> parseCSLikeRules(std::istream& input) const;
template<class T> T parseCSLikeGrammar(std::istream& input) const;
std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> parsePreservingCSLikeRules(std::istream& input) const;
template<class T> T parsePreservingCSLikeGrammar(std::istream& input) const;
 
Grammar parseGrammar(std::istream& input) const;
Grammar parseGrammar(std::istream& input, const std::set<FEATURES>& features) const;
 
RightRG parseRightRG(std::istream& input) const;
LeftRG parseLeftRG(std::istream& input) const;
RightLG parseRightLG(std::istream& input) const;
LeftLG parseLeftLG(std::istream& input) const;
LG parseLG(std::istream& input) const;
CFG parseCFG(std::istream& input) const;
EpsilonFreeCFG parseEpsilonFreeCFG(std::istream& input) const;
GNF parseGNF(std::istream& input) const;
CNF parseCNF(std::istream& input) const;
 
NonContractingGrammar parseNonContractingGrammar(std::istream& input) const;
CSG parseCSG(std::istream& input) const;
ContextPreservingUnrestrictedGrammar parseContextPreservingUnrestrictedGrammar(std::istream& input) const;
UnrestrictedGrammar parseUnrestrictedGrammar(std::istream& input) const;
template<typename T> friend class alib::stringApi;
};
 
......
#include "GrammarToStringComposer.h"
#include <sstream>
#include "Regular/RightRG.h"
#include "Regular/RightLG.h"
#include "Regular/LeftRG.h"
#include "Regular/LeftLG.h"
#include "ContextFree/CFG.h"
#include "ContextFree/EpsilonFreeCFG.h"
#include "ContextFree/LG.h"
#include "ContextFree/CNF.h"
#include "ContextFree/GNF.h"
 
#include "../StringApi.hpp"
#include "ContextSensitive/CSG.h"
#include "ContextSensitive/NonContractingGrammar.h"
 
namespace grammar {
#include "Unrestricted/ContextPreservingUnrestrictedGrammar.h"
#include "Unrestricted/UnrestrictedGrammar.h"
 
void GrammarToStringComposer::compose(std::ostream& output, const Grammar& grammar) const {
grammar.getData().Accept((void*) &output, *this);
}
#include "../StringApi.hpp"
 
void GrammarToStringComposer::compose(std::ostream& output, const LeftLG& grammar) const {
// TODO
}
namespace grammar {
 
void GrammarToStringComposer::compose(std::ostream& output, const LeftRG& grammar) const {
// TODO
}
template<class T>
void GrammarToStringComposer::composeCFLikeGrammar(std::ostream& output, const T& grammar) const {
bool first;
 
void GrammarToStringComposer::compose(std::ostream& output, const RightLG& grammar) const {
// TODO
}
output << " (" << std::endl;
 
void GrammarToStringComposer::compose(std::ostream& output, const RightRG& grammar) const {
// TODO
output << "{";
first = false;
for(const auto& symbol : grammar.getNonterminalAlphabet() ) {
if(first)
output << ", ";
else
first = true;
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << "}," << std::endl;
output << "{";
first = false;
for(const auto& symbol : grammar.getTerminalAlphabet() ) {
if(first)
output << ", ";
else
first = true;
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << "}," << std::endl;
output << "{ ";
first = true;
for(const auto& rule : grammar.getRawRules() ) {
if(first)
first = false;
else
output << "," << std::endl << " ";
alib::stringApi<alphabet::Symbol>::compose(output, rule.first);
output << " ->";
bool innerFirst = true;
for(const auto& rhs : rule.second) {
if(innerFirst)
innerFirst = false;
else
output << " |";
for(const auto& symbol : rhs) {
output << " ";
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
}
}
output << "}," << std::endl;
alib::stringApi<alphabet::Symbol>::compose(output, grammar.getInitialSymbol());
output << ")" << std::endl;
}
 
void GrammarToStringComposer::compose(std::ostream& output, const LG& grammar) const {
// TODO
}
template<class T>
void GrammarToStringComposer::composeCSLikeGrammar(std::ostream& output, const T& grammar) const {
bool first;
 
void GrammarToStringComposer::compose(std::ostream& output, const CFG& grammar) const {
// TODO
}
output << " (" << std::endl;
 
void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG& grammar) const {
// TODO
output << "{";
first = false;
for(const auto& symbol : grammar.getNonterminalAlphabet() ) {
if(first)
output << ", ";
else
first = true;
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << "}," << std::endl;
output << "{";
first = false;
for(const auto& symbol : grammar.getTerminalAlphabet() ) {
if(first)
output << ", ";
else
first = true;
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << "}," << std::endl;
output << "{";
first = true;
for(const auto& rule : grammar.getRules() ) {
if(first)
first = false;
else
output << "," << std::endl << " ";
for(const auto& symbol : rule.first) {
output << " ";
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << " ->";
bool innerFirst = true;
for(const auto& rhs : rule.second) {
if(innerFirst)
innerFirst = false;
else
output << " |";
for(const auto& symbol : rhs) {
output << " ";
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
}
}
output << "}," << std::endl;
alib::stringApi<alphabet::Symbol>::compose(output, grammar.getInitialSymbol());
output << ")" << std::endl;
}
 
void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) const {
template<class T>
void GrammarToStringComposer::composePreservingCSLikeGrammar(std::ostream& output, const T& grammar) const {
bool first;
 
output << "CNF (" << std::endl;
output << " (" << std::endl;
 
output << "{";
first = false;
......@@ -63,14 +155,24 @@ void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar)
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << "}," << std::endl;
output << "{ ";
output << "{";
first = true;
for(const auto& rule : grammar.getRawRules() ) {
for(const auto& rule : grammar.getRules() ) {
if(first)
first = false;
else
output << "," << std::endl << " ";
alib::stringApi<alphabet::Symbol>::compose(output, rule.first);
output << "," << std::endl << " ";
for(const auto& symbol : std::get<0>(rule.first)) {
output << " ";
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << " | ";
alib::stringApi<alphabet::Symbol>::compose(output, std::get<1>(rule.first));
output << " |";
for(const auto& symbol : std::get<2>(rule.first)) {
output << " ";
alib::stringApi<alphabet::Symbol>::compose(output, symbol);
}
output << " ->";
bool innerFirst = true;
for(const auto& rhs : rule.second) {
......@@ -89,24 +191,73 @@ void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar)
output << ")" << std::endl;
}
 
void GrammarToStringComposer::compose(std::ostream& output, const Grammar& grammar) const {
grammar.getData().Accept((void*) &output, *this);
}
void GrammarToStringComposer::compose(std::ostream& output, const LeftLG& grammar) const {
output << "LEFT_LG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const LeftRG& grammar) const {
output << "LEFT_RG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const RightLG& grammar) const {
output << "RIGHT_LG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const RightRG& grammar) const {
output << "RIGHT_RG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const LG& grammar) const {
output << "LG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const CFG& grammar) const {
output << "CFG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG& grammar) const {
output << "EPSILON_FREE_CFG";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) const {
output << "CNF";
composeCFLikeGrammar(output, grammar);
}
void GrammarToStringComposer::compose(std::ostream& output, const GNF& grammar) const {
// TODO
output << "GNF";
composeCFLikeGrammar(output, grammar);
}
 
void GrammarToStringComposer::compose(std::ostream& output, const CSG& grammar) const {
// TODO
output << "CSG";
composePreservingCSLikeGrammar(output, grammar);
}
 
void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar& grammar) const {
// TODO
output << "NON_CONTRACTING_GRAMMAR";
composeCSLikeGrammar(output, grammar);
}
 
void GrammarToStringComposer::compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) const {
// TODO
output << "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR";
composePreservingCSLikeGrammar(output, grammar);
}
 
void GrammarToStringComposer::compose(std::ostream& output, const UnrestrictedGrammar& grammar) const {
// TODO
output << "UNRESTRICTED_GRAMMAR";
composeCSLikeGrammar(output, grammar);
}
 
void GrammarToStringComposer::Visit(void* data, const LeftLG& grammar) const {
......
......@@ -25,6 +25,10 @@ class GrammarToStringComposer : public VisitableGrammarBase::const_visitor_type
void Visit(void*, const ContextPreservingUnrestrictedGrammar& grammar) const;
void Visit(void*, const UnrestrictedGrammar& grammar) const;
 
template<class T> void composeCFLikeGrammar(std::ostream& output, const T& grammar) const;
template<class T> void composeCSLikeGrammar(std::ostream& input, const T& grammar) const;
template<class T> void composePreservingCSLikeGrammar(std::ostream& input, const T& grammar) const;
public:
/**
* Prints XML representation of Automaton to the output stream.
......
......@@ -65,9 +65,11 @@ Label LabelFromStringParser::parseLabel(std::istream& input, const std::set<FEAT
return Label(label::LabelPairLabel(std::make_pair(firstLabel, secondLabel)));
}
case LabelFromStringLexer::TokenType::SET_END:
throw exception::AlibException("Unexpected start of Label SET_END.");
case LabelFromStringLexer::TokenType::PAIR_END:
throw exception::AlibException("Unexpected start of Label PAIR_END.");
case LabelFromStringLexer::TokenType::COMMA:
throw exception::AlibException("Unexpected start of Label.");
throw exception::AlibException("Unexpected start of Label COMMA.");
case LabelFromStringLexer::TokenType::ERROR:
if(!features.count(FEATURES::PRIMITIVE)) throw exception::AlibException();
m_Lexer.putback(input, token);
......
......@@ -39,6 +39,63 @@ void GrammarTest::stringParserTest() {
 
grammar::Grammar grammar2 = alib::StringDataFactory::fromString<grammar::Grammar>(output);
 
CPPUNIT_ASSERT( grammar == grammar2 );
}
{
std::string input = "RIGHT_RG (\n"
"{A, B, S},\n"
"{a, b},\n"
"{ A -> a | a A,\n"
" B -> b | b B,\n"
" S -> | a A | a S | b B},\n"
"S)\n";
grammar::Grammar grammar = alib::StringDataFactory::fromString<grammar::Grammar>(input);
std::string output = alib::StringDataFactory::toString(grammar);
std::cout << "\"" << input << "\"" << std::endl << std::endl << "\"" << output << "\"" << std::endl;
CPPUNIT_ASSERT( input == output );
grammar::Grammar grammar2 = alib::StringDataFactory::fromString<grammar::Grammar>(output);
CPPUNIT_ASSERT( grammar == grammar2 );
}
{
std::string input = "NON_CONTRACTING_GRAMMAR (\n"
"{A, B, S},\n"
"{a, b},\n"
"{ A A -> B B | a A,\n"
" B -> b | b B,\n"
" S -> A S | B B | S A},\n"
"S)\n";
grammar::Grammar grammar = alib::StringDataFactory::fromString<grammar::Grammar>(input);
std::string output = alib::StringDataFactory::toString(grammar);
std::cout << "\"" << input << "\"" << std::endl << std::endl << "\"" << output << "\"" << std::endl;
CPPUNIT_ASSERT( input == output );
grammar::Grammar grammar2 = alib::StringDataFactory::fromString<grammar::Grammar>(output);
CPPUNIT_ASSERT( grammar == grammar2 );
}
{
std::string input = "CSG (\n"
"{A, B, S},\n"
"{a, b},\n"
"{ | B | -> b | b B,\n"
" | S | -> A S | B B | S A,\n"
" A | A | -> B B | a A},\n"
"S)\n";
grammar::Grammar grammar = alib::StringDataFactory::fromString<grammar::Grammar>(input);
std::string output = alib::StringDataFactory::toString(grammar);
std::cout << "\"" << input << "\"" << std::endl << std::endl << "\"" << output << "\"" << std::endl;
CPPUNIT_ASSERT( input == output );
grammar::Grammar grammar2 = alib::StringDataFactory::fromString<grammar::Grammar>(output);
CPPUNIT_ASSERT( grammar == grammar2 );
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment