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

another test of absorbTerminalSymbol algorithm

parent ed4281a9
Branches
Tags
No related merge requests found
...@@ -14,18 +14,30 @@ namespace grammar { ...@@ -14,18 +14,30 @@ namespace grammar {
   
namespace parsing { namespace parsing {
   
alphabet::Symbol AbsorbTerminalSymbol::handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & nonterminal, const alphabet::Symbol & terminal ) { void AbsorbTerminalSymbol::handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, alphabet::Symbol > & nonterminalsPrimed ) {
alphabet::Symbol newSymbol = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( nonterminal, terminal ) ) ), res.getTerminalAlphabet ( ), res.getNonterminalAlphabet ( ) ); for ( const alphabet::Symbol & nonterminal : nonterminals )
for ( const std::vector < alphabet::Symbol > & rhs : orig.getRules ( ).find ( nonterminal )->second ) {
std::vector < alphabet::Symbol > newRHS;
   
res.addNonterminalSymbol ( newSymbol ); for ( std::vector < alphabet::Symbol >::const_iterator iter = rhs.begin ( ); iter != rhs.end ( ); ++iter ) {
if ( nonterminals.count ( * iter ) && ( ( iter + 1 == rhs.end ( ) ) || ( terminal == * ( iter + 1 ) ) ) ) {
newRHS.push_back ( nonterminalsPrimed.find ( * iter )->second );
   
for ( const std::vector < alphabet::Symbol > & rhs : orig.getRules ( ).find ( nonterminal )->second ) { if ( iter + 1 != rhs.end ( ) ) ++iter;
std::vector < alphabet::Symbol > newRHS ( rhs.begin ( ), rhs.end ( ) ); } else if ( iter + 1 == rhs.end ( ) ) {
newRHS.push_back ( terminal ); newRHS.push_back ( * iter );
res.addRule ( newSymbol, newRHS ); newRHS.push_back ( terminal );
} } else {
newRHS.push_back ( * iter );
}
}
if ( rhs.size ( ) == 0 )
newRHS.push_back ( terminal );
res.addRule ( nonterminalsPrimed.find ( nonterminal )->second, newRHS );
}
   
return newSymbol;
} }
   
void AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) { void AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ) {
...@@ -37,10 +49,13 @@ void AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar::CFG & grammar, const ...@@ -37,10 +49,13 @@ void AbsorbTerminalSymbol::absorbTerminalSymbol ( grammar::CFG & grammar, const
std::map < alphabet::Symbol, alphabet::Symbol > nonterminalsPrimed; // terminal is fixed in particular calls std::map < alphabet::Symbol, alphabet::Symbol > nonterminalsPrimed; // terminal is fixed in particular calls
   
for ( const alphabet::Symbol & nonterminal : nonterminals ) { for ( const alphabet::Symbol & nonterminal : nonterminals ) {
alphabet::Symbol newSymbol = handleAbsobtion ( grammar, res, nonterminal, terminal ); alphabet::Symbol newSymbol = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( nonterminal, terminal ) ) ), res.getTerminalAlphabet ( ), res.getNonterminalAlphabet ( ) );
res.addNonterminalSymbol ( newSymbol );
nonterminalsPrimed.insert ( std::make_pair ( nonterminal, newSymbol ) ); nonterminalsPrimed.insert ( std::make_pair ( nonterminal, newSymbol ) );
} }
   
handleAbsobtion ( grammar, res, terminal, nonterminals, nonterminalsPrimed );
for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) { for ( const std::pair < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rule : grammar.getRules ( ) ) {
const alphabet::Symbol & lhs = rule.first; const alphabet::Symbol & lhs = rule.first;
   
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <grammar/GrammarFeatures.h> #include <grammar/GrammarFeatures.h>
#include <alphabet/Symbol.h> #include <alphabet/Symbol.h>
#include <set> #include <set>
#include <map>
   
namespace grammar { namespace grammar {
   
...@@ -18,10 +19,9 @@ namespace parsing { ...@@ -18,10 +19,9 @@ namespace parsing {
   
class AbsorbTerminalSymbol { class AbsorbTerminalSymbol {
public: public:
static alphabet::Symbol handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & nonterminal, const alphabet::Symbol & terminal ); static void handleAbsobtion ( const grammar::CFG & orig, grammar::CFG & res, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals, const std::map < alphabet::Symbol, alphabet::Symbol > & nonterminalPrimed );
   
static void absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals ); static void absorbTerminalSymbol ( grammar::CFG & grammar, const alphabet::Symbol & terminal, const std::set < alphabet::Symbol > & nonterminals );
}; };
   
} /* namespace parsing */ } /* namespace parsing */
......
...@@ -60,4 +60,96 @@ void AbsorbTerminalSymbol::testAbsorbTerminalSymbol ( ) { ...@@ -60,4 +60,96 @@ void AbsorbTerminalSymbol::testAbsorbTerminalSymbol ( ) {
} }
   
void AbsorbTerminalSymbol::testAbsorbTerminalSymbol2 ( ) { void AbsorbTerminalSymbol::testAbsorbTerminalSymbol2 ( ) {
alphabet::Symbol A = alphabet::symbolFrom ( "A" );
alphabet::Symbol B = alphabet::symbolFrom ( "B" );
alphabet::Symbol C = alphabet::symbolFrom ( "C" );
alphabet::Symbol X = alphabet::symbolFrom ( "X" );
alphabet::Symbol a = alphabet::symbolFrom ( 'a' );
alphabet::Symbol b = alphabet::symbolFrom ( 'b' );
alphabet::Symbol c = alphabet::symbolFrom ( 'c' );
alphabet::Symbol Ba = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( B, a ) ) ), { }, { } );
alphabet::Symbol Xa = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( X, a ) ) ), { }, { } );
grammar::CFG grammar ( A );
grammar.setTerminalAlphabet ( { a, b, c } );
grammar.setNonterminalAlphabet ( { A, B, C, X } );
grammar.setInitialSymbol ( A );
grammar.addRule ( A, { X, a, C } );
grammar.addRule ( X, { c, B } );
grammar.addRule ( B, { } );
grammar.addRule ( B, { a, a, C } );
grammar.addRule ( C, { c } );
grammar.addRule ( C, { b, C } );
grammar::CFG res = grammar;
grammar::parsing::AbsorbTerminalSymbol::absorbTerminalSymbol ( res, a, { B, X } );
grammar::CFG comp ( A );
comp.setTerminalAlphabet ( { a, b, c } );
comp.setNonterminalAlphabet ( { A, B, Ba, C, X, Xa } );
comp.setInitialSymbol ( A );
comp.addRule ( A, { Xa, C } );
comp.addRule ( X, { c, B } );
comp.addRule ( Xa, { c, Ba } );
comp.addRule ( B, { } );
comp.addRule ( B, { a, a, C } );
comp.addRule ( Ba, { a } );
comp.addRule ( Ba, { a, a, C, a } );
comp.addRule ( C, { c } );
comp.addRule ( C, { b, C } );
std::cout << "res " << alib::StringDataFactory::toString ( grammar::Grammar ( res ) ) << std::endl << "comp " << alib::StringDataFactory::toString ( grammar::Grammar ( comp ) ) << std::endl;
CPPUNIT_ASSERT ( res == comp );
}
void AbsorbTerminalSymbol::testAbsorbTerminalSymbol3 ( ) {
alphabet::Symbol A = alphabet::symbolFrom ( "A" );
alphabet::Symbol B = alphabet::symbolFrom ( "B" );
alphabet::Symbol C = alphabet::symbolFrom ( "C" );
alphabet::Symbol a = alphabet::symbolFrom ( 'a' );
alphabet::Symbol b = alphabet::symbolFrom ( 'b' );
alphabet::Symbol c = alphabet::symbolFrom ( 'c' );
alphabet::Symbol Ba = alphabet::createUniqueSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( B, a ) ) ), { }, { } );
grammar::CFG grammar ( A );
grammar.setTerminalAlphabet ( { a, b, c } );
grammar.setNonterminalAlphabet ( { A, B, C } );
grammar.setInitialSymbol ( A );
grammar.addRule ( A, { B, a, C } );
grammar.addRule ( B, { } );
grammar.addRule ( B, { a, a, B } );
grammar.addRule ( C, { c } );
grammar.addRule ( C, { b, C } );
grammar::CFG res = grammar;
grammar::parsing::AbsorbTerminalSymbol::absorbTerminalSymbol ( res, a, { B } );
grammar::CFG comp ( A );
comp.setTerminalAlphabet ( { a, b, c } );
comp.setNonterminalAlphabet ( { A, B, Ba, C } );
comp.setInitialSymbol ( A );
comp.addRule ( A, { Ba, C } );
comp.addRule ( B, { } );
comp.addRule ( B, { a, a, B } );
comp.addRule ( Ba, { a } );
comp.addRule ( Ba, { a, a, Ba } );
comp.addRule ( C, { c } );
comp.addRule ( C, { b, C } );
std::cout << alib::StringDataFactory::toString ( grammar::Grammar ( res ) ) << std::endl << alib::StringDataFactory::toString ( grammar::Grammar ( comp ) ) << std::endl;
CPPUNIT_ASSERT ( res == comp );
} }
...@@ -7,6 +7,7 @@ class AbsorbTerminalSymbol : public CppUnit::TestFixture { ...@@ -7,6 +7,7 @@ class AbsorbTerminalSymbol : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE ( AbsorbTerminalSymbol ); CPPUNIT_TEST_SUITE ( AbsorbTerminalSymbol );
CPPUNIT_TEST ( testAbsorbTerminalSymbol ); CPPUNIT_TEST ( testAbsorbTerminalSymbol );
CPPUNIT_TEST ( testAbsorbTerminalSymbol2 ); CPPUNIT_TEST ( testAbsorbTerminalSymbol2 );
CPPUNIT_TEST ( testAbsorbTerminalSymbol3 );
CPPUNIT_TEST_SUITE_END ( ); CPPUNIT_TEST_SUITE_END ( );
   
public: public:
...@@ -15,6 +16,7 @@ public: ...@@ -15,6 +16,7 @@ public:
   
void testAbsorbTerminalSymbol ( ); void testAbsorbTerminalSymbol ( );
void testAbsorbTerminalSymbol2 ( ); void testAbsorbTerminalSymbol2 ( );
void testAbsorbTerminalSymbol3 ( );
}; };
   
#endif /* ABSORB_TERMINAL_SYMBOL_TEST_H_ */ #endif /* ABSORB_TERMINAL_SYMBOL_TEST_H_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment