SyntaxTree - Location field
This commit is contained in:
parent
b659f2f237
commit
6f52668540
3 changed files with 95 additions and 57 deletions
|
@ -23,13 +23,16 @@ namespace ebcl {
|
||||||
template<
|
template<
|
||||||
// Node type (should be an enum)
|
// Node type (should be an enum)
|
||||||
typename NodeType ,
|
typename NodeType ,
|
||||||
|
// Location type
|
||||||
|
typename LocationType ,
|
||||||
// Data storage size
|
// Data storage size
|
||||||
size_t InPlaceSize = sizeof( void* )
|
size_t InPlaceSize = sizeof( void* )
|
||||||
> class T_SyntaxTree
|
> class T_SyntaxTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using E_Node = NodeType;
|
using E_Node = NodeType;
|
||||||
using T_Self = T_SyntaxTree< NodeType , InPlaceSize >;
|
using T_Location = LocationType;
|
||||||
|
using T_Self = T_SyntaxTree< NodeType , LocationType , InPlaceSize >;
|
||||||
|
|
||||||
static constexpr size_t StorageSize
|
static constexpr size_t StorageSize
|
||||||
= T_VariantExt< InPlaceSize >::StorageSize;
|
= T_VariantExt< InPlaceSize >::StorageSize;
|
||||||
|
@ -59,6 +62,8 @@ template<
|
||||||
E_Node type;
|
E_Node type;
|
||||||
// Index of the parent node
|
// Index of the parent node
|
||||||
uint32_t parent;
|
uint32_t parent;
|
||||||
|
// Location of the node
|
||||||
|
T_Location location;
|
||||||
// Indices of the node's children
|
// Indices of the node's children
|
||||||
T_AutoArray< uint32_t , 8 > children;
|
T_AutoArray< uint32_t , 8 > children;
|
||||||
// Extra data storage
|
// Extra data storage
|
||||||
|
@ -113,6 +118,9 @@ template<
|
||||||
template< typename D >
|
template< typename D >
|
||||||
D const& dataOf( uint32_t node ) const;
|
D const& dataOf( uint32_t node ) const;
|
||||||
|
|
||||||
|
// Access a node's location
|
||||||
|
T_Location const& locationOf( uint32_t node ) const noexcept;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
// Add a new child, return its index
|
// Add a new child, return its index
|
||||||
|
@ -128,6 +136,9 @@ template<
|
||||||
template< typename D >
|
template< typename D >
|
||||||
D& dataOf( uint32_t node );
|
D& dataOf( uint32_t node );
|
||||||
|
|
||||||
|
// Access a node's location
|
||||||
|
T_Location& locationOf( uint32_t node ) noexcept;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
// Return a visitor suitable for this syntax tree
|
// Return a visitor suitable for this syntax tree
|
||||||
|
@ -137,8 +148,9 @@ template<
|
||||||
T_Node root( ) const noexcept;
|
T_Node root( ) const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
void swap( T_SyntaxTree< T , S >& lhs , T_SyntaxTree< T , S >& rhs ) noexcept;
|
void swap( T_SyntaxTree< T , L , S >& lhs ,
|
||||||
|
T_SyntaxTree< T , L , S >& rhs ) noexcept;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ namespace ebcl {
|
||||||
|
|
||||||
/*= T_SyntaxTree =============================================================*/
|
/*= T_SyntaxTree =============================================================*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||||
T_Self const& tree ,
|
T_Self const& tree ,
|
||||||
const uint32_t node ) noexcept
|
const uint32_t node ) noexcept
|
||||||
: tree{ tree } , node{ node }
|
: tree{ tree } , node{ node }
|
||||||
|
@ -19,34 +19,34 @@ T_SyntaxTree< T , S >::T_Node::T_Node(
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||||
T_Node const& other ) noexcept
|
T_Node const& other ) noexcept
|
||||||
: tree{ other.tree } , node{ other.node }
|
: tree{ other.tree } , node{ other.node }
|
||||||
{
|
{
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||||
T_Node&& other ) noexcept
|
T_Node&& other ) noexcept
|
||||||
: T_Node( other )
|
: T_Node( other )
|
||||||
{
|
{
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
|
||||||
T_SyntaxTree< T , S >::T_Node const& other ) noexcept
|
T_SyntaxTree< T , L , S >::T_Node const& other ) noexcept
|
||||||
{
|
{
|
||||||
assert( &other.tree == &tree );
|
assert( &other.tree == &tree );
|
||||||
node = other.node;
|
node = other.node;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
|
||||||
T_SyntaxTree< T , S >::T_Node&& other ) noexcept
|
T_SyntaxTree< T , L , S >::T_Node&& other ) noexcept
|
||||||
{
|
{
|
||||||
assert( &other.tree == &tree );
|
assert( &other.tree == &tree );
|
||||||
node = other.node;
|
node = other.node;
|
||||||
|
@ -55,31 +55,33 @@ typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
|
||||||
const T nodeType ,
|
const T nodeType ,
|
||||||
const uint32_t parent ) noexcept
|
const uint32_t parent ) noexcept
|
||||||
: type{ nodeType } , parent{ parent }
|
: type{ nodeType } , parent{ parent } , location{ }
|
||||||
{
|
{
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
|
||||||
T_Node_&& other ) noexcept
|
T_Node_&& other ) noexcept
|
||||||
: type{ other.type } , parent{ other.parent } ,
|
: type{ other.type } , parent{ other.parent } ,
|
||||||
|
location{ other.location } ,
|
||||||
children{ std::move( other.children ) } ,
|
children{ std::move( other.children ) } ,
|
||||||
data{ std::move( other.data ) }
|
data{ std::move( other.data ) }
|
||||||
{
|
{
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operator =(
|
typename T_SyntaxTree< T , L , S >::T_Node_& T_SyntaxTree< T , L , S >::T_Node_::operator =(
|
||||||
T_Node_&& other ) noexcept
|
T_Node_&& other ) noexcept
|
||||||
{
|
{
|
||||||
type = other.type;
|
type = other.type;
|
||||||
parent = other.parent;
|
parent = other.parent;
|
||||||
|
location = other.location;
|
||||||
children = std::move( other.children );
|
children = std::move( other.children );
|
||||||
data = std::move( other.data );
|
data = std::move( other.data );
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -87,8 +89,8 @@ typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operato
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_SyntaxTree(
|
T_SyntaxTree< T , L , S >::T_SyntaxTree(
|
||||||
const T rootType ) noexcept
|
const T rootType ) noexcept
|
||||||
: nodes_( 64 )
|
: nodes_( 64 )
|
||||||
{
|
{
|
||||||
|
@ -97,17 +99,17 @@ T_SyntaxTree< T , S >::T_SyntaxTree(
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >::T_SyntaxTree(
|
T_SyntaxTree< T , L , S >::T_SyntaxTree(
|
||||||
T_SyntaxTree< T , S >&& other ) noexcept
|
T_SyntaxTree< T , L , S >&& other ) noexcept
|
||||||
: nodes_{ std::move( other.nodes_ ) }
|
: nodes_{ std::move( other.nodes_ ) }
|
||||||
{
|
{
|
||||||
// EMPTY
|
// EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
|
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::operator =(
|
||||||
T_SyntaxTree< T , S >&& other ) noexcept
|
T_SyntaxTree< T , L , S >&& other ) noexcept
|
||||||
{
|
{
|
||||||
nodes_ = std::move( other.nodes_ );
|
nodes_ = std::move( other.nodes_ );
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -115,64 +117,71 @@ T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::swap(
|
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::swap(
|
||||||
T_SyntaxTree< T , S >& other ) noexcept
|
T_SyntaxTree< T , L , S >& other ) noexcept
|
||||||
{
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap( nodes_ , other.nodes_ );
|
swap( nodes_ , other.nodes_ );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
void swap( T_SyntaxTree< T , S >& lhs ,
|
void swap( T_SyntaxTree< T , L , S >& lhs ,
|
||||||
T_SyntaxTree< T , S >& rhs ) noexcept
|
T_SyntaxTree< T , L , S >& rhs ) noexcept
|
||||||
{
|
{
|
||||||
lhs.swap( rhs );
|
lhs.swap( rhs );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T T_SyntaxTree< T , S >::typeOf(
|
T T_SyntaxTree< T , L , S >::typeOf(
|
||||||
const uint32_t node ) const noexcept
|
const uint32_t node ) const noexcept
|
||||||
{
|
{
|
||||||
return nodes_[ node ].type;
|
return nodes_[ node ].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
uint32_t T_SyntaxTree< T , S >::parentOf(
|
uint32_t T_SyntaxTree< T , L , S >::parentOf(
|
||||||
const uint32_t node ) const noexcept
|
const uint32_t node ) const noexcept
|
||||||
{
|
{
|
||||||
return nodes_[ node ].parent;
|
return nodes_[ node ].parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , S >::childrenOf(
|
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , L , S >::childrenOf(
|
||||||
const uint32_t node ) const noexcept
|
const uint32_t node ) const noexcept
|
||||||
{
|
{
|
||||||
return nodes_[ node ].children;
|
return nodes_[ node ].children;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
bool T_SyntaxTree< T , S >::hasData(
|
bool T_SyntaxTree< T , L , S >::hasData(
|
||||||
const uint32_t node ) const noexcept
|
const uint32_t node ) const noexcept
|
||||||
{
|
{
|
||||||
return bool( nodes_[ node ].data );
|
return bool( nodes_[ node ].data );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
template< typename D >
|
template< typename D >
|
||||||
D const& T_SyntaxTree< T , S >::dataOf(
|
D const& T_SyntaxTree< T , L , S >::dataOf(
|
||||||
const uint32_t node ) const
|
const uint32_t node ) const
|
||||||
{
|
{
|
||||||
return nodes_[ node ].data.template value< D >( );
|
return nodes_[ node ].data.template value< D >( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T , typename L , size_t S >
|
||||||
|
L const& T_SyntaxTree< T , L , S >::locationOf(
|
||||||
|
const uint32_t node ) const noexcept
|
||||||
|
{
|
||||||
|
return nodes_[ node ].location;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
uint32_t T_SyntaxTree< T , S >::addChild(
|
uint32_t T_SyntaxTree< T , L , S >::addChild(
|
||||||
const uint32_t parent ,
|
const uint32_t parent ,
|
||||||
const E_Node type ) noexcept
|
const E_Node type ) noexcept
|
||||||
{
|
{
|
||||||
|
@ -183,9 +192,9 @@ uint32_t T_SyntaxTree< T , S >::addChild(
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
template< typename D , typename ... ArgTypes >
|
template< typename D , typename ... ArgTypes >
|
||||||
D& T_SyntaxTree< T , S >::newData(
|
D& T_SyntaxTree< T , L , S >::newData(
|
||||||
const uint32_t node ,
|
const uint32_t node ,
|
||||||
ArgTypes&& ... args )
|
ArgTypes&& ... args )
|
||||||
{
|
{
|
||||||
|
@ -194,18 +203,25 @@ D& T_SyntaxTree< T , S >::newData(
|
||||||
return data.template value< D >( );
|
return data.template value< D >( );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
template< typename D >
|
template< typename D >
|
||||||
D& T_SyntaxTree< T , S >::dataOf(
|
D& T_SyntaxTree< T , L , S >::dataOf(
|
||||||
const uint32_t node )
|
const uint32_t node )
|
||||||
{
|
{
|
||||||
return nodes_[ node ].data.template value< D >( );
|
return nodes_[ node ].data.template value< D >( );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T , typename L , size_t S >
|
||||||
|
L& T_SyntaxTree< T , L , S >::locationOf(
|
||||||
|
const uint32_t node ) noexcept
|
||||||
|
{
|
||||||
|
return nodes_[ node ].location;
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) const noexcept
|
typename T_SyntaxTree< T , L , S >::T_Visitor T_SyntaxTree< T , L , S >::visitor( ) const noexcept
|
||||||
{
|
{
|
||||||
return T_Visitor{
|
return T_Visitor{
|
||||||
[this]( T_Node node , uint32_t child ) -> T_Optional< T_Node > {
|
[this]( T_Node node , uint32_t child ) -> T_Optional< T_Node > {
|
||||||
|
@ -218,8 +234,8 @@ typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) cons
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T , size_t S >
|
template< typename T , typename L , size_t S >
|
||||||
typename T_SyntaxTree< T , S >::T_Node T_SyntaxTree< T , S >::root( ) const noexcept
|
typename T_SyntaxTree< T , L , S >::T_Node T_SyntaxTree< T , L , S >::root( ) const noexcept
|
||||||
{
|
{
|
||||||
return T_Node{ *this , 0 };
|
return T_Node{ *this , 0 };
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ class SyntaxTreeTest : public CppUnit::TestFixture
|
||||||
CPPUNIT_TEST( testUpdateData );
|
CPPUNIT_TEST( testUpdateData );
|
||||||
CPPUNIT_TEST( testAddChildren );
|
CPPUNIT_TEST( testAddChildren );
|
||||||
CPPUNIT_TEST( testVisit );
|
CPPUNIT_TEST( testVisit );
|
||||||
|
CPPUNIT_TEST( testLocation );
|
||||||
CPPUNIT_TEST_SUITE_END( );
|
CPPUNIT_TEST_SUITE_END( );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -18,6 +19,7 @@ public:
|
||||||
void testUpdateData( );
|
void testUpdateData( );
|
||||||
void testAddChildren( );
|
void testAddChildren( );
|
||||||
void testVisit( );
|
void testVisit( );
|
||||||
|
void testLocation( );
|
||||||
};
|
};
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
|
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ enum class E_TestNode_
|
||||||
VALUE
|
VALUE
|
||||||
};
|
};
|
||||||
|
|
||||||
using T_Test_ = T_SyntaxTree< E_TestNode_ >;
|
using T_Test_ = T_SyntaxTree< E_TestNode_ , uint32_t >;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -139,3 +141,11 @@ void SyntaxTreeTest::testVisit( )
|
||||||
CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) );
|
CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) );
|
||||||
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) );
|
CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SyntaxTreeTest::testLocation( )
|
||||||
|
{
|
||||||
|
T_Test_ st{ E_TestNode_::ROOT };
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 0u , st.locationOf( 0 ) );
|
||||||
|
st.locationOf( 0 ) = 123;
|
||||||
|
CPPUNIT_ASSERT_EQUAL( 123u , st.locationOf( 0 ) );
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue