From 79db48a0d14163da70a1d9f61969cd8762463285 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 9 Mar 2015 10:17:23 +0100 Subject: [PATCH] openddl-parser: latest greatest. Signed-off-by: Kim Kulling --- contrib/openddlparser/code/DDLNode.cpp | 11 +- contrib/openddlparser/code/OpenDDLParser.cpp | 216 ++++++++++-------- .../include/openddlparser/DDLNode.h | 3 + .../include/openddlparser/OpenDDLCommon.h | 10 +- .../include/openddlparser/OpenDDLParser.h | 3 +- .../openddlparser/OpenDDLParserUtils.h | 14 ++ 6 files changed, 162 insertions(+), 95 deletions(-) diff --git a/contrib/openddlparser/code/DDLNode.cpp b/contrib/openddlparser/code/DDLNode.cpp index aba11d8ae..e65f1c45e 100644 --- a/contrib/openddlparser/code/DDLNode.cpp +++ b/contrib/openddlparser/code/DDLNode.cpp @@ -52,7 +52,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, , m_properties( ddl_nullptr ) , m_value( ddl_nullptr ) , m_idx( idx ) -, m_dtArrayList( ddl_nullptr ) { +, m_dtArrayList( ddl_nullptr ) +, m_references( ddl_nullptr ) { if( m_parent ) { m_parent->m_children.push_back( this ); } @@ -140,6 +141,14 @@ DataArrayList *DDLNode::getDataArrayList() const { return m_dtArrayList; } +void DDLNode::setReferences( Reference *refs ) { + m_references = refs; +} + +Reference *DDLNode::getReferences() const { + return m_references; +} + DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) { const size_t idx( s_allocatedNodes.size() ); DDLNode *node = new DDLNode( type, name, idx, parent ); diff --git a/contrib/openddlparser/code/OpenDDLParser.cpp b/contrib/openddlparser/code/OpenDDLParser.cpp index c85f498de..46eb50fd8 100644 --- a/contrib/openddlparser/code/OpenDDLParser.cpp +++ b/contrib/openddlparser/code/OpenDDLParser.cpp @@ -37,26 +37,33 @@ BEGIN_ODDLPARSER_NS static const char *Version = "0.1.0"; -static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { - "bool", - "int8", - "int16", - "int32", - "int64", - "unsigned_int8", - "unsigned_int16", - "unsigned_int32", - "unsigned_int64", - "half", - "float", - "double", - "string", - "ref" -}; +namespace Grammar { + static const char *OpenBracketToken = "{"; + static const char *CloseBracketToken = "}"; + static const char *OpenPropertyToken = "("; + static const char *ClosePropertyToken = ")"; + static const char *BoolTrue = "true"; + static const char *BoolFalse = "false"; + static const char *RefToken = "ref"; + + static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = { + "bool", + "int8", + "int16", + "int32", + "int64", + "unsigned_int8", + "unsigned_int16", + "unsigned_int32", + "unsigned_int64", + "half", + "float", + "double", + "string", + "ref" + }; +} // Namespace Grammar -static const char *BoolTrue = "true"; -static const char *BoolFalse = "false"; -static const char *RefToken = "ref"; static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) { std::stringstream stream; @@ -65,7 +72,8 @@ static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallbac } static bool isIntegerType( Value::ValueType integerType ) { - if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { + if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 && + integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) { return false; } @@ -203,6 +211,12 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) { return in; } +static void dumpId( Identifier *id ) { + if( ddl_nullptr != id ) { + std::cout << id->m_buffer << std::endl; + } +} + char *OpenDDLParser::parseHeader( char *in, char *end ) { if( nullptr == in || in == end ) { return in; @@ -212,9 +226,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in = OpenDDLParser::parseIdentifier( in, end, &id ); #ifdef DEBUG_HEADER_NAME - if( ddl_nullptr != id ) { - std::cout << id->m_buffer << std::endl; - } + dumpId( id ); #endif // DEBUG_HEADER_NAME in = getNextToken( in, end ); @@ -224,13 +236,14 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) { in++; Property *prop( ddl_nullptr ), *prev( ddl_nullptr ); while( *in != ')' && in != end ) { - in = parseProperty( in, end, &prop ); + in = OpenDDLParser::parseProperty( in, end, &prop ); in = getNextToken( in, end ); if( *in != ',' && *in != ')' ) { logInvalidTokenError( in, ")", m_logCallback ); return in; } + if( ddl_nullptr != prop && *in != ',' ) { if( ddl_nullptr == first ) { first = prop; @@ -276,55 +289,17 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { bool error( false ); in = getNextToken( in, end ); if( *in == '{' ) { + do { + // loop over all childs ( data and nodes ) + in = parseStructureBody( in, end, error ); + } while ( *in != '}' ); in++; - in = getNextToken( in, end ); - Value::ValueType type( Value::ddl_none ); - size_t arrayLen( 0 ); - in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); - if( Value::ddl_none != type ) { - in = getNextToken( in, end ); - if( *in == '{' ) { - DataArrayList *dtArrayList( ddl_nullptr ); - Value *values( ddl_nullptr ); - if( 1 == arrayLen ) { - in = parseDataList( in, end, &values ); - if( ddl_nullptr != values ){ - DDLNode *currentNode( top() ); - if( ddl_nullptr != currentNode ) { - currentNode->setValue( values ); - } - } - } else if( arrayLen > 1 ) { - in = parseDataArrayList( in, end, &dtArrayList ); - if( ddl_nullptr != dtArrayList ) { - DDLNode *currentNode( top() ); - if( ddl_nullptr != currentNode ) { - currentNode->setDataArrayList( dtArrayList ); - } - } - } else { - std::cerr << "0 for array is invalid." << std::endl; - error = true; - } - } - - in = getNextToken( in, end ); - if( *in != '}' ) { - logInvalidTokenError( in, "}", m_logCallback ); - } - else { - in++; - } - } else { - in = parseHeader( in, end ); - in = parseStructure( in, end ); - } - } else { + } + else { in++; logInvalidTokenError( in, "{", m_logCallback ); error = true; return in; - } in = getNextToken( in, end ); @@ -336,6 +311,71 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) { return in; } +static void setNodeValues( DDLNode *currentNode, Value *values ) { + if( ddl_nullptr != values ){ + if( ddl_nullptr != currentNode ) { + currentNode->setValue( values ); + } + } +} + +static void setNodeReferences( DDLNode *currentNode, Reference *refs ) { + if( ddl_nullptr != refs ) { + if( ddl_nullptr != currentNode ) { + currentNode->setReferences( refs ); + } + } +} + +static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) { + if( ddl_nullptr != dtArrayList ) { + if( ddl_nullptr != currentNode ) { + currentNode->setDataArrayList( dtArrayList ); + } + } +} + +char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) { + if( !isNumeric( *in ) && !isCharacter( *in ) ) { + in++; + } + + in = getNextToken( in, end ); + Value::ValueType type( Value::ddl_none ); + size_t arrayLen( 0 ); + in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen ); + if( Value::ddl_none != type ) { + in = getNextToken( in, end ); + if( *in == '{' ) { + Reference *refs( ddl_nullptr ); + DataArrayList *dtArrayList( ddl_nullptr ); + Value *values( ddl_nullptr ); + if( 1 == arrayLen ) { + in = parseDataList( in, end, &values, &refs ); + setNodeValues( top(), values ); + setNodeReferences( top(), refs ); + } else if( arrayLen > 1 ) { + in = parseDataArrayList( in, end, &dtArrayList ); + setNodeDataArrayList( top(), dtArrayList ); + } else { + std::cerr << "0 for array is invalid." << std::endl; + error = true; + } + } + + in = getNextToken( in, end ); + if( *in != '}' ) { + logInvalidTokenError( in, "}", m_logCallback ); + } else { + //in++; + } + } else { + in = parseNextNode( in, end ); + } + + return in; +} + void OpenDDLParser::pushNode( DDLNode *node ) { if( nullptr == node ) { return; @@ -469,9 +509,10 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy return in; } + size_t prim_len( 0 ); for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { - const size_t prim_len( strlen( PrimitiveTypeToken[ i ] ) ); - if( 0 == strncmp( in, PrimitiveTypeToken[ i ], prim_len ) ) { + prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] ); + if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) { type = ( Value::ValueType ) i; break; } @@ -481,7 +522,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy in = getNextToken( in, end ); return in; } else { - in += strlen( PrimitiveTypeToken[ type ] ); + in += prim_len; } bool ok( true ); @@ -513,27 +554,12 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector &na return in; } - if( 0 != strncmp( in, RefToken, strlen( RefToken ) ) ) { - return in; - } else { - const size_t refTokenLen( strlen( RefToken ) ); - in += refTokenLen; - } - - in = getNextToken( in, end ); - if( '{' != *in ) { - return in; - } else { - in++; - } - - in = getNextToken( in, end ); Name *nextName( ddl_nullptr ); in = parseName( in, end, &nextName ); if( nextName ) { names.push_back( nextName ); } - while( '}' != *in ) { + while( ',' == *in ) { in = getNextSeparator( in, end ); if( ',' == *in ) { in = parseName( in, end, &nextName ); @@ -562,9 +588,9 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) len++; } len++; - int res = ::strncmp( BoolTrue, start, strlen( BoolTrue ) ); + int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) ); if( 0 != res ) { - res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) ); + res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) ); if( 0 != res ) { *boolean = ddl_nullptr; return in; @@ -770,7 +796,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) { return in; } -char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { +char *OpenDDLParser::parseDataList( char *in, char *end, Value **data, Reference **refs ) { *data = ddl_nullptr; if( ddl_nullptr == in || in == end ) { return in; @@ -791,6 +817,13 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) { in = parseStringLiteral( in, end, ¤t ); } else if( isHexLiteral( in, end ) ) { in = parseHexaLiteral( in, end, ¤t ); + } else { // reference data + std::vector names; + in = parseReference( in, end, names ); + if( !names.empty() ) { + Reference *ref = new Reference( names.size(), &names[ 0 ] ); + *refs = ref; + } } if( ddl_nullptr != current ) { @@ -824,9 +857,10 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da if( *in == '{' ) { in++; Value *current( ddl_nullptr ); + Reference *refs( nullptr ); DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); do { - in = parseDataList( in, end, ¤t ); + in = parseDataList( in, end, ¤t, &refs ); if( ddl_nullptr != current ) { if( ddl_nullptr == prev ) { *dataList = new DataArrayList; diff --git a/contrib/openddlparser/include/openddlparser/DDLNode.h b/contrib/openddlparser/include/openddlparser/DDLNode.h index bb5f87b79..93b447bb2 100644 --- a/contrib/openddlparser/include/openddlparser/DDLNode.h +++ b/contrib/openddlparser/include/openddlparser/DDLNode.h @@ -61,6 +61,8 @@ public: Value *getValue() const; void setDataArrayList( DataArrayList *dtArrayList ); DataArrayList *getDataArrayList() const; + void setReferences( Reference *refs ); + Reference *getReferences() const; static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr ); private: @@ -78,6 +80,7 @@ private: Property *m_properties; Value *m_value; DataArrayList *m_dtArrayList; + Reference *m_references; size_t m_idx; static DllNodeList s_allocatedNodes; }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h index 789bc15ad..c7fd844a2 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h @@ -88,9 +88,15 @@ struct Reference { size_t m_numRefs; Name **m_referencedName; + Reference() + : m_numRefs( 0 ) + , m_referencedName( ddl_nullptr ) { + // empty + } + Reference( size_t numrefs, Name **names ) - : m_numRefs( numrefs ) - , m_referencedName( names ) { + : m_numRefs( numrefs ) + , m_referencedName( names ) { // empty } }; diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h index 4f003a0e4..00f2c2e58 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParser.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParser.h @@ -77,6 +77,7 @@ public: char *parseNextNode( char *current, char *end ); char *parseHeader( char *in, char *end ); char *parseStructure( char *in, char *end ); + char *parseStructureBody( char *in, char *end, bool &error ); void pushNode( DDLNode *node ); DDLNode *popNode(); DDLNode *top(); @@ -95,7 +96,7 @@ public: // static parser helpers static char *parseStringLiteral( char *in, char *end, Value **stringData ); static char *parseHexaLiteral( char *in, char *end, Value **data ); static char *parseProperty( char *in, char *end, Property **prop ); - static char *parseDataList( char *in, char *end, Value **data ); + static char *parseDataList( char *in, char *end, Value **data, Reference **refs ); static char *parseDataArrayList( char *in, char *end, DataArrayList **dataList ); static const char *getVersion(); diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index 179a51326..b1b4f6cde 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -196,6 +196,20 @@ bool isHexLiteral( T *in, T *end ) { return false; } +template +inline +bool isReference( T *in, T *end ) { + if( *in == 'r' ) { + if( *(in+1) == 'e' ) { + if( *(in+2) == 'f' ) { + return true; + } + } + } + + return false; +} + template inline bool isEndofLine( const T in ) {