/*
================
Lexer::ReadFloat
================
*/
float Lexer::ReadFloat( void ) {
	if ( !ReadToken() )
		throw LexerError( LexerError::END_OF_FILE );
	if ( !String::IsNumeric( token.GetString() ) )
		throw LexerError( LexerError::BAD_TOKEN, token.line, "float", token.GetString() );
	return String::ToFloat( token.GetString() );
}
示例#2
0
文件: Tree.cpp 项目: konlil/openddl
openddl::Tree openddl::Tree::parse(const std::string & i)
{
	Tree::Impl * impl = new Tree::Impl();
	std::vector<detail::Token> tokens;
	std::vector<detail::Error> errors;
	if (!detail::lex(i, tokens, errors))
	{
		throw LexerError(errors);
	}
	else if (!detail::parse(tokens, impl->commands, errors))
	{
		throw ParseError(errors);
	}
	else if (!detail::semantic_check(impl->commands, errors, impl->global_names, impl->local_names))
	{
		throw SemanticError(errors);
	}

	//Build the child table to avoid walking the table whenever running visitors across the data
	for (unsigned int i = 0; i < impl->commands.size(); i++)
	{
		auto it = impl->child_table.find(impl->commands[i].parent);
		if (it == impl->child_table.end())
			it = impl->child_table.emplace(impl->commands[i].parent,std::vector<unsigned int>()).first;
		it->second.push_back(i);
	}
	Tree t; t.implementation.reset(impl);
	return std::move(t);
}
/*
================
Lexer::FindToken
================
*/
void Lexer::FindToken( const char *str ) {
	while ( ReadToken() ) {
		if ( String::Icmp( token.GetString(), str ) == 0 )
			return;
	}
	throw LexerError( LexerError::MISSING_TOKEN, token.line, str, "[EOF]" );
}
/*
================
Lexer::CheckToken
================
*/
bool Lexer::CheckToken( const char *string ) {
	if ( !ReadToken() )
		throw LexerError( LexerError::END_OF_FILE );
	if ( String::Icmp( token.GetString(), string ) != 0 ) {
		UnreadToken();
		return false;
	}
	return true;
}
/*
================
Lexer::ParseQuoted
================
*/
void Lexer::ParseQuoted( void ) {
	char c = buffer[bufPos];
	if ( flags & LEXER_FULL_LINES )
		AddToToken( buffer[bufPos] );

	bufPos++;

	while ( bufPos < bufSize ) {
		// Check for newlines
		if ( buffer[bufPos] == '\n' || buffer[bufPos] == '\r' )
			throw LexerError( LexerError::BAD_TOKEN, token.line, Format( "quote end: '\\$*'" ) << c, "[EOL]" );

		// Check for escape characters
		if ( useEscapeChars && buffer[bufPos] == '\\' ) {
			if ( buffer[bufPos+1] == 'n' ) {
				AddToToken( '\n' );
				bufPos += 2;
				continue;
			} else if ( buffer[bufPos+1] == 't' ) {
				AddToToken( '\t' );
				bufPos += 2;
				continue;
			} else if ( buffer[bufPos+1] == '\"' || buffer[bufPos+1] == '\'' ) {
				AddToToken( buffer[bufPos+1] );
				bufPos += 2;
				continue;
			}
		}
		// Check if this is the quote end we are looking for.
		else if ( buffer[bufPos] == c ) {
			if ( flags & LEXER_FULL_LINES )
				AddToToken( buffer[bufPos] );
			else
				FinishToken( true );
			bufPos++;
			return;
		}

		AddToToken( buffer[bufPos] );
		bufPos++;
	}
	throw LexerError( LexerError::BAD_TOKEN, token.line, Format("quote end: '\\$*'" ) << c, "[EOF]" );
}
/*
================
DeclParser::Parse
================
*/
void DeclParser::Parse( Lexer &lexer ) {
	Dict *resultDict = OG_NULL;

	bool getKeyValue = false;

	int index;
	const Token *token;
	String key, value;

	const char *p;
	while ( (token = lexer.ReadToken()) != OG_NULL ) {
		p = token->GetString();
		if ( p ) {
			if ( *p == '\0' )
				lexer.Error("Unexpected Empty Token");
			if ( !getKeyValue ) {
				index = declTypes.Find(p);
				if ( index != -1 ) {
					value = lexer.ReadString();

					if ( value.IsEmpty() )
						lexer.Error("Empty name!");

					DictEx<Dict> &result = declTypes[index]->declList;
					index = result.Find(p);
					if ( index == -1 ) 
						resultDict = &result[p];
					else {
						resultDict = &result[index];
						resultDict->Clear();
					}
				} else {
					resultDict = OG_NULL;
					lexer.Warning( Format("Unknown decl Type '$*'") << p );
				}
				lexer.ExpectToken("{");
				getKeyValue = true;
			} else {
				if ( *p == '}' )
					getKeyValue = false;
				else if ( resultDict ) {
					key = p;
					(*resultDict).Set( key.c_str(), lexer.ReadString() );
				}
			}
		}
	}
	if ( getKeyValue )
		throw LexerError( LexerError::END_OF_FILE );
}
/*
================
ImportMD5AnimBaseFrame
================
*/
bool ImportMD5AnimBaseFrame( const char *filename, Model *model ) {
    Lexer lexer(LEXER_NO_BOM_WARNING);
    if ( !lexer.LoadFile( filename ) ) {
        delete model;
        return false;
    }

    try {
        // MD5Version must be the first keyword
        lexer.ExpectToken( "MD5Version" );
        int fileVersion = lexer.ReadInt();
        if ( fileVersion != MD5_VERSION_DOOM3 && fileVersion != MD5_VERSION_QUAKEWARS )
            lexer.Error( Format("MD5Version is $*, should be $* or $*") << fileVersion << MD5_VERSION_DOOM3 << MD5_VERSION_QUAKEWARS );

        const Token *token;
        String key;

        const char *p;

        bool inHierarchyGroup = false;
        bool inBoundsGroup = false;
        bool inBaseFrameGroup = false;
        bool inFrameGroup = false;

        int numJoints = -1;
        int frameRate, numFrames, currentFrame;

        bool noAnimate = false;
        bool readVertexColor = false;
        Color vertexColor;

        ListEx<MD5Vertex> vertexList;
        ListEx<MD5Weight> weightList;
        Vec3 vTemp;
        int boneIndex = 0;

        while ( (token = lexer.ReadToken()) != NULL ) {
            p = token->GetString();
            if ( !p || !*p )
                continue;

            if ( inHierarchyGroup ) {
                if ( *p == '}' ) {
                    inHierarchyGroup = false;
                    continue;
                }
                Bone &bone = model->bones.Alloc();
                bone.name = p;
                bone.idParent = lexer.ReadInt();
                bone.flags = lexer.ReadInt();
                lexer.ReadInt(); // start index ?
            } else if ( inBaseFrameGroup ) {
                if ( *p == '}' ) {
                    inBaseFrameGroup = false;
                    break; //! @todo	should be continue when loading all frames.
                }
                lexer.UnreadToken();
                Bone &bone = model->bones[boneIndex++];
                ParseVector( lexer, &bone.origin.x, 3 );
                ParseVector( lexer, &bone.quat.x, 3 );

                bone.origin *= MD5_MODEL_SCALE;

                // Compute w
                bone.quat.w = 1.0f - (bone.quat.x * bone.quat.x) - (bone.quat.y * bone.quat.y) - (bone.quat.z * bone.quat.z);
                bone.quat.w = ( bone.quat.w <= 0.0f ) ? 0.0f : -Math::Sqrt( bone.quat.w );
            } else if ( inBoundsGroup ) {
                if ( *p == '}' ) {
                    inBoundsGroup = false;
                    continue;
                }
                lexer.UnreadToken();
                ParseVector( lexer, &vTemp.x, 3 );
                ParseVector( lexer, &vTemp.x, 3 );
            } else if ( inFrameGroup ) {
                if ( *p == '}' ) {
                    inFrameGroup = false;
                    continue;
                }
                //! @todo	why was here a fixme ?
            } else {
                if ( String::Icmp( p, "commandline" ) == 0 ) {
                    // Skip value, we don't need it
                    lexer.ReadToken();
                } else if ( String::Icmp( p, "frameRate" ) == 0 ) {
                    frameRate = lexer.ReadInt();
                } else if ( String::Icmp( p, "numAnimatedComponents" ) == 0 ) {
                    // Skip value, we don't need it
                    lexer.ReadToken();
                } else if ( String::Icmp( p, "numJoints" ) == 0 ) {
                    numJoints = lexer.ReadInt();
                    if ( numJoints > 0 ) {
                        model->bones.SetGranularity( numJoints );
                        model->bones.CheckSize( numJoints );
                    }
                } else if ( String::Icmp( p, "numFrames" ) == 0 ) {
                    numFrames = lexer.ReadInt();
                    if ( numFrames <= 0 )
                        lexer.Error("Zero frames on model");
                    //! @todo	why was here a fixme ?
                } else if ( String::Icmp( p, "hierarchy" ) == 0 ) {
                    if ( numJoints == -1 )
                        lexer.Error("numJoins not set!");
                    lexer.ExpectToken( "{" );
                    inHierarchyGroup = true;
                } else if ( String::Icmp( p, "bounds" ) == 0 ) {
                    lexer.ExpectToken( "{" );
                    inBoundsGroup = true;
                } else if ( String::Icmp( p, "baseframe" ) == 0 ) {
                    lexer.ExpectToken( "{" );
                    inBaseFrameGroup = true;
                } else if ( String::Icmp( p, "frame" ) == 0 ) {
                    currentFrame = lexer.ReadInt();
                    lexer.ExpectToken( "{" );
                    inFrameGroup = true;
                } else {
                    lexer.Error( Format("Unexpected '$*'") << p );
                }
            }
        }
        if ( inHierarchyGroup || inBoundsGroup || inFrameGroup || numJoints == -1 )
            throw LexerError( LexerError::END_OF_FILE );
        return true;
    }
    catch( LexerError err ) {
        delete model;
        String errStr;
        err.ToString( errStr );
        User::Error( ERR_LEXER_FAILURE, errStr.c_str(), filename );
        return false;
    }
}
/*
================
Model::ImportMD5
================
*/
Model *Model::ImportMD5( const char *filename, const char *filenameAnim ) {
    Lexer lexer(LEXER_NO_BOM_WARNING);
    if ( !lexer.LoadFile( filename ) )
        return NULL;

    Model *model = new Model(true);
    int numJoints = -1;
    try {

        // MD5Version must be the first keyword
        lexer.ExpectToken( "MD5Version" );
        int fileVersion = lexer.ReadInt();
        if ( fileVersion != MD5_VERSION_DOOM3 && fileVersion != MD5_VERSION_QUAKEWARS )
            lexer.Error( Format( "MD5Version is $*, should be $* or $*") << fileVersion << MD5_VERSION_DOOM3 << MD5_VERSION_QUAKEWARS );

        const Token *token;
        String key;

        const char *p;

        bool inJointGroup = false;
        bool inMeshGroup = false;
        bool readMeshVerts = false;
        bool readMeshTris = false;

        int numMeshes = -1;
        int numVerts, vertIndex;
        int triCounter, indexCounter;
        int numWeights;
        MeshAnimated *mesh = NULL;

        int i, j, num;
        Vec3 vTemp;

        bool noAnimate = false;
        bool readVertexColor = false;
        Color vertexColor;

        ListEx<MD5Vertex> vertexList;
        ListEx<MD5Weight> weightList;

        while ( (token = lexer.ReadToken()) != NULL ) {
            p = token->GetString();
            if ( !p || !*p )
                continue;

            if ( inJointGroup ) {
                if ( *p == '}' ) {
                    inJointGroup = false;
                    continue;
                }
                lexer.ReadInt(); // unused
                ParseVector( lexer, &vTemp.x, 3 );
                ParseVector( lexer, &vTemp.x, 3 );
            } else if ( inMeshGroup ) {
                lexer.UnreadToken();
                if ( readMeshVerts ) {
                    if ( lexer.CheckToken( "numtris" ) ) {
                        if ( numVerts != vertexList.Num() )
                            lexer.Error( Format("numVerts don't match: $*") << vertexList.Num() );
                        InitIndices( mesh, lexer.ReadInt() * 3 ); // numtris * 3
                        triCounter = 0;
                        indexCounter = 0;
                        readMeshVerts = false;
                        readMeshTris = true;
                        continue;
                    }
                    lexer.ExpectToken( "vert" );

                    vertIndex = lexer.ReadInt();
                    if ( vertIndex != vertexList.Num() )
                        lexer.Error( Format("Bad Vert Index, should be $*") << vertexList.Num() );

                    MD5Vertex &vertex = vertexList.Alloc();
                    ParseVector( lexer, &vertex.texCoord.x, 2 );
                    vertex.firstWeight = lexer.ReadInt();
                    vertex.lastWeight = lexer.ReadInt() + vertex.firstWeight - 1;

                    if ( readVertexColor ) {
                        // Currently we don't have use for vertex color..
                        // I haven't seen md5meshes with other values than ( 1 1 1 1 ) for vertexColor anyway..
                        ParseVector( lexer, &vertexColor.r, 4 );
                    }
                } else if ( readMeshTris ) {
                    if ( lexer.CheckToken( "numweights" ) ) {
                        numWeights = lexer.ReadInt();
                        weightList.CheckSize( numWeights );
                        readMeshTris = false;
                        continue;
                    }
                    lexer.ExpectToken( "tri" );

                    if ( lexer.ReadInt() != triCounter )
                        lexer.Error( Format("Bad Tri Index, should be $*") << triCounter );

                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    triCounter++;
                } else {
                    if ( lexer.CheckToken( "}" ) ) {
                        if ( numWeights != weightList.Num() )
                            lexer.Error( Format("numWeights doesn't match $*") << weightList.Num() );

                        // Convert vertices:
                        num = vertexList.Num();
                        for( i=0; i<num; i++ ) {
                            if ( i >= vertexList.Num() )
                                lexer.Error( "Vertex index out of range" );

                            const MD5Vertex &md5Vert = vertexList[i];

                            mesh->texCoords[i] = md5Vert.texCoord;

                            Vertex &vInfo = mesh->vertices[i];
                            InitVertex( &vInfo, 1 + md5Vert.lastWeight - md5Vert.firstWeight );
                            vInfo.numWeights = 0;

                            for ( j=md5Vert.firstWeight; j<=md5Vert.lastWeight; j++ ) {
                                if ( j >= weightList.Num() )
                                    lexer.Error( "Weight index out of range" );
                                const MD5Weight &md5Weight = weightList[j];

                                if ( md5Weight.jointIndex >= numJoints )
                                    lexer.Error( "Weight joint index out of range" );

                                if ( md5Weight.bias == 0.0f )
                                    continue;

                                VertexWeight &weight = vInfo.weights[vInfo.numWeights++];
                                weight.boneId = md5Weight.jointIndex;
                                weight.origin = md5Weight.origin;
                                //weight.normal = md5Weight.normal; //! @todo	calculate normal
                                weight.influence = md5Weight.bias;
                            }
                        }
                        inMeshGroup = false;
                        continue;
                    }
                    lexer.ExpectToken( "weight" );

                    if ( lexer.ReadInt() != weightList.Num() )
                        lexer.Error( Format("Bad VertexWeight Index, should be $*") << weightList.Num() );

                    MD5Weight &weight = weightList.Alloc();
                    weight.jointIndex = lexer.ReadInt();
                    weight.bias = lexer.ReadFloat();
                    ParseVector( lexer, &weight.origin.x, 3 );
                    weight.origin *= MD5_MODEL_SCALE;
                }
            } else {
                if ( String::Icmp( p, "commandline" ) == 0 ) {
                    // Skip value, we don't need it
                    lexer.ReadToken();
                } else if ( String::Icmp( p, "numJoints" ) == 0 ) {
                    numJoints = lexer.ReadInt();
                    if ( numJoints > 0 ) {
                        model->bones.SetGranularity( numJoints );
                        model->bones.CheckSize( numJoints );
                    }
                } else if ( String::Icmp( p, "numMeshes" ) == 0 ) {
                    numMeshes = lexer.ReadInt();
                    if ( numMeshes <= 0 )
                        lexer.Error("Zero meshes");
                    model->meshes.SetGranularity( numMeshes );
                    model->meshes.CheckSize( numMeshes );
                } else if ( String::Icmp( p, "joints" ) == 0 ) {
                    if ( numJoints == -1 )
                        lexer.Error( "numJoins not set!" );

                    lexer.ExpectToken( "{" );
                    inJointGroup = true;
                } else if ( String::Icmp( p, "mesh" ) == 0 ) {
                    if ( numMeshes == -1 )
                        lexer.Error( "numMeshes not set!" );

                    lexer.ExpectToken( "{" );

                    mesh = new MeshAnimated;
                    model->meshes.Append(mesh);

                    if ( fileVersion != MD5_VERSION_QUAKEWARS )
                        mesh->name = Format("mesh $*") << model->meshes.Num();
                    else {
                        lexer.ExpectToken( "name" );
                        mesh->name = lexer.ReadString();
                    }

                    lexer.ExpectToken( "shader" );
                    mesh->material = lexer.ReadString();

                    noAnimate = false;
                    readVertexColor = false;
                    if ( fileVersion == MD5_VERSION_QUAKEWARS ) {
                        lexer.ExpectToken( "flags" );
                        lexer.ExpectToken( "{" );
                        while( !lexer.CheckToken("}") ) {
                            if ( lexer.CheckToken("noAnimate") )
                                noAnimate = true;
                            else if ( lexer.CheckToken("vertexColor") )
                                readVertexColor = true;
                            else
                                lexer.Error( Format("Unknown flag: '$*'") << lexer.ReadString() );
                        }
                    }
                    lexer.ExpectToken( "numverts" );

                    numVerts = lexer.ReadInt();

                    vertexList.Clear();
                    vertexList.CheckSize( numVerts );
                    weightList.Clear();
                    InitVertices( mesh, numVerts );
                    inMeshGroup = true;
                    readMeshVerts = true;
                } else {
                    lexer.Error( Format("Unexpected '$*'") << p );
                }
            }
        }
        if ( inJointGroup || inMeshGroup || numJoints == -1 || numMeshes == -1 )
            throw LexerError( LexerError::END_OF_FILE );
    }
    catch( LexerError err ) {
        delete model;
        String errStr;
        err.ToString( errStr );
        User::Error( ERR_LEXER_FAILURE, errStr.c_str(), filename );
        return NULL;
    }

    if ( !ImportMD5AnimBaseFrame( filenameAnim, model ) )
        return NULL;

    if ( numJoints != model->bones.Num() ) {
        delete model;
        User::Error( ERR_FILE_CORRUPT, "Number of Joints do not match", filename );
        return NULL;
    }
    return model;
}
示例#9
0
int yyFlexLexer::yylex()
	{
	LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
	return 0;
	}
示例#10
0
/*
================
Lexer::ReadString
================
*/
const char *Lexer::ReadString( void ) {
	if ( !ReadToken() )
		throw LexerError( LexerError::END_OF_FILE );
	return token.GetString();
}
示例#11
0
/*
================
Lexer::ExpectToken
================
*/
void Lexer::ExpectToken( const char *string ) {
	if ( !ReadToken() )
		throw LexerError( LexerError::END_OF_FILE );
	if ( String::Icmp( token.GetString(), string ) != 0 )
		throw LexerError( LexerError::MISSING_TOKEN, token.line, string, token.GetString() );
}
示例#12
0
/*
================
Lexer::Error
================
*/
void Lexer::Error( const char *message ) {
	throw LexerError( LexerError::CUSTOM, token.line, message );
}
示例#13
0
 void yyerror(const char * msg)
 {
    LexerError(msg);
 }
/*
================
XDeclParser::Parse
================
*/
void XDeclParser::Parse( Lexer &lexer ) {
	const Token *token;
	String name, value;
	XDeclNode *currentNode = &rootNode;
	XDeclNode *newNode;
	bool getKeyValue = false;
	bool addNode;
	Stack<XDeclNode *> nodeStack;

	const char *p;
	while ( (token = lexer.ReadToken()) != NULL ) {
		p = token->GetString();
		if ( p ) {
			if ( *p == '\0' )
				lexer.Error("Unexpected Empty Token");

			if ( !getKeyValue ) {
				if ( String::Cmp( p, "}" ) == 0 ) {
					currentNode = nodeStack.Top();
					nodeStack.Pop();
				} else {
					name = p;
					addNode = false;
					if ( lexer.CheckToken("=") ) {
						currentNode->dict.Set( name.c_str(), lexer.ReadString() );
						lexer.ExpectToken(";");
					} else if ( lexer.CheckToken("(") ) {
						addNode = true;
						getKeyValue = true;
					} else if ( lexer.CheckToken("{") ) {
						addNode = true;
					} else {
						lexer.Error("Syntax Error, was expecting '(', '=' or '{'");
					}
					if ( addNode ) {
						newNode = allocator.Alloc();
						newNode->name = name;
						currentNode->numChildren++;
						if ( currentNode->firstChild == NULL )
							currentNode->firstChild = newNode;
						else
							currentNode->lastChild->next = newNode;
						currentNode->lastChild= newNode;
						nodeStack.Push( currentNode );
						currentNode = newNode;
					}
				}
			} else  {
				name = p;
				lexer.ExpectToken("=");
				currentNode->dict.Set( name.c_str(), lexer.ReadString() );
				if ( !lexer.CheckToken(",") ) {
					lexer.ExpectToken(")");
					if ( lexer.CheckToken(";") ) {
						currentNode = nodeStack.Top();
						nodeStack.Pop();
						getKeyValue = false;
					} else if ( lexer.CheckToken("{") ) {
						getKeyValue = false;
					} else {
						lexer.Error("Syntax Error, was expecting ';' or '{'");
					}
				}
			}
		}
	}
	if ( getKeyValue || nodeStack.Num() )
		throw LexerError( LexerError::END_OF_FILE );
}