⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 2009 ROBOCUP 仿真2DSERVER 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// -*-c++-*-/***************************************************************************                                parser.cpp                          Parser for config options                             -------------------    begin                : 15-MAY-2003    copyright            : (C) 2003 by The RoboCup Soccer Server                           Maintenance Group.    email                : sserver-admin@lists.sourceforge.net***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU LGPL as published by the Free Software  * *   Foundation; either version 2 of the License, or (at your option) any  * *   later version.                                                        * *                                                                         * ***************************************************************************/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "parser.hpp"#include "builder.hpp"#ifdef HAVE_SSTREAM#include <sstream>#else#include <strstream>#endif#include <iterator>#include <cerrno>#include <climits>#include <boost/filesystem/operations.hpp>#include <boost/filesystem/fstream.hpp>#include <boost/filesystem/exception.hpp>// #define BOOST_SPIRIT_DEBUG#include <boost/spirit.hpp>#include <boost/function.hpp>#include <boost/bind.hpp>namespace {boolisQuated( const std::string & str ){    return ( str.length() >= 2             && ( ( *str.begin() == '\"' && *str.rbegin() == '\"' )                  || ( *str.begin() == '\'' && *str.rbegin() == '\'' )                  )             );}std::stringcleanString( std::string str ){    if ( str.empty() )    {        return str;    }    if ( *str.begin() == '\'' )    {        if ( *str.rbegin() == '\''  )        {            str = str.substr( 1, str.length() - 2 );        }        else        {            return str;        }        for ( std::string::size_type esc = str.find( "\\'" );              esc != std::string::npos;              esc = str.find( "\\'" ) )        {            str.replace( esc, 2, "'" );        }    }    else if ( *str.begin() == '"' )    {        if ( *str.rbegin() == '"'  )        {            str = str.substr( 1, str.length() - 2 );        }        else        {            return str;        }        for ( std::string::size_type esc = str.find( "\\\"" );              esc != std::string::npos;              esc = str.find( "\\\"" ) )        {            str.replace( esc, 2, "\"" );        }    }    return str;}std::stringcleanString( const char * begin,             const char * end ){    return cleanString( std::string( begin, end ) );}}namespace rcss {namespace conf {const char * Parser::ErrorStrs[] = { "None",                                     "'=' expected",                                     "'::' expected",                                     "value expected",                                     "string expected" };class ParseErrorHandler {public:    static    boost::spirit::error_status<> parseError( const Parser * parser,                                              const boost::spirit::rule<>::scanner_t & scanner,                                              const boost::spirit::parser_error< Parser::Errors > & error )      {          std::string what;          if ( error.where + 10 > scanner.last )          {              what = std::string( error.where, scanner.last );          }          else          {              what = std::string( error.where,                                  error.where + 10 );          }          std::string::iterator newline = std::find( what.begin(),                                                     what.end(),                                                     '\n' );          if ( newline != what.end() )          {              what = std::string( what.begin(), newline );          }          parser->m_builder.parseError( what,                                        Parser::ErrorStrs[ error.descriptor ],                                        parser->m_stack.front().m_name,                                        parser->m_stack.front().m_lineno );          return boost::spirit::error_status<>( boost::spirit::error_status<>::fail );      }};Parser::Parser( Builder & builder )    : m_builder( builder ){    m_builder.addedToParser( *this );}Parser::~Parser(){    m_builder.removedFromParser();}boolParser::parse( int argc,               const char * const * argv ){#ifdef HAVE_SSTREAM    std::stringstream strm;#else    std::strstream strm;#endif    if ( argc > 1 )    {        std::string arg( argv[1] );        if ( arg.find_first_of( " \t" ) != std::string::npos             && ! isQuated( arg ) )        {            strm << "\'" << arg << "\'";        }        else        {            strm << arg;        }    }    for ( int i = 2; i < argc; ++i )    {        std::string arg( argv[i] );        if ( arg.find_first_of( " \t" ) != std::string::npos             && ! isQuated( arg ) )        {            strm << ' ' << '\'' << arg << '\'';        }        else        {            strm << ' ' << arg;        }    }#ifndef HAVE_SSTREAM    strm << std::ends;#else    strm << std::flush;#endif    bool res = rcss::Parser::parse( strm, "cmd line args" );#ifndef HAVE_SSTREAM    strm.freeze( false );#endif    return res;}boolParser::parse( std::istream & strm ){    return rcss::Parser::parse( strm );}boolParser::parse( std::istream & strm,               const std::string & name ){    return rcss::Parser::parse( strm, name );}boolParser::parse( const boost::filesystem::path & file ){    return rcss::Parser::parse( file );}boolParser::parseCreateConf( const boost::filesystem::path & conf_name,                         const std::string & module_name ){    std::string native_path = conf_name.native_file_string();    boost::filesystem::ifstream conf( conf_name );    if ( ! conf.is_open() )    {        m_builder.creatingConfFile( native_path );        boost::filesystem::ofstream new_conf( conf_name );        if ( new_conf.is_open() )        {            m_builder.createConfFile( new_conf, module_name );            new_conf.close();            m_builder.createdConfFile( native_path );            return true;        }        else        {            std::cerr << "is not opened. Parser::parseCreateConf " << native_path << std::endl;            m_builder.confCreationFailed( native_path, errno );            return false;        }    }    else    {        bool rval = parse( conf, native_path );        conf.close();        return rval;    }}boolParser::doParse( std::istream & strm ){    m_builder.reset();    m_stack.push_front( StreamState( strm,  getStreamName(), 1 ) );    bool rval = boostParse();    m_stack.pop_front();    rval = rval && m_builder.success();    return rval;}voidParser::countNewLines( const char * begin,                       const char * end ){    int count = 0;    for ( const char * i = begin; i != end; ++i )    {        if ( '\n' == *i )        {            ++count;        }    }    if ( ! m_stack.empty() )    {        m_stack.front().m_lineno += count;    }}boolParser::include( const char * begin,                 const char * end ){    std::string incname = cleanString( begin, end );    boost::filesystem::path path;    try    {        path = boost::filesystem::path( incname,                                        &boost::filesystem::native );    }    catch(...)    {        try        {            path = boost::filesystem::path( incname );        }        catch ( const std::exception & e )        {            m_builder.includeFailed( incname,                                     e.what(),                                     m_stack.front().m_name,                                     m_stack.front().m_lineno );            return false;        }    }    boost::filesystem::path full_name;    if ( path.has_root_directory() )    {        full_name = path;    }    else    {        const std::string & curr_path = m_stack.front().m_name;        if ( curr_path.empty()             || curr_path == "cmd line args"             || curr_path == "anonymous stream" )        {            full_name = complete( path );        }        else        {            boost::filesystem::path branch( curr_path,                                            boost::filesystem::native );            branch = branch.branch_path();            full_name = branch / path;        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -