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

📄 stategraphparser.cpp

📁 机器人开源项目orocos的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************  tag: Peter Soetens  Mon May 10 19:10:37 CEST 2004  StateGraphParser.cxx                        StateGraphParser.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"#include "StateGraphParser.hpp"#include "CommonParser.hpp"#include "ConditionParser.hpp"#include "CommandParser.hpp"#include "ValueChangeParser.hpp"#include "ProgramGraphParser.hpp"#include "PeerParser.hpp"#include "ArgumentsParser.hpp"#include "StateMachineBuilder.hpp"#include "TaskContext.hpp"#include "StateMachineTask.hpp"#include "CommandComposite.hpp"#include "Exceptions.hpp"#include "AttributeBase.hpp"#include "ConditionTrue.hpp"#include "ConditionInvert.hpp"#include "StateDescription.hpp"#include "ParsedStateMachine.hpp"#include <iostream>#include <functional>#include <algorithm>#include <boost/bind.hpp>#include <boost/lambda/lambda.hpp>#include <boost/call_traits.hpp>#include <iostream>#include <memory>namespace RTT{    using namespace boost;    using namespace detail;    using boost::bind;        using namespace std;    namespace {        enum GraphSyntaxErrors        {            state_expected,            handle_expected,            transition_expected,        };        assertion<GraphSyntaxErrors> expect_state(state_expected);        assertion<GraphSyntaxErrors> expect_handle(handle_expected);        assertion<GraphSyntaxErrors> expect_transition(transition_expected);        assertion<std::string> expect_end("Ending '}' expected ( or could not find out what this line means ).");        assertion<std::string> expect_end_of_state("Exptected ending '}' at end of state ( or could not find out what this line means ).");        assertion<std::string> expect_if("Wrongly formatted \"if ... then select\" clause.");        assertion<std::string> expect_select("'select' statement required after emty transition program.");        assertion<std::string> expect_comma("Expected a comma separator.");        assertion<std::string> expect_ident("Expected a valid identifier.");        assertion<std::string> expect_open("Open brace expected.");        assertion<std::string> expect_eof("Invalid input in file.");        assertion<std::string> expect_eol("Newline expected at end of statement.");        assertion<std::string> expect_semicolon("Semi colon expected after statement.");        assertion<std::string> expect_open_parenth( "Open parenthesis expected." );        assertion<std::string> expect_close_parenth( "Open parenthesis expected." );        assertion<std::string> expect_eventselect("'select' statement required after event or transition program.");        assertion<std::string> expect_eventargs("Could not parse arguments after event.");    }    StateGraphParser::StateGraphParser( iter_t& positer,                                        TaskContext* tc )        : context( tc ),          curobject( 0 ),          mpositer( positer ),          ln_offset(0),          curtemplate(),          curinstantiatedmachine(),          curmachinebuilder( 0 ),          curinitialstateflag( false ),          curfinalstateflag( false ),          curstate( 0 ),          curnonprecstate( 0 ),          progParser( 0 ),          elsestate(0),          curcondition( 0 ),          isroot(false),          selectln(0),          evname(""),          conditionparser( new ConditionParser( context ) ),          commonparser( new CommonParser ),          valuechangeparser( new ValueChangeParser(context) ),          expressionparser( new ExpressionParser(context) ),          argsparser(0),          peerparser( new PeerParser(context, true) ) // full-path peer parser for events.    {        BOOST_SPIRIT_DEBUG_RULE( production );        BOOST_SPIRIT_DEBUG_RULE( rootmachineinstantiation );        BOOST_SPIRIT_DEBUG_RULE( statemachine );        BOOST_SPIRIT_DEBUG_RULE( machineinstantiation );        BOOST_SPIRIT_DEBUG_RULE( statemachinecontent );        BOOST_SPIRIT_DEBUG_RULE( varline );        BOOST_SPIRIT_DEBUG_RULE( state );        BOOST_SPIRIT_DEBUG_RULE( vardec );        BOOST_SPIRIT_DEBUG_RULE( subMachinedecl );        BOOST_SPIRIT_DEBUG_RULE( statecontent );        BOOST_SPIRIT_DEBUG_RULE( statecontentline );        BOOST_SPIRIT_DEBUG_RULE( entry );        BOOST_SPIRIT_DEBUG_RULE( preconditions );        BOOST_SPIRIT_DEBUG_RULE( precondition );        BOOST_SPIRIT_DEBUG_RULE( handle );        BOOST_SPIRIT_DEBUG_RULE( transitions );        BOOST_SPIRIT_DEBUG_RULE( transition );        BOOST_SPIRIT_DEBUG_RULE( exit );        BOOST_SPIRIT_DEBUG_RULE( transline );        BOOST_SPIRIT_DEBUG_RULE( selectcommand );        BOOST_SPIRIT_DEBUG_RULE( brancher );        BOOST_SPIRIT_DEBUG_RULE( selector );        BOOST_SPIRIT_DEBUG_RULE( machineinstarguments );        BOOST_SPIRIT_DEBUG_RULE( machineinstargument );        BOOST_SPIRIT_DEBUG_RULE( machinememvar );        BOOST_SPIRIT_DEBUG_RULE( machinevariable );        BOOST_SPIRIT_DEBUG_RULE( machineparam );        BOOST_SPIRIT_DEBUG_RULE( machineconstant );        BOOST_SPIRIT_DEBUG_RULE( machinealias );        BOOST_SPIRIT_DEBUG_RULE( subMachinevarchange );        production = *( (statemachine[ bind( &StateGraphParser::seenstatemachineend, this ) ]                         >> *( rootmachineinstantiation ))[bind( &StateGraphParser::saveText, this, _1, _2)])                         >> expect_eof(end_p);        rootmachineinstantiation =            str_p("RootMachine")[bind (&StateGraphParser::startrootmachineinstantiation, this) ]            >> machineinstantiation[ bind( &StateGraphParser::seenrootmachineinstantiation, this ) ];        statemachine =            str_p("StateMachine") //[bind( &StateGraphParser::storeOffset, this)]            >> expect_ident( commonparser->identifier[ bind( &StateGraphParser::seenstatemachinename, this, _1, _2 )] )            >> expect_open( ch_p( '{' ) )            >> statemachinecontent            >> expect_end( ch_p( '}' ) );        // Zero or more declarations and Zero or more states        statemachinecontent = *( varline | state );        varline = vardec[lambda::var(eol_skip_functor::skipeol) = false] >> commonparser->eos[lambda::var(eol_skip_functor::skipeol) = true];        vardec = subMachinedecl | machinememvar | machineparam;        machinememvar = ( machineconstant | machinevariable | machinealias )[bind( &StateGraphParser::seenmachinevariable, this )];        machineconstant = valuechangeparser->constantDefinitionParser();        machinevariable = valuechangeparser->variableDefinitionParser();        machinealias = valuechangeparser->aliasDefinitionParser();        machineparam = valuechangeparser->paramDefinitionParser()[bind( &StateGraphParser::seenmachineparam, this )];        subMachinedecl = str_p("SubMachine")                         >> machineinstantiation[bind( &StateGraphParser::seensubMachineinstantiation, this )];        machineinstantiation =            expect_ident( commonparser->identifier[ bind( &StateGraphParser::seenmachinetypename, this, _1, _2 )] )            >> expect_ident( commonparser->identifier[ bind( &StateGraphParser::seeninstmachinename, this, _1, _2 )] )            >> ( ! ( ch_p( '(' )                     >> !machineinstarguments                     >> expect_close_parenth( ch_p( ')' ) ) ) )[ bind( &StateGraphParser::seenmachineinstantiation, this )];        machineinstarguments =            machineinstargument >> *( ',' >> machineinstargument );        machineinstargument =            commonparser->identifier[ bind( &StateGraphParser::seenmachineinstargumentname, this, _1, _2 )]            >> '='            >> expressionparser->parser()[ bind( &StateGraphParser::seenmachineinstargumentvalue, this )];        state =          !( str_p( "initial" )[bind( &StateGraphParser::seeninitialstate,this )]             | str_p( "final" )[bind( &StateGraphParser::seenfinalstate,this )] )          >> str_p( "state" )          >> expect_ident(commonparser->identifier[ bind( &StateGraphParser::statedef, this, _1, _2 ) ])          >> expect_open(ch_p( '{' ))          >> statecontent          >> expect_end_of_state(ch_p( '}' ))[ bind( &StateGraphParser::seenstateend, this ) ];        // the content of a program can be any number of lines        // a line is not strictly defined in the sense of text-line.        statecontent = *statecontentline;        // a state can contain various programs and variable definitions        statecontentline =            entry            | preconditions            | run            | handle            | transitions            | exit            | machinememvar[lambda::var(eol_skip_functor::skipeol) = false] >> commonparser->eos[lambda::var(eol_skip_functor::skipeol) = true];        precondition = str_p( "precondition")            >> conditionparser->parser()[ bind( &StateGraphParser::seenprecondition, this)] ;        preconditions = (str_p( "preconditions" )[ bind( &StateGraphParser::inpreconditions, this )]                        >> expect_open( ch_p( '{' ))                        >> *transline                        >> expect_end( ch_p( '}' ) )[                            bind( &StateGraphParser::seenpreconditions, this )]) | precondition;        entry = str_p( "entry" )[ bind( &StateGraphParser::inprogram, this, "entry" )]                >> expect_open(ch_p('{'))>> programBody >> expect_end(ch_p('}'))[                    bind( &StateGraphParser::seenentry, this )];        run = str_p( "run" )[ bind( &StateGraphParser::inprogram, this, "run" )]                 >> expect_open(ch_p('{'))>> programBody >> expect_end(ch_p('}'))[                     bind( &StateGraphParser::seenrun, this )];        exit = str_p( "exit" )[ bind( &StateGraphParser::inprogram, this, "exit" )]               >> expect_open(ch_p('{')) >> programBody >> expect_end(ch_p('}'))[                   bind( &StateGraphParser::seenexit, this )];        handle = str_p( "handle" )[ bind( &StateGraphParser::inprogram, this, "handle" )]                 >> expect_open(ch_p('{'))>> programBody >> expect_end(ch_p('}'))[                     bind( &StateGraphParser::seenhandle, this )];        // event based transition        transition = str_p("transition")            >> !peerparser->parser() >> expect_ident(commonparser->identifier[ bind( &StateGraphParser::seeneventname, this,_1,_2)])            >> expect_eventargs(argslist[ bind( &StateGraphParser::seeneventargs, this)])            >> expect_eventselect(selectcommand[ bind( &StateGraphParser::seeneventtrans, this)]);        // condition based transition.        // the order of rule "transition" vs "transitions" is important        transitions = ( str_p( "transitions" )                        >> expect_open(ch_p('{'))>> *transline >> expect_end(ch_p('}')) ) | transition;        transline = selectcommand;        // You are only allowed to select a new state in transitions :        selectcommand = (brancher | selector)[bind(&StateGraphParser::seenendcondition,this)];        brancher = str_p( "if") >> conditionparser->parser()[ bind( &StateGraphParser::seencondition, this)]                                >> expect_if(str_p( "then" ))                                >> !transprog                                >> !selector                                >> !(str_p("else")[bind( &StateGraphParser::seenelse, this )] >> expect_select( (elseprog >> !selector) | selector));        transprog =            ch_p('{')[ bind( &StateGraphParser::inprogram, this, "transition" )]                >> programBody                >> expect_end(ch_p('}'))[bind( &StateGraphParser::seentransprog, this )];        elseprog =             ch_p('{')[ bind( &StateGraphParser::inprogram, this, "elsetransition" )]                >> programBody                >> expect_end(ch_p('}'))[bind( &StateGraphParser::seenelseprog, this )];        selector = str_p( "select" ) >> ( commonparser->identifier[ bind( &StateGraphParser::seenselect, this, _1, _2) ]                                          >> *("or" >> commonparser->identifier[ bind( &StateGraphParser::seenselect, this, _1, _2) ])                                          )[lambda::var(eol_skip_functor::skipeol) = false]                                     >> commonparser->eos[lambda::var(eol_skip_functor::skipeol) = true]; // if eos fails skipeol stays false !, see cleanup() !    }    void StateGraphParser::seeninitialstate()    {        curinitialstateflag = true;    }    void StateGraphParser::seenfinalstate()    {        curfinalstateflag = true;    }    void StateGraphParser::statedef( iter_t s, iter_t f)    {        assert( !curstate );        std::string def(s, f);        if ( curtemplate->getState( def ) != 0 )        {            assert( dynamic_cast<StateDescription*>( curtemplate->getState( def ) ) );            StateDescription* existingstate = static_cast<StateDescription*>( curtemplate->getState( def ) );            if ( existingstate->isDefined() )                ORO_THROW(parse_exception_semantic_error("state " + def + " redefined.") );            else                curstate = existingstate;            curstate->setEntryPoint( mpositer.get_position().line - ln_offset );        }        else        {            curstate = new StateDescription(def, curtemplate->getTaskObject()->engine()->programs(), mpositer.get_position().line - ln_offset ); // create an empty state            curtemplate->addState( curstate );        }

⌨️ 快捷键说明

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