Explorar o código

openddl-parser: latest greatest.

Signed-off-by: Kim Kulling <[email protected]>
Kim Kulling %!s(int64=10) %!d(string=hai) anos
pai
achega
79db48a0d1

+ 10 - 1
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 );

+ 126 - 92
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"
-};
-
-static const char *BoolTrue  = "true";
-static const char *BoolFalse = "false";
-static const char *RefToken  = "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 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<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;

+ 3 - 0
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;
 };

+ 8 - 2
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
     }
 };

+ 2 - 1
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();
 

+ 14 - 0
contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h

@@ -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 ) {