openddl-parser: latest greatest.
Signed-off-by: Kim Kulling <kim.kulling@googlemail.com>pull/502/head
parent
0292868917
commit
79db48a0d1
|
@ -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 );
|
||||||
|
|
|
@ -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, ¤t );
|
in = parseStringLiteral( in, end, ¤t );
|
||||||
} else if( isHexLiteral( in, end ) ) {
|
} else if( isHexLiteral( in, end ) ) {
|
||||||
in = parseHexaLiteral( in, end, ¤t );
|
in = parseHexaLiteral( in, end, ¤t );
|
||||||
|
} 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, ¤t );
|
in = parseDataList( in, end, ¤t, &refs );
|
||||||
if( ddl_nullptr != current ) {
|
if( ddl_nullptr != current ) {
|
||||||
if( ddl_nullptr == prev ) {
|
if( ddl_nullptr == prev ) {
|
||||||
*dataList = new DataArrayList;
|
*dataList = new DataArrayList;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
Loading…
Reference in New Issue