zoukankan      html  css  js  c++  java
  • 一个通用的语法解析器

    //---------------------------------------------------------------------------------------------
    Parser::Parser()
    {
    }

    //---------------------------------------------------------------------------------------------
    Parser::~Parser()
    {
    }

    //---------------------------------------------------------------------------------------------
    int Parser::Call(int id, std::vector<std::string> & args)
    {
        
    switch( id ) {
        
    case 1:        return g_Renderer->world_begin();
        
    case 2:        return g_Renderer->world_end();
        
    case 3:        return g_Renderer->frame_begin();
        
    case 4:        return g_Renderer->frame_end();
        
    case 5:        return g_Renderer->group_begin( AsString(args[0]) );
        
    case 6:        return g_Renderer->group_end();
        
    case 7:        return g_Renderer->init_instance( AsString(args[0]) );
        
    case 8:        return g_Renderer->object_begin( AsString(args[0]), AsString(args[1]) );
        
    case 9:        return g_Renderer->object_end();
        
    case 10:    return g_Renderer->motion_begin();
        
    case 11:    return g_Renderer->motion_end();
        
    case 12:    return g_Renderer->vertex( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]),
                                                AsFloat(args[
    3]), AsFloat(args[4]) );
        
    case 13:    return g_Renderer->vertex( AsInteger(args[0]) );
        
    case 14:    return g_Renderer->normal( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
        
    case 15:    return g_Renderer->primitive_begin( AsString(args[0]) );
        
    case 16:    return g_Renderer->primitive_end();
        
    case 17:    return g_Renderer->texture( AsString(args[0]), AsString(args[1]) );
        
    case 18:    return g_Renderer->translate( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
        
    case 19:    return g_Renderer->rotate( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
        
    case 20:    return g_Renderer->scale( AsFloat(args[0]), AsFloat(args[1]), AsFloat(args[2]) );
        
    case 21:    return g_Renderer->material_begin( AsString(args[0]) );
        
    case 22:    return g_Renderer->material_end();
        
    case 23:    return g_Renderer->light_begin( AsString(args[0]), AsString(args[1]) );
        
    case 24:    return g_Renderer->light_end();
        
    case 25:    return g_Renderer->select_group( AsString(args[0]) );
        
    case 26:    return g_Renderer->delete_group( AsString(args[0]) );
        
    case 27:    return g_Renderer->select_object( AsString(args[0]) );
        
    case 28:    return g_Renderer->delete_object( AsString(args[0]) );
        
    case 29:    return g_Renderer->select_material( AsString(args[0]) );
        
    case 30:    return g_Renderer->delete_material( AsString(args[0]) );
        
    case 31:    return g_Renderer->select_light( AsString(args[0]) );
        
    case 32:    return g_Renderer->select_light( AsString(args[0]) );
        
    case 33:    return g_Renderer->select_end();
        
    default:
            
    return FALSE;
        }

    }

    //---------------------------------------------------------------------------------------------
    int Parser::SetOption(int id, std::string & value)
    {
        
    if( id >= FLOAT_OPTION_BEGIN && id <= FLOAT_OPTION_END )
            
    return g_Renderer->set_option( id, AsFloat(value) );
        
    else if( id >= INTEGER_OPTION_BEGIN && id <= INTEGER_OPTION_END )
            
    return g_Renderer->set_option( id, AsInteger(value) );
        
    else if( id >= STRING_OPTION_BEGIN && id <= STRING_OPTION_END )
            
    return g_Renderer->set_option( id, AsString(value) );
        
    else if( id >= BOOLEAN_OPTION_BEGIN && id <= BOOLEAN_OPTION_END )
            
    return g_Renderer->set_option( id, AsBoolean(value) );
        
    else {
            std::vector
    <float>    vec;
            AsVector( value, vec );
            
    switch( vec.size() ) {
            
    case 2:
                
    return g_Renderer->set_option( id, vec[0], vec[1] );
            
    case 3:
                
    return g_Renderer->set_option( id, vec[0], vec[1], vec[2] );
            
    case 4:
                
    return g_Renderer->set_option( id, vec[0], vec[1], vec[2], vec[3] );
            
    default:
                
    return FALSE;
            }

        }

    }

    //---------------------------------------------------------------------------------------------
    int Parser::SetParameter(const char *name, std::string & value)
    {
        
    int    ret = TRUE;
        
    if( (ret = g_Renderer->set_parameter( name, AsFloat(value) )) != TRUE ) {
            
    if( (ret = g_Renderer->set_parameter( name, AsInteger(value) )) != TRUE ) {
                
    if( (ret = g_Renderer->set_parameter( name, AsBoolean(value) )) != TRUE ) {
                    
    if( (ret = g_Renderer->set_parameter( name, AsString(value) )) != TRUE ) {
                        std::vector
    <float>    vec;
                        AsVector( value, vec );
                        
    switch( vec.size() ) {
                        
    case 2:
                            ret 
    = g_Renderer->set_parameter( name, vec[0], vec[1] );
                            
    break;
                        
    case 3:
                            ret 
    = g_Renderer->set_parameter( name, vec[0], vec[1], vec[2] );
                            
    break;
                        
    case 4:
                            ret 
    = g_Renderer->set_parameter( name, vec[0], vec[1], vec[2], vec[3] );
                            
    break;
                        
    default:
                            
    return FALSE;
                        }

                    }

                }

            }

        }

        
    return ret;
    }

    //---------------------------------------------------------------------------------------------
    int Parser::Load(const char *name)
    {
        std::ifstream    file( name );
        
    if!file )
            
    return FALSE;
        std::
    string        cstr;
        size_t            pos 
    = 0;
        
    int                ret = TRUE;
        keepOnLoading 
    = true;
        
    while( keepOnLoading && ReadString( file, cstr ) ) {
            g_Window
    ->print( cstr.c_str() );
            
    if( (pos = cstr.find( KEYWORD_COMMENT )) != std::string::npos )
                cstr 
    = cstr.substr( 0, pos );
            TrimLeft( cstr );
            TrimRight( cstr );
            
    if( cstr.empty() )
                
    continue;
            cstr 
    += KEYWORD_NEWLINE;
            std::vector
    <std::string>    args;
            size_t                        len;
            
    for(int i = 0; i < FUNCTION_AMOUNT; ++i) {
                len 
    = strlen( SDL[i].name );
                
    if( cstr.substr( 0, len ) == SDL[i].name ) {
                    
    if( i == 20 /* material */ && g_Renderer->objectBegin )
                        
    break;
                    
    else if( i == 11 /* vertex */ && g_Renderer->primitiveBegin )
                        
    continue;
                    
    if( cstr[len] == KEYWORD_ARGUMENT_BEGIN1 ||
                        cstr[len] 
    == KEYWORD_ARGUMENT_BEGIN2 ||
                        cstr[len] 
    == KEYWORD_NEWLINE ) {
                        std::
    string        para, sect;
                        para 
    = cstr.substr( len + 1, cstr.length() - len - 1 );
                        
    for(int j = 0; j < (int) para.length(); ++j) {
                            
    if( para[j] != KEYWORD_ARGUMENT_DELIMITER &&
                                para[j] 
    != KEYWORD_ARGUMENT_END )
                                sect 
    += para[j];
                            
    else {
                                args.push_back( sect );
                                sect.clear();
                            }

                        }

                        
    if!args.empty() ) {
                            
    for(int j = 0; j < (int) args.size() - 1++j) {
                                TrimLeft( args[j] );
                                TrimRight( args[j] );
                            }

                            TrimLeft( args.back() );
                        }

                        
    if( args.size() == SDL[i].noArg ) {
                            
    if( (ret = Call( i + 1, args )) != TRUE )
                                
    goto OPTIONS;
                            
    else
                                
    goto END_OF_LOOP;
                        }

                    }

                }

            }

    OPTIONS:
            
    for(int i = 0; i < OPTION_AMOUNT; ++i) {
                len 
    = strlen( OptMap[i].name );
                
    if( cstr.substr( 0, len ) == OptMap[i].name ) {
                    
    for(int j = (int) len; j < (int) cstr.length(); ++j) {
                        
    if( cstr[j] != KEYWORD_SPACE1 &&
                            cstr[j] 
    != KEYWORD_SPACE2 &&
                            cstr[j] 
    != KEYWORD_SPACE3 &&
                            cstr[j] 
    != KEYWORD_SET1    &&
                            cstr[j] 
    != KEYWORD_SET2 ) {
                            
    goto END_OF_LOOP;
                        }
     else if( cstr[j] == KEYWORD_SET1 || cstr[j] == KEYWORD_SET2 ) {
                            std::
    string        value;
                            value 
    = cstr.substr( j + 1, cstr.length() - j - 1 );
                            TrimLeft( value );
                            
    if( (ret = SetOption( OptMap[i].id, value )) != TRUE )
                                
    goto PARAMETERS;
                            
    else
                                
    goto END_OF_LOOP;
                        }

                    }

                }

            }

    PARAMETERS:
            
    if( (pos = cstr.find( KEYWORD_CUSTOM_SET )) != std::string::npos ) {
                std::
    string        value;
                value 
    = cstr.substr( pos + 1, cstr.length() - pos - 1 );
                cstr 
    = cstr.substr( 0, pos );
                TrimLeft( cstr );
                TrimRight( cstr );
                TrimLeft( value );
                TrimRight( value );
                
    if( (ret = SetParameter( cstr.c_str(), value )) != TRUE ) {
                    
    return ret;
                }

            }
     else
                
    return FALSE;
    END_OF_LOOP:;
        }
    ;
        
    return TRUE;
    }

    //---------------------------------------------------------------------------------------------
    bool Parser::ReadString(std::ifstream & file, std::string & str)
    {
        str.clear();
        
    char    ch;
        
    while( file.get(ch) ) {
            
    if( ch == KEYWORD_NEWLINE )
                
    return true;
            str 
    += ch;
        }
    ;
        
    return false;
    }

    //---------------------------------------------------------------------------------------------
    void Parser::TrimLeft(std::string & str)
    {
        
    for(int i = 0; i < (int) str.length(); ++i) {
            
    if( str[i] != KEYWORD_SPACE1 && str[i] != KEYWORD_SPACE2 && str[i] != KEYWORD_SPACE3 ) {
                str.erase( 
    0, i );
                
    return;
            }

        }

        str.clear();
    }

    //---------------------------------------------------------------------------------------------
    void Parser::TrimRight(std::string & str)
    {
        
    for(int i = (int) str.length() - 1; i >= 0--i) {
            
    if( str[i] != KEYWORD_SPACE1 && str[i] != KEYWORD_SPACE2 && str[i] != KEYWORD_SPACE3 ) {
                str.erase( i 
    + 1, str.length() - i - 1 );
                
    return;
            }

        }

        str.clear();
    }

    //---------------------------------------------------------------------------------------------
    float Parser::AsFloat(const std::string & str)
    {
        
    return (float) atof( str.c_str() );
    }

    //---------------------------------------------------------------------------------------------
    int Parser::AsInteger(const std::string & str)
    {
        
    return atoi( str.c_str() );
    }

    //---------------------------------------------------------------------------------------------
    bool Parser::AsBoolean(std::string & str)
    {
        
    if( str[str.length() - 1== KEYWORD_NEWLINE )
            str.erase( str.end() 
    - 1 );
        
    if( str == KEYWORD_TRUE1 || str == KEYWORD_TRUE2 )
            
    return true;
        
    else
            
    return false;
    }

    //---------------------------------------------------------------------------------------------
    const char *Parser::AsString(std::string & str)
    {
        
    if( str[str.length() - 1== KEYWORD_NEWLINE )
            str.erase( str.end() 
    - 1 );
        
    if( str[0== KEYWORD_STRING_BEGIN && str[str.length() - 1== KEYWORD_STRING_END ) {
            str.erase( str.begin() );
            str.erase( str.end() 
    - 1 );
            
    return str.c_str();
        }
     else
            
    return NULL;
    }

    //---------------------------------------------------------------------------------------------
    bool Parser::AsVector(std::string & str, std::vector<float> & vec)
    {
        
    if( str[str.length() - 1== KEYWORD_NEWLINE )
            str.erase( str.end() 
    - 1 );
        
    if( str[0== KEYWORD_VECTOR_BEGIN && str[str.length() - 1== KEYWORD_VECTOR_END ) {
            std::
    string        sect;
            
    for(int i = 1; i < (int) str.length(); ++i) {
                
    if( str[i] != KEYWORD_VECTOR_DELIMITER &&
                    str[i] 
    != KEYWORD_VECTOR_END )
                    sect 
    += str[i];
                
    else {
                    vec.push_back( (
    float) atof( sect.c_str() ) );
                    sect.clear();
                }

            }

            
    return true;
        }
     else
            
    return false;
    }
  • 相关阅读:
    HDU 1010 Tempter of the Bone(DFS剪枝)
    HDU 1013 Digital Roots(九余数定理)
    HDU 2680 Choose the best route(反向建图最短路)
    HDU 1596 find the safest road(最短路)
    HDU 2072 单词数
    HDU 3790 最短路径问题 (dijkstra)
    HDU 1018 Big Number
    HDU 1042 N!
    NYOJ 117 求逆序数 (树状数组)
    20.QT文本文件读写
  • 原文地址:https://www.cnblogs.com/len3d/p/355876.html
Copyright © 2011-2022 走看看