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

📄 expressionparser.cpp

📁 机器人开源项目orocos的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  tag: Peter Soetens  Mon May 10 19:10:37 CEST 2004  ExpressionParser.cxx                        ExpressionParser.cxx -  description                           -------------------    begin                : Mon May 10 2004    copyright            : (C) 2004 Peter Soetens    email                : peter.soetens@mech.kuleuven.ac.be *************************************************************************** *   This library is free software; you can redistribute it and/or         * *   modify it under the terms of the GNU Lesser General Public            * *   License as published by the Free Software Foundation; either          * *   version 2.1 of the License, or (at your option) any later version.    * *                                                                         * *   This library is distributed in the hope that it will be useful,       * *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     * *   Lesser General Public License for more details.                       * *                                                                         * *   You should have received a copy of the GNU Lesser General Public      * *   License along with this library; if not, write to the Free Software   * *   Foundation, Inc., 59 Temple Place,                                    * *   Suite 330, Boston, MA  02111-1307  USA                                * *                                                                         * ***************************************************************************/#include "parser-debug.hpp"#include "parse_exception.hpp"#ifdef ORO_PRAGMA_INTERFACE#pragma implementation#endif#include "ExpressionParser.hpp"//#include "DumpObject.hpp"#include "ArgumentsParser.hpp"#include <Operators.hpp>#include <DataSourceCondition.hpp>#include "DataSourceTime.hpp"#include "TaskContext.hpp"#include "PeerParser.hpp"#include "Types.hpp"#include <boost/lambda/lambda.hpp>#include <boost/bind.hpp>#include "../rtt-config.h"#include <iostream>namespace RTT{    using boost::bind;        using namespace detail;    using namespace std;    namespace {        assertion<std::string> expect_open("Open brace expected.");        assertion<std::string> expect_close("Closing brace expected ( or could not find out what this line means ).");        assertion<std::string> expect_type("Unknown type. Please specify a type.");        assertion<std::string> expect_expr("Expected a valid expression.");        assertion<std::string> expect_ident("Expected a valid identifier.");        assertion<std::string> expect_init("Expected an initialisation value of the value.");        assertion<std::string> expect_comma("Expected the ',' separator after expression.");        assertion<std::string> expect_timespec("Expected a time specification (e.g. > 10s or > varname ) after 'time' .");        guard<std::string> my_guard;    }  DataCallParser::DataCallParser( ExpressionParser& p, TaskContext* c )      : expressionparser( p ), peerparser( c )  {    BOOST_SPIRIT_DEBUG_RULE( datacall );    BOOST_SPIRIT_DEBUG_RULE( arguments );    // this parser uses a neat boost.spirit trick to avoid keeping    // loads of stacks for all parsing data ( this parser needs to be    // reentrant because it can be called while parsing an argument of    // a datacall, which has itself been called while parsing an    // argument of a datacall... ).  Boost.Spirit allows you to change    // the parser that a rule points to at runtime, so we only create    // the parser just before it's going to be used, when we know what    // arguments we want..  See the ArgumentsParser doc for more    // details..    datacall =         ( peerparser.locator() >>          !(commonparser.identifier >> ".") >>   // just consume, peer locator already has object name          expect_ident(commonparser.identifier)[bind( &DataCallParser::seenmethodname, this, _1, _2 ) ]          [ bind( &DataCallParser::seendataname, this ) ]          >> !arguments          )[ bind( &DataCallParser::seendatacall, this ) ];  };  void DataCallParser::seendataname()  {      mobject =  peerparser.object();      TaskContext* peer = peerparser.peer();      OperationInterface* ops  = peerparser.taskObject();      peerparser.reset();      // Check if it is a constructor      if ( mobject == "this" && TypeInfoRepository::Instance()->type( mmethod ) ) {          // it is...      } else {          // it ain't...          //cout << "DCP saw method "<< mmethod <<" of object "<<mobject<<" of peer "<<peer->getName()<<endl;          // this is slightly different from CommandParser          if ( ops == 0 ) {              //DumpObject( peer );              throw_( iter_t(), std::string("Task '")+peer->getName()+"' has no object '"+mobject+"'." );          }          if ( ops->methods()->hasMember(mmethod) == false ) {              //DumpObject( peer );              if ( mobject != "this" )                  throw parse_exception_no_such_method_on_component( "DataCall::"+mobject, mmethod );              else                  throw parse_exception_no_such_method_on_component( "DataCall::"+peer->getName(), mmethod );          }      }                 // create an argument parser for the call..      // Store everything in the ArgumentsParser ! This DataCallParser instance is recursively called !      ArgumentsParser* argspar =          new ArgumentsParser( expressionparser, peer, ops,                               mobject, mmethod );      // we no longer need these two..      mobject.clear();      mmethod.clear();      // keep hold of the argspar, we're still going to need it after      // it's done its work..  ( in seendatacall(), that is.. )      argparsers.push( argspar );      // set the arguments parser to the parser provided by the      // ArgumentsParser we just created..      arguments = argspar->parser();  }  void DataCallParser::seendatacall()  {    ArgumentsParser* argspar = argparsers.top();    argparsers.pop();    std::string obj = argspar->objectname();    std::string meth = argspar->methodname();    std::vector<DataSourceBase::shared_ptr> args = argspar->result();    OperationInterface* peer = argspar->object();    delete argspar;    // separate track if we are handling a constructor:    if ( obj == "this" && TypeInfoRepository::Instance()->type( meth ) ) {        log(Info) << "Looking for constructor "<<meth<<" with "<< args.size() << " Args."<<endlog();         ret = TypeInfoRepository::Instance()->type( meth )->construct( args );        if (!ret) {            log(Error) << " no such constructor ! "<< endlog();            throw parse_exception_no_such_constructor( meth, args );        }    } else {        // plain method:        OperationInterface* ops = peer;        // we already checked for the existence of this object and method        // in seendataname()..        try {            ret = ops->methods()->produce( meth, args );        }        catch( const wrong_number_of_args_exception& e )            {                throw parse_exception_wrong_number_of_arguments                    (obj, meth, e.wanted, e.received );            }        catch( const wrong_types_of_args_exception& e )            {                throw parse_exception_wrong_type_of_argument                    (obj, meth, e.whicharg, e.expected_, e.received_ );            }        catch(...) {            assert(false);        }    }    assert( ret.get() );  }  DataCallParser::~DataCallParser()  {    // if argparsers is not empty, then something went wrong during    // the parsing ( someone threw an exception ), and we're    // responsible for cleaning up the argparsers we created..    while ( ! argparsers.empty() )    {      delete argparsers.top();      argparsers.pop();    };  };    error_status<> handle_no_value(scanner_t const& scan, parser_error<std::string, iter_t>& e )    {        //std::cerr << "No value in EP : "<<e.descriptor<<std::endl;        // retry if it is a datacall, thus fail this rule        return error_status<>( error_status<>::fail );    }    error_status<> handle_no_datacall(scanner_t const& scan, parser_error<std::string, iter_t>&e )    {        // retry with a member :        //std::cerr << "No DataCall in EP : "<<e.descriptor<<std::endl;        return error_status<>( error_status<>::fail );    }    error_status<> handle_no_member(scanner_t const& scan, parser_error<std::string, iter_t>&e )    {        // if this rule also fails, throw semantic exception ( member not found )        throw parse_exception_semantic_error( e.descriptor );        // dough ! not reached :        return error_status<>( error_status<>::rethrow );    }  ExpressionParser::ExpressionParser( TaskContext* pc )      : datacallparser( *this, pc ),        valueparser( pc ),        _invert_time(false),        opreg( OperatorRepository::Instance() )  {    BOOST_SPIRIT_DEBUG_RULE( expression );    BOOST_SPIRIT_DEBUG_RULE( unarynotexp );    BOOST_SPIRIT_DEBUG_RULE( unaryminusexp );    BOOST_SPIRIT_DEBUG_RULE( unaryplusexp );    BOOST_SPIRIT_DEBUG_RULE( multexp );    BOOST_SPIRIT_DEBUG_RULE( divexp );    BOOST_SPIRIT_DEBUG_RULE( modexp );    BOOST_SPIRIT_DEBUG_RULE( plusexp );    BOOST_SPIRIT_DEBUG_RULE( minusexp );    BOOST_SPIRIT_DEBUG_RULE( smallereqexp );    BOOST_SPIRIT_DEBUG_RULE( smallerexp );    BOOST_SPIRIT_DEBUG_RULE( greatereqexp );    BOOST_SPIRIT_DEBUG_RULE( greaterexp );    BOOST_SPIRIT_DEBUG_RULE( equalexp );    BOOST_SPIRIT_DEBUG_RULE( notequalexp );    BOOST_SPIRIT_DEBUG_RULE( orexp );    BOOST_SPIRIT_DEBUG_RULE( andexp );    BOOST_SPIRIT_DEBUG_RULE( ifthenelseexp );    BOOST_SPIRIT_DEBUG_RULE( groupexp );    BOOST_SPIRIT_DEBUG_RULE( dotexp );    BOOST_SPIRIT_DEBUG_RULE( atomicexpression );    BOOST_SPIRIT_DEBUG_RULE( time_expression );    BOOST_SPIRIT_DEBUG_RULE( time_spec );    BOOST_SPIRIT_DEBUG_RULE( indexexp );    BOOST_SPIRIT_DEBUG_RULE( comma );    BOOST_SPIRIT_DEBUG_RULE( close_brace );

⌨️ 快捷键说明

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