openddl-parser: latest greatest.

Signed-off-by: Kim Kulling <kim.kulling@googlemail.com>
pull/502/head
Kim Kulling 2015-03-09 10:17:23 +01:00
parent 0292868917
commit 79db48a0d1
6 changed files with 162 additions and 95 deletions

View File

@ -52,7 +52,8 @@ DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx,
, m_properties( ddl_nullptr ) , m_properties( ddl_nullptr )
, m_value( ddl_nullptr ) , m_value( ddl_nullptr )
, m_idx( idx ) , m_idx( idx )
, m_dtArrayList( ddl_nullptr ) { , m_dtArrayList( ddl_nullptr )
, m_references( ddl_nullptr ) {
if( m_parent ) { if( m_parent ) {
m_parent->m_children.push_back( this ); m_parent->m_children.push_back( this );
} }
@ -140,6 +141,14 @@ DataArrayList *DDLNode::getDataArrayList() const {
return m_dtArrayList; 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 ) { DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
const size_t idx( s_allocatedNodes.size() ); const size_t idx( s_allocatedNodes.size() );
DDLNode *node = new DDLNode( type, name, idx, parent ); DDLNode *node = new DDLNode( type, name, idx, parent );

View File

@ -37,6 +37,15 @@ BEGIN_ODDLPARSER_NS
static const char *Version = "0.1.0"; static const char *Version = "0.1.0";
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 ] = { static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
"bool", "bool",
"int8", "int8",
@ -53,10 +62,8 @@ static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
"string", "string",
"ref" "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 ) { static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallback callback ) {
std::stringstream stream; std::stringstream stream;
@ -65,7 +72,8 @@ static void logInvalidTokenError( char *in, char *exp, OpenDDLParser::logCallbac
} }
static bool isIntegerType( Value::ValueType integerType ) { 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; return false;
} }
@ -203,6 +211,12 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) {
return in; 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 ) { char *OpenDDLParser::parseHeader( char *in, char *end ) {
if( nullptr == in || in == end ) { if( nullptr == in || in == end ) {
return in; return in;
@ -212,9 +226,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
in = OpenDDLParser::parseIdentifier( in, end, &id ); in = OpenDDLParser::parseIdentifier( in, end, &id );
#ifdef DEBUG_HEADER_NAME #ifdef DEBUG_HEADER_NAME
if( ddl_nullptr != id ) { dumpId( id );
std::cout << id->m_buffer << std::endl;
}
#endif // DEBUG_HEADER_NAME #endif // DEBUG_HEADER_NAME
in = getNextToken( in, end ); in = getNextToken( in, end );
@ -224,13 +236,14 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
in++; in++;
Property *prop( ddl_nullptr ), *prev( ddl_nullptr ); Property *prop( ddl_nullptr ), *prev( ddl_nullptr );
while( *in != ')' && in != end ) { while( *in != ')' && in != end ) {
in = parseProperty( in, end, &prop ); in = OpenDDLParser::parseProperty( in, end, &prop );
in = getNextToken( in, end ); in = getNextToken( in, end );
if( *in != ',' && *in != ')' ) { if( *in != ',' && *in != ')' ) {
logInvalidTokenError( in, ")", m_logCallback ); logInvalidTokenError( in, ")", m_logCallback );
return in; return in;
} }
if( ddl_nullptr != prop && *in != ',' ) { if( ddl_nullptr != prop && *in != ',' ) {
if( ddl_nullptr == first ) { if( ddl_nullptr == first ) {
first = prop; first = prop;
@ -276,7 +289,57 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
bool error( false ); bool error( false );
in = getNextToken( in, end ); in = getNextToken( in, end );
if( *in == '{' ) { if( *in == '{' ) {
do {
// loop over all childs ( data and nodes )
in = parseStructureBody( in, end, error );
} while ( *in != '}' );
in++; in++;
}
else {
in++;
logInvalidTokenError( in, "{", m_logCallback );
error = true;
return in;
}
in = getNextToken( in, end );
// pop node from stack after successful parsing
if( !error ) {
popNode();
}
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 ); in = getNextToken( in, end );
Value::ValueType type( Value::ddl_none ); Value::ValueType type( Value::ddl_none );
size_t arrayLen( 0 ); size_t arrayLen( 0 );
@ -284,24 +347,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
if( Value::ddl_none != type ) { if( Value::ddl_none != type ) {
in = getNextToken( in, end ); in = getNextToken( in, end );
if( *in == '{' ) { if( *in == '{' ) {
Reference *refs( ddl_nullptr );
DataArrayList *dtArrayList( ddl_nullptr ); DataArrayList *dtArrayList( ddl_nullptr );
Value *values( ddl_nullptr ); Value *values( ddl_nullptr );
if( 1 == arrayLen ) { if( 1 == arrayLen ) {
in = parseDataList( in, end, &values ); in = parseDataList( in, end, &values, &refs );
if( ddl_nullptr != values ){ setNodeValues( top(), values );
DDLNode *currentNode( top() ); setNodeReferences( top(), refs );
if( ddl_nullptr != currentNode ) {
currentNode->setValue( values );
}
}
} else if( arrayLen > 1 ) { } else if( arrayLen > 1 ) {
in = parseDataArrayList( in, end, &dtArrayList ); in = parseDataArrayList( in, end, &dtArrayList );
if( ddl_nullptr != dtArrayList ) { setNodeDataArrayList( top(), dtArrayList );
DDLNode *currentNode( top() );
if( ddl_nullptr != currentNode ) {
currentNode->setDataArrayList( dtArrayList );
}
}
} else { } else {
std::cerr << "0 for array is invalid." << std::endl; std::cerr << "0 for array is invalid." << std::endl;
error = true; error = true;
@ -311,26 +366,11 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
in = getNextToken( in, end ); in = getNextToken( in, end );
if( *in != '}' ) { if( *in != '}' ) {
logInvalidTokenError( in, "}", m_logCallback ); logInvalidTokenError( in, "}", m_logCallback );
} } else {
else { //in++;
in++;
} }
} else { } else {
in = parseHeader( in, end ); in = parseNextNode( in, end );
in = parseStructure( in, end );
}
} else {
in++;
logInvalidTokenError( in, "{", m_logCallback );
error = true;
return in;
}
in = getNextToken( in, end );
// pop node from stack after successful parsing
if( !error ) {
popNode();
} }
return in; return in;
@ -469,9 +509,10 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
return in; return in;
} }
size_t prim_len( 0 );
for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) { for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
const size_t prim_len( strlen( PrimitiveTypeToken[ i ] ) ); prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
if( 0 == strncmp( in, PrimitiveTypeToken[ i ], prim_len ) ) { if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
type = ( Value::ValueType ) i; type = ( Value::ValueType ) i;
break; break;
} }
@ -481,7 +522,7 @@ char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueTy
in = getNextToken( in, end ); in = getNextToken( in, end );
return in; return in;
} else { } else {
in += strlen( PrimitiveTypeToken[ type ] ); in += prim_len;
} }
bool ok( true ); bool ok( true );
@ -513,27 +554,12 @@ char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &na
return in; 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 ); Name *nextName( ddl_nullptr );
in = parseName( in, end, &nextName ); in = parseName( in, end, &nextName );
if( nextName ) { if( nextName ) {
names.push_back( nextName ); names.push_back( nextName );
} }
while( '}' != *in ) { while( ',' == *in ) {
in = getNextSeparator( in, end ); in = getNextSeparator( in, end );
if( ',' == *in ) { if( ',' == *in ) {
in = parseName( in, end, &nextName ); in = parseName( in, end, &nextName );
@ -562,9 +588,9 @@ char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean )
len++; len++;
} }
len++; len++;
int res = ::strncmp( BoolTrue, start, strlen( BoolTrue ) ); int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
if( 0 != res ) { if( 0 != res ) {
res = ::strncmp( BoolFalse, start, strlen( BoolFalse ) ); res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
if( 0 != res ) { if( 0 != res ) {
*boolean = ddl_nullptr; *boolean = ddl_nullptr;
return in; return in;
@ -770,7 +796,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
return in; 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; *data = ddl_nullptr;
if( ddl_nullptr == in || in == end ) { if( ddl_nullptr == in || in == end ) {
return in; return in;
@ -791,6 +817,13 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value **data ) {
in = parseStringLiteral( in, end, &current ); in = parseStringLiteral( in, end, &current );
} else if( isHexLiteral( in, end ) ) { } else if( isHexLiteral( in, end ) ) {
in = parseHexaLiteral( in, end, &current ); in = parseHexaLiteral( in, end, &current );
} else { // reference data
std::vector<Name*> names;
in = parseReference( in, end, names );
if( !names.empty() ) {
Reference *ref = new Reference( names.size(), &names[ 0 ] );
*refs = ref;
}
} }
if( ddl_nullptr != current ) { if( ddl_nullptr != current ) {
@ -824,9 +857,10 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da
if( *in == '{' ) { if( *in == '{' ) {
in++; in++;
Value *current( ddl_nullptr ); Value *current( ddl_nullptr );
Reference *refs( nullptr );
DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr ); DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
do { do {
in = parseDataList( in, end, &current ); in = parseDataList( in, end, &current, &refs );
if( ddl_nullptr != current ) { if( ddl_nullptr != current ) {
if( ddl_nullptr == prev ) { if( ddl_nullptr == prev ) {
*dataList = new DataArrayList; *dataList = new DataArrayList;

View File

@ -61,6 +61,8 @@ public:
Value *getValue() const; Value *getValue() const;
void setDataArrayList( DataArrayList *dtArrayList ); void setDataArrayList( DataArrayList *dtArrayList );
DataArrayList *getDataArrayList() const; 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 ); static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
private: private:
@ -78,6 +80,7 @@ private:
Property *m_properties; Property *m_properties;
Value *m_value; Value *m_value;
DataArrayList *m_dtArrayList; DataArrayList *m_dtArrayList;
Reference *m_references;
size_t m_idx; size_t m_idx;
static DllNodeList s_allocatedNodes; static DllNodeList s_allocatedNodes;
}; };

View File

@ -88,6 +88,12 @@ struct Reference {
size_t m_numRefs; size_t m_numRefs;
Name **m_referencedName; Name **m_referencedName;
Reference()
: m_numRefs( 0 )
, m_referencedName( ddl_nullptr ) {
// empty
}
Reference( size_t numrefs, Name **names ) Reference( size_t numrefs, Name **names )
: m_numRefs( numrefs ) : m_numRefs( numrefs )
, m_referencedName( names ) { , m_referencedName( names ) {

View File

@ -77,6 +77,7 @@ public:
char *parseNextNode( char *current, char *end ); char *parseNextNode( char *current, char *end );
char *parseHeader( char *in, char *end ); char *parseHeader( char *in, char *end );
char *parseStructure( char *in, char *end ); char *parseStructure( char *in, char *end );
char *parseStructureBody( char *in, char *end, bool &error );
void pushNode( DDLNode *node ); void pushNode( DDLNode *node );
DDLNode *popNode(); DDLNode *popNode();
DDLNode *top(); DDLNode *top();
@ -95,7 +96,7 @@ public: // static parser helpers
static char *parseStringLiteral( char *in, char *end, Value **stringData ); static char *parseStringLiteral( char *in, char *end, Value **stringData );
static char *parseHexaLiteral( char *in, char *end, Value **data ); static char *parseHexaLiteral( char *in, char *end, Value **data );
static char *parseProperty( char *in, char *end, Property **prop ); 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 char *parseDataArrayList( char *in, char *end, DataArrayList **dataList );
static const char *getVersion(); static const char *getVersion();

View File

@ -196,6 +196,20 @@ bool isHexLiteral( T *in, T *end ) {
return false; return false;
} }
template<class T>
inline
bool isReference( T *in, T *end ) {
if( *in == 'r' ) {
if( *(in+1) == 'e' ) {
if( *(in+2) == 'f' ) {
return true;
}
}
}
return false;
}
template<class T> template<class T>
inline inline
bool isEndofLine( const T in ) { bool isEndofLine( const T in ) {