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_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 );

View File

@ -37,7 +37,16 @@ BEGIN_ODDLPARSER_NS
static const char *Version = "0.1.0";
static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
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",
@ -52,11 +61,9 @@ static const char* PrimitiveTypeToken[ Value::ddl_types_max ] = {
"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,7 +289,57 @@ 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++;
}
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 );
Value::ValueType type( Value::ddl_none );
size_t arrayLen( 0 );
@ -284,24 +347,16 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
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 );
if( ddl_nullptr != values ){
DDLNode *currentNode( top() );
if( ddl_nullptr != currentNode ) {
currentNode->setValue( values );
}
}
in = parseDataList( in, end, &values, &refs );
setNodeValues( top(), values );
setNodeReferences( top(), refs );
} else if( arrayLen > 1 ) {
in = parseDataArrayList( in, end, &dtArrayList );
if( ddl_nullptr != dtArrayList ) {
DDLNode *currentNode( top() );
if( ddl_nullptr != currentNode ) {
currentNode->setDataArrayList( dtArrayList );
}
}
setNodeDataArrayList( top(), dtArrayList );
} else {
std::cerr << "0 for array is invalid." << std::endl;
error = true;
@ -311,26 +366,11 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
in = getNextToken( in, end );
if( *in != '}' ) {
logInvalidTokenError( in, "}", m_logCallback );
}
else {
in++;
} else {
//in++;
}
} else {
in = parseHeader( 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();
in = parseNextNode( in, end );
}
return in;
@ -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<Name*> &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, &current );
} else if( isHexLiteral( in, end ) ) {
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 ) {
@ -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, &current );
in = parseDataList( in, end, &current, &refs );
if( ddl_nullptr != current ) {
if( ddl_nullptr == prev ) {
*dataList = new DataArrayList;

View File

@ -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;
};

View File

@ -88,6 +88,12 @@ 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 ) {

View File

@ -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();

View File

@ -196,6 +196,20 @@ bool isHexLiteral( T *in, T *end ) {
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>
inline
bool isEndofLine( const T in ) {