Syntax tree - Visitors

Syntax trees can return a pre-configured visitor object that can be used
to visit all the nodes. Also added a method to create a "root node"
handle for the visitor, because I'm a lazy bastard.
This commit is contained in:
Emmanuel BENOîT 2018-03-31 22:11:00 +02:00
parent a9762a901e
commit b659f2f237
3 changed files with 159 additions and 1 deletions

View file

@ -9,6 +9,7 @@ class SyntaxTreeTest : public CppUnit::TestFixture
CPPUNIT_TEST( testSetData );
CPPUNIT_TEST( testUpdateData );
CPPUNIT_TEST( testAddChildren );
CPPUNIT_TEST( testVisit );
CPPUNIT_TEST_SUITE_END( );
public:
@ -16,6 +17,7 @@ public:
void testSetData( );
void testUpdateData( );
void testAddChildren( );
void testVisit( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
@ -75,3 +77,65 @@ void SyntaxTreeTest::testAddChildren( )
CPPUNIT_ASSERT_EQUAL( cc , st.childrenOf( rc )[ 0 ] );
CPPUNIT_ASSERT( E_TestNode_::VALUE == st.typeOf( cc ) );
}
void SyntaxTreeTest::testVisit( )
{
T_Test_ st{ E_TestNode_::ROOT };
const uint32_t c0{ st.addChild( 0 , E_TestNode_::ADD ) };
const uint32_t c1{ st.addChild( c0 , E_TestNode_::VALUE ) };
const uint32_t c2{ st.addChild( c0 , E_TestNode_::VALUE ) };
st.newData< uint32_t >( c1 , 12u );
st.newData< uint32_t >( c2 , 42u );
using T_Result_ = std::tuple< bool , uint32_t , T_Optional< uint32_t > >;
T_Array< T_Result_ > visitData;
st.visitor( ).visit( st.root( ) ,
[&visitData]( T_Test_::T_Node node , bool after ) {
//fprintf( stderr , "NODE %d (%c)\n" , node.node , after ? 'O' : 'I' );
visitData.add( std::make_tuple( !after , node.node ,
node.tree.hasData( node.node )
? T_Optional< uint32_t >( node.tree.dataOf< uint32_t >( node.node ) )
: T_Optional< uint32_t >() ) );
return true;
} );
// ROOT <-- ADD <-- VALUE{12}
// <-- VALUE{42}
CPPUNIT_ASSERT_EQUAL( 8u , visitData.size( ) );
CPPUNIT_ASSERT( std::get< 0 >( visitData[ 0 ] ) );
CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 0 ] ) );
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 0 ] ) );
CPPUNIT_ASSERT( std::get< 0 >( visitData[ 1 ] ) );
CPPUNIT_ASSERT_EQUAL( c0 , std::get< 1 >( visitData[ 1 ] ) );
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 1 ] ) );
CPPUNIT_ASSERT( std::get< 0 >( visitData[ 2 ] ) );
CPPUNIT_ASSERT_EQUAL( c1 , std::get< 1 >( visitData[ 2 ] ) );
CPPUNIT_ASSERT( std::get< 2 >( visitData[ 2 ] ) );
CPPUNIT_ASSERT_EQUAL( 12u , *std::get< 2 >( visitData[ 2 ] ) );
CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 3 ] ) );
CPPUNIT_ASSERT_EQUAL( c1 , std::get< 1 >( visitData[ 3 ] ) );
CPPUNIT_ASSERT( std::get< 2 >( visitData[ 3 ] ) );
CPPUNIT_ASSERT_EQUAL( 12u , *std::get< 2 >( visitData[ 3 ] ) );
CPPUNIT_ASSERT( std::get< 0 >( visitData[ 4 ] ) );
CPPUNIT_ASSERT_EQUAL( c2 , std::get< 1 >( visitData[ 4 ] ) );
CPPUNIT_ASSERT( std::get< 2 >( visitData[ 4 ] ) );
CPPUNIT_ASSERT_EQUAL( 42u , *std::get< 2 >( visitData[ 4 ] ) );
CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 5 ] ) );
CPPUNIT_ASSERT_EQUAL( c2 , std::get< 1 >( visitData[ 5 ] ) );
CPPUNIT_ASSERT( std::get< 2 >( visitData[ 5 ] ) );
CPPUNIT_ASSERT_EQUAL( 42u , *std::get< 2 >( visitData[ 5 ] ) );
CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 6 ] ) );
CPPUNIT_ASSERT_EQUAL( c0 , std::get< 1 >( visitData[ 6 ] ) );
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) );
CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 7 ] ) );
CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) );
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) );
}