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

ContextPreservingUnrestrictedGrammar internal form

parent 00ea07ce
No related branches found
No related tags found
No related merge requests found
......@@ -416,9 +416,11 @@ void GrammarFromXMLParser::parseRule(std::list<sax::Token>& input, UnrestrictedG
}
 
void GrammarFromXMLParser::parseRule(std::list<sax::Token>& input, ContextPreservingUnrestrictedGrammar& grammar) const {
std::vector<alphabet::Symbol> lhs = parseRuleLHS(input);
std::vector<alphabet::Symbol> lContext = parseRuleLContext(input);
alphabet::Symbol lhs = parseRuleSingleSymbolLHS(input);
std::vector<alphabet::Symbol> rContext = parseRuleRContext(input);
std::vector<alphabet::Symbol> rhs = parseRuleRHS(input);
grammar.addRule(lhs, rhs);
grammar.addRule(lContext, lhs, rContext, rhs);
}
 
void GrammarFromXMLParser::parseRule(std::list<sax::Token>& input, NonContractingGrammar& grammar) const {
......
......@@ -290,7 +290,9 @@ void GrammarToXMLComposer::composeRules(std::list<sax::Token>& out, const Contex
for(const auto& rhs : rule.second) {
out.push_back(sax::Token("rule", sax::Token::TokenType::START_ELEMENT));
 
composeRuleLHS(out, rule.first);
composeRuleLContext(out, std::get<0>(rule.first));
composeRuleSingleSymbolLHS(out, std::get<1>(rule.first));
composeRuleRContext(out, std::get<2>(rule.first));
composeRuleRHS(out, rhs);
 
out.push_back(sax::Token("rule", sax::Token::TokenType::END_ELEMENT));
......
......@@ -32,9 +32,14 @@ GrammarBase* ContextPreservingUnrestrictedGrammar::plunder() && {
}
 
bool ContextPreservingUnrestrictedGrammar::removeTerminalSymbol(const alphabet::Symbol& symbol) {
for(const std::pair<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
if(std::find(rule.first.begin(), rule.first.end(), symbol) != rule.first.end())
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
for(const std::pair<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
for(const alphabet::Symbol& lCont : std::get<0>(rule.first))
if(lCont == symbol)
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
for(const alphabet::Symbol& rCont : std::get<2>(rule.first))
if(rCont == symbol)
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
 
for(const std::vector<alphabet::Symbol>& rhs : rule.second)
if(std::find(rhs.begin(), rhs.end(), symbol) != rhs.end())
......@@ -45,10 +50,18 @@ bool ContextPreservingUnrestrictedGrammar::removeTerminalSymbol(const alphabet::
}
 
bool ContextPreservingUnrestrictedGrammar::removeNonterminalSymbol(const alphabet::Symbol& symbol) {
for(const std::pair<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
if(std::find(rule.first.begin(), rule.first.end(), symbol) != rule.first.end())
for(const std::pair<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
for(const alphabet::Symbol& lCont : std::get<0>(rule.first))
if(lCont == symbol)
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
if(std::get<1>(rule.first) == symbol)
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
 
for(const alphabet::Symbol& rCont : std::get<2>(rule.first))
if(rCont == symbol)
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
for(const std::vector<alphabet::Symbol>& rhs : rule.second)
if(std::find(rhs.begin(), rhs.end(), symbol) != rhs.end())
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is used in rule.");
......@@ -61,45 +74,34 @@ bool ContextPreservingUnrestrictedGrammar::removeNonterminalSymbol(const alphabe
return nonterminalAlphabet.erase(symbol);
}
 
bool ContextPreservingUnrestrictedGrammar::addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
int lSize = leftHandSide.size();
int rSize = rightHandSide.size();
if(lSize > rSize + 1)
throw GrammarException("Invalid size of right hand side of a rule");
int lContext;
int rContext;
for(lContext = 0; lContext < lSize - 1 && leftHandSide[lContext] == rightHandSide[lContext]; lContext++);
for(rContext = 0; rContext < lSize - 1 && leftHandSide[lSize - rContext] == rightHandSide[rSize - rContext]; rContext++);
if(lContext + rContext + 1 < lSize) {
throw GrammarException("Rule must rewrite only one symbol");
} else
if(lContext + rContext + 1 == lSize) {
if(!nonterminalAlphabet.count(leftHandSide[lContext - 1]) && !nonterminalAlphabet.count(leftHandSide[lSize - rContext])) throw GrammarException("Rule must rewrite nonterminal symbol");
} else
if(/* lContext + rContext + 1 > lSize */ std::all_of(leftHandSide.end() - rContext, leftHandSide.begin() + lContext + 1, [&](const alphabet::Symbol symbol) {return !nonterminalAlphabet.count(symbol);}))
throw GrammarException("Rule must rewrite nonterminal symbol");
bool ContextPreservingUnrestrictedGrammar::addRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide) {
for(const alphabet::Symbol& symbol : lContext) {
if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
}
 
if(!nonterminalAlphabet.count(leftHandSide))
throw GrammarException("Rule must rewrite nonterminal symbol");
 
for(const alphabet::Symbol& symbol : leftHandSide)
for(const alphabet::Symbol& symbol : rContext) {
if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
}
 
for(const alphabet::Symbol& symbol : rightHandSide)
for(const alphabet::Symbol& symbol : rightHandSide) {
if(terminalAlphabet.find(symbol) == terminalAlphabet.end() && nonterminalAlphabet.find(symbol) == nonterminalAlphabet.end())
throw GrammarException("Symbol \"" + (std::string) symbol.getSymbol() + "\" is not neither terminal nor nonterminal symbol");
}
 
return rules[leftHandSide].insert(rightHandSide).second;
return rules[make_tuple(lContext, leftHandSide, rContext)].insert(rightHandSide).second;
}
 
const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> ContextPreservingUnrestrictedGrammar::getRules() const {
const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> ContextPreservingUnrestrictedGrammar::getRules() const {
return rules;
}
 
bool ContextPreservingUnrestrictedGrammar::removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide) {
return rules[leftHandSide].erase(rightHandSide);
bool ContextPreservingUnrestrictedGrammar::removeRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide) {
return rules[make_tuple(lContext, leftHandSide, rContext)].erase(rightHandSide);
}
 
bool ContextPreservingUnrestrictedGrammar::operator==(const GrammarBase& other) const {
......
......@@ -16,11 +16,10 @@
namespace grammar {
 
/**
* Context preserving unrestricted grammar. Type 0 in Chomsky hierarchy. Produces recursively enumerable language.
* Epsilon free context free grammar. Type 2 in Chomsky hierarchy. Produces context free languages.
*/
class ContextPreservingUnrestrictedGrammar : public std::element<ContextPreservingUnrestrictedGrammar, GrammarBase>, public TerminalNonterminalAlphabetInitialSymbol {
std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> rules;
std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> rules;
public:
ContextPreservingUnrestrictedGrammar(const alphabet::Symbol& initialSymbol);
 
......@@ -30,11 +29,11 @@ public:
 
virtual GrammarBase* plunder() &&;
 
bool addRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
bool addRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
const std::map<std::vector<alphabet::Symbol>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
const std::map<std::tuple<std::vector<alphabet::Symbol>, alphabet::Symbol, std::vector<alphabet::Symbol>>, std::set<std::vector<alphabet::Symbol>>> getRules() const;
 
bool removeRule(const std::vector<alphabet::Symbol>& leftHandSide, const std::vector<alphabet::Symbol>& rightHandSide);
bool removeRule(const std::vector<alphabet::Symbol>& lContext, const alphabet::Symbol& leftHandSide, const std::vector<alphabet::Symbol>& rContext, const std::vector<alphabet::Symbol>& rightHandSide);
 
bool removeTerminalSymbol(const alphabet::Symbol& symbol);
 
......
......@@ -86,6 +86,35 @@ void GrammarTest::testUnrestrictedParser() {
 
CPPUNIT_ASSERT( grammar == grammar2 );
}
{
grammar::ContextPreservingUnrestrictedGrammar grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))));
grammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))));
grammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))));
grammar.addNonterminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3)))));
grammar.addTerminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
grammar.addTerminalSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
grammar.addRule(std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))}, alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))), std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))}, std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))});
grammar.addRule(std::vector<alphabet::Symbol> {}, alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::vector<alphabet::Symbol> {}, std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3))))});
grammar.addRule(std::vector<alphabet::Symbol> {}, alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))), std::vector<alphabet::Symbol> {}, std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(3))))});
grammar.addRule(std::vector<alphabet::Symbol> {}, alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(1)))), std::vector<alphabet::Symbol> {}, std::vector<alphabet::Symbol> {alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2))))});
grammar.addRule(std::vector<alphabet::Symbol> {}, alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::IntegerLabel(2)))), std::vector<alphabet::Symbol> {}, std::vector<alphabet::Symbol> {});
CPPUNIT_ASSERT( grammar == grammar );
{
grammar::GrammarToXMLComposer composer;
std::list<sax::Token> tokens = composer.compose(grammar);
std::string tmp;
sax::SaxComposeInterface::printMemory(tmp, tokens);
std::list<sax::Token> tokens2;
sax::SaxParseInterface::parseMemory(tmp, tokens2);
grammar::GrammarFromXMLParser parser;
grammar::ContextPreservingUnrestrictedGrammar grammar2 = parser.parseContextPreservingUnrestrictedGrammar(tokens2);
CPPUNIT_ASSERT( grammar == grammar2 );
}
}
}
 
void GrammarTest::testRegularParser() {
......
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