• 一个通用的语法解析器


    //---------------------------------------------------------------------------------------------
    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;
    }
  • 相关阅读:
    ado异常代码含义对照表及SQL Access,oracle 数据类型对照表
    关于同花顺日数据格式
    把自己以前的QQ plan贴一下
    为应用程序制作帮助文件
    [临时]单源最短路径(Dijkstra算法)
    [IDA] 分析for循环的汇编代码
    对 strlen 汇编代码的解释
    [VC6] 在对话框上实现LOGO图片的渐变性切换效果
    [C++]拼图游戏
    使用 ADO 向数据库中存储一张图片
  • 原文地址:https://www.cnblogs.com/len3d/p/355876.html
Copyright © 2020-2023  润新知