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<
|
||||
// Node type (should be an enum)
|
||||
typename NodeType ,
|
||||
// Location type
|
||||
typename LocationType ,
|
||||
// Data storage size
|
||||
size_t InPlaceSize = sizeof( void* )
|
||||
> class T_SyntaxTree
|
||||
{
|
||||
public:
|
||||
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
|
||||
= T_VariantExt< InPlaceSize >::StorageSize;
|
||||
|
@ -59,6 +62,8 @@ template<
|
|||
E_Node type;
|
||||
// Index of the parent node
|
||||
uint32_t parent;
|
||||
// Location of the node
|
||||
T_Location location;
|
||||
// Indices of the node's children
|
||||
T_AutoArray< uint32_t , 8 > children;
|
||||
// Extra data storage
|
||||
|
@ -113,6 +118,9 @@ template<
|
|||
template< typename D >
|
||||
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
|
||||
|
@ -128,6 +136,9 @@ template<
|
|||
template< typename D >
|
||||
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
|
||||
|
@ -137,8 +148,9 @@ template<
|
|||
T_Node root( ) const noexcept;
|
||||
};
|
||||
|
||||
template< typename T , size_t S >
|
||||
void swap( T_SyntaxTree< T , S >& lhs , T_SyntaxTree< T , S >& rhs ) noexcept;
|
||||
template< typename T , typename L , size_t S >
|
||||
void swap( T_SyntaxTree< T , L , S >& lhs ,
|
||||
T_SyntaxTree< T , L , S >& rhs ) noexcept;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ namespace ebcl {
|
|||
|
||||
/*= T_SyntaxTree =============================================================*/
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||
T_Self const& tree ,
|
||||
const uint32_t node ) noexcept
|
||||
: tree{ tree } , node{ node }
|
||||
|
@ -19,34 +19,34 @@ T_SyntaxTree< T , S >::T_Node::T_Node(
|
|||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||
T_Node const& other ) noexcept
|
||||
: tree{ other.tree } , node{ other.node }
|
||||
{
|
||||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >::T_Node::T_Node(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_Node::T_Node(
|
||||
T_Node&& other ) noexcept
|
||||
: T_Node( other )
|
||||
{
|
||||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
||||
T_SyntaxTree< T , S >::T_Node const& other ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
|
||||
T_SyntaxTree< T , L , S >::T_Node const& other ) noexcept
|
||||
{
|
||||
assert( &other.tree == &tree );
|
||||
node = other.node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
typename T_SyntaxTree< T , S >::T_Node& T_SyntaxTree< T , S >::T_Node::operator =(
|
||||
T_SyntaxTree< T , S >::T_Node&& other ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
typename T_SyntaxTree< T , L , S >::T_Node& T_SyntaxTree< T , L , S >::T_Node::operator =(
|
||||
T_SyntaxTree< T , L , S >::T_Node&& other ) noexcept
|
||||
{
|
||||
assert( &other.tree == &tree );
|
||||
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 >
|
||||
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
|
||||
const T nodeType ,
|
||||
const uint32_t parent ) noexcept
|
||||
: type{ nodeType } , parent{ parent }
|
||||
: type{ nodeType } , parent{ parent } , location{ }
|
||||
{
|
||||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >::T_Node_::T_Node_(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_Node_::T_Node_(
|
||||
T_Node_&& other ) noexcept
|
||||
: type{ other.type } , parent{ other.parent } ,
|
||||
location{ other.location } ,
|
||||
children{ std::move( other.children ) } ,
|
||||
data{ std::move( other.data ) }
|
||||
{
|
||||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
typename T_SyntaxTree< T , S >::T_Node_& T_SyntaxTree< T , S >::T_Node_::operator =(
|
||||
template< typename T , typename L , size_t S >
|
||||
typename T_SyntaxTree< T , L , S >::T_Node_& T_SyntaxTree< T , L , S >::T_Node_::operator =(
|
||||
T_Node_&& other ) noexcept
|
||||
{
|
||||
type = other.type;
|
||||
parent = other.parent;
|
||||
location = other.location;
|
||||
children = std::move( other.children );
|
||||
data = std::move( other.data );
|
||||
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 >
|
||||
T_SyntaxTree< T , S >::T_SyntaxTree(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_SyntaxTree(
|
||||
const T rootType ) noexcept
|
||||
: nodes_( 64 )
|
||||
{
|
||||
|
@ -97,17 +99,17 @@ T_SyntaxTree< T , S >::T_SyntaxTree(
|
|||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >::T_SyntaxTree(
|
||||
T_SyntaxTree< T , S >&& other ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >::T_SyntaxTree(
|
||||
T_SyntaxTree< T , L , S >&& other ) noexcept
|
||||
: nodes_{ std::move( other.nodes_ ) }
|
||||
{
|
||||
// EMPTY
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
|
||||
T_SyntaxTree< T , S >&& other ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::operator =(
|
||||
T_SyntaxTree< T , L , S >&& other ) noexcept
|
||||
{
|
||||
nodes_ = std::move( other.nodes_ );
|
||||
return *this;
|
||||
|
@ -115,64 +117,71 @@ T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::operator =(
|
|||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_SyntaxTree< T , S >& T_SyntaxTree< T , S >::swap(
|
||||
T_SyntaxTree< T , S >& other ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
T_SyntaxTree< T , L , S >& T_SyntaxTree< T , L , S >::swap(
|
||||
T_SyntaxTree< T , L , S >& other ) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
swap( nodes_ , other.nodes_ );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
void swap( T_SyntaxTree< T , S >& lhs ,
|
||||
T_SyntaxTree< T , S >& rhs ) noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
void swap( T_SyntaxTree< T , L , S >& lhs ,
|
||||
T_SyntaxTree< T , L , S >& rhs ) noexcept
|
||||
{
|
||||
lhs.swap( rhs );
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
template< typename T , size_t S >
|
||||
T T_SyntaxTree< T , S >::typeOf(
|
||||
template< typename T , typename L , size_t S >
|
||||
T T_SyntaxTree< T , L , S >::typeOf(
|
||||
const uint32_t node ) const noexcept
|
||||
{
|
||||
return nodes_[ node ].type;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
uint32_t T_SyntaxTree< T , S >::parentOf(
|
||||
template< typename T , typename L , size_t S >
|
||||
uint32_t T_SyntaxTree< T , L , S >::parentOf(
|
||||
const uint32_t node ) const noexcept
|
||||
{
|
||||
return nodes_[ node ].parent;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , S >::childrenOf(
|
||||
template< typename T , typename L , size_t S >
|
||||
T_AutoArray< uint32_t , 8 > const& T_SyntaxTree< T , L , S >::childrenOf(
|
||||
const uint32_t node ) const noexcept
|
||||
{
|
||||
return nodes_[ node ].children;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
bool T_SyntaxTree< T , S >::hasData(
|
||||
template< typename T , typename L , size_t S >
|
||||
bool T_SyntaxTree< T , L , S >::hasData(
|
||||
const uint32_t node ) const noexcept
|
||||
{
|
||||
return bool( nodes_[ node ].data );
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
template< typename T , typename L , size_t S >
|
||||
template< typename D >
|
||||
D const& T_SyntaxTree< T , S >::dataOf(
|
||||
D const& T_SyntaxTree< T , L , S >::dataOf(
|
||||
const uint32_t node ) const
|
||||
{
|
||||
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 >
|
||||
uint32_t T_SyntaxTree< T , S >::addChild(
|
||||
template< typename T , typename L , size_t S >
|
||||
uint32_t T_SyntaxTree< T , L , S >::addChild(
|
||||
const uint32_t parent ,
|
||||
const E_Node type ) noexcept
|
||||
{
|
||||
|
@ -183,9 +192,9 @@ uint32_t T_SyntaxTree< T , S >::addChild(
|
|||
return idx;
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
template< typename T , typename L , size_t S >
|
||||
template< typename D , typename ... ArgTypes >
|
||||
D& T_SyntaxTree< T , S >::newData(
|
||||
D& T_SyntaxTree< T , L , S >::newData(
|
||||
const uint32_t node ,
|
||||
ArgTypes&& ... args )
|
||||
{
|
||||
|
@ -194,18 +203,25 @@ D& T_SyntaxTree< T , S >::newData(
|
|||
return data.template value< D >( );
|
||||
}
|
||||
|
||||
template< typename T , size_t S >
|
||||
template< typename T , typename L , size_t S >
|
||||
template< typename D >
|
||||
D& T_SyntaxTree< T , S >::dataOf(
|
||||
D& T_SyntaxTree< T , L , S >::dataOf(
|
||||
const uint32_t node )
|
||||
{
|
||||
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 >
|
||||
typename T_SyntaxTree< T , S >::T_Visitor T_SyntaxTree< T , S >::visitor( ) const noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
typename T_SyntaxTree< T , L , S >::T_Visitor T_SyntaxTree< T , L , S >::visitor( ) const noexcept
|
||||
{
|
||||
return T_Visitor{
|
||||
[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 >
|
||||
typename T_SyntaxTree< T , S >::T_Node T_SyntaxTree< T , S >::root( ) const noexcept
|
||||
template< typename T , typename L , size_t S >
|
||||
typename T_SyntaxTree< T , L , S >::T_Node T_SyntaxTree< T , L , S >::root( ) const noexcept
|
||||
{
|
||||
return T_Node{ *this , 0 };
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ class SyntaxTreeTest : public CppUnit::TestFixture
|
|||
CPPUNIT_TEST( testUpdateData );
|
||||
CPPUNIT_TEST( testAddChildren );
|
||||
CPPUNIT_TEST( testVisit );
|
||||
CPPUNIT_TEST( testLocation );
|
||||
CPPUNIT_TEST_SUITE_END( );
|
||||
|
||||
public:
|
||||
|
@ -18,6 +19,7 @@ public:
|
|||
void testUpdateData( );
|
||||
void testAddChildren( );
|
||||
void testVisit( );
|
||||
void testLocation( );
|
||||
};
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest );
|
||||
|
||||
|
@ -30,7 +32,7 @@ enum class E_TestNode_
|
|||
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( !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