📄 stategraphparser.cpp
字号:
clear(); throw file_parse_exception( e.copy(), mpositer.get_position().file, mpositer.get_position().line, mpositer.get_position().column ); }// catch( ... ) {// assert( false );// } } StateGraphParser::~StateGraphParser() { clear(); delete commonparser; delete valuechangeparser; delete expressionparser; delete conditionparser; delete peerparser; } void StateGraphParser::clear() { // remove tmp vars from TaskContext valuechangeparser->reset(); // in case of corrupt file, skipeol could have remained on false, // so make sure it is set correctly again (I hate this global variable approach, it should be a member of commonparser !) eol_skip_functor::skipeol = true; selectln = 0; transProgram.reset(); elseProgram.reset(); delete argsparser; argsparser = 0; delete curcondition; curcondition = 0; // we own curstate, but not through this pointer... curstate = 0; delete curnonprecstate; curnonprecstate = 0; // we own curmachinebuilder, but not through this pointer... curmachinebuilder = 0; curinstantiatedmachine.reset(); // If non null, there was a parse-error, undo all : if ( curtemplate ) { // remove all 'this' data factories curtemplate->getTaskObject()->methods()->clear(); // remove temporary subMachine peers from current task. for( StateMachine::ChildList::const_iterator it= curtemplate->getChildren().begin(); it != curtemplate->getChildren().end(); ++it ) { ParsedStateMachine* psc = dynamic_cast<ParsedStateMachine*>( it->get() ); if (psc) { context->removeObject( psc->getTaskObject()->getName() ); } } // will also delete all children : curtemplate.reset(); } // should be empty in most cases : for ( std::vector<CommandInterface*>::iterator i = varinitcommands.begin(); i != varinitcommands.end(); ++ i ) delete *i; varinitcommands.clear(); for ( std::vector<CommandInterface*>::iterator i = paraminitcommands.begin(); i != paraminitcommands.end(); ++ i ) delete *i; paraminitcommands.clear(); for ( machinebuilders_t::iterator i = machinebuilders.begin(); i != machinebuilders.end(); ++i ) delete i->second; machinebuilders.clear(); } void StateGraphParser::seenstatemachinename( iter_t begin, iter_t end ) { // the 'type' of the SC : curmachinename = std::string ( begin, end ); // check if the type exists already : if ( machinebuilders.count( curmachinename ) != 0 ) ORO_THROW( parse_exception_semantic_error("StateMachine type " + curmachinename + " redefined.")); curtemplate.reset(new ParsedStateMachine()); // Connect the new SC to the relevant machines. // 'sc' acts as a stack for storing variables. curobject = new StateMachineTask(curtemplate, context->engine() ); curobject->setName( curmachinename ); curtemplate->setTaskObject( curobject ); // store. curtemplate->setEventProcessor( context->engine()->events() ); //handle events in TaskContext. // we pass the plain file positer such that parse errors are // refering to correct file line numbers. progParser = new ProgramGraphParser(mpositer, context); // set the 'type' name : curtemplate->setName( curmachinename, false ); } void StateGraphParser::storeOffset() { // stores the begining of a (possible) new statemachine definition. // start line number : ln_offset = mpositer.get_position().line - 1; // start of text : saveStartPos = mpositer; } void StateGraphParser::saveText( iter_t begin, iter_t end ) { assert( curmachinename.length() != 0 ); //cerr << std::string(begin, end)<<endl; if ( machinebuilders.count( curmachinename ) == 0 ) return; // yes this might be possible // due to the shared-text implementation, we can set the text afterwards. machinebuilders[curmachinename]->item()->setText( std::string( saveStartPos, end) ); this->storeOffset(); } void StateGraphParser::inpreconditions() { // we postpone the current state assert( curnonprecstate == 0 ); curnonprecstate = curstate->postponeState(); // add the postponed state in PSM : curtemplate->addState( curnonprecstate ); } void StateGraphParser::seenpreconditions() { curtemplate->transitionSet( curstate, curnonprecstate, new ConditionTrue, rank--, mpositer.get_position().line - ln_offset ); curstate->setDefined( true ); curstate = curnonprecstate; curnonprecstate = 0; } void StateGraphParser::startrootmachineinstantiation() { isroot = true; } void StateGraphParser::seenrootmachineinstantiation() { // first reset the flag. isroot = false; if( rootmachines.find( curinstmachinename ) != rootmachines.end() ) ORO_THROW( parse_exception_semantic_error( "Root machine \"" + curinstmachinename + "\" already defined." )); rootmachines[curinstmachinename] = curinstantiatedmachine; // recursively set the name of this SC and all subs : // furthermore, it adds the TC of each child as peer TC to the parent. curinstantiatedmachine->setName( curinstmachinename, true ); // check if the type exists already : if ( context->getObject( curinstmachinename ) ) ORO_THROW( parse_exception_semantic_error("TaskContext '"+context->getName()+"' has already an Object named '" + curinstmachinename + "' .")); // Transfer ownership to the owning task. curinstantiatedmachine->getTaskObject()->setParent( 0 ); context->addObject( curinstantiatedmachine->getTaskObject() ); curinstantiatedmachine.reset(); curinstmachinename.clear(); } void StateGraphParser::seensubMachineinstantiation() { if ( find_if( curtemplate->getChildren().begin(), curtemplate->getChildren().end(), bind( equal_to<string>(), bind(&StateMachine::getName,_1), curinstmachinename )) != curtemplate->getChildren().end() ) ORO_THROW( parse_exception_semantic_error( "SubMachine \"" + curinstmachinename + "\" already defined." )); // Since we parse in the task context, we must _temporarily_ // make each subMachine a peer of the task so that we can access // its methods. if ( !context->addObject( curinstantiatedmachine->getTaskObject() ) ) ORO_THROW( parse_exception_semantic_error( "Name clash: name of instantiated machine \"" + curinstmachinename + "\" already used as object name in task '"+context->getName()+"'." )); // this trick sets the parent back to zero, such that the next call to addObject on curtemplate // will re-set the parent. We will removeObject on 'context' lateron. curinstantiatedmachine->getTaskObject()->setParent(0); curtemplate->addChild( curinstantiatedmachine ); curtemplate->getTaskObject()->addObject( curinstantiatedmachine->getTaskObject() ); // we add this statemachine to the list of variables, so that the // user can refer to it by its name... //detail::ParsedAlias<std::string>* pv = new detail::ParsedAlias<std::string>( curinstantiatedmachine->getNameDS() ); //context->attributes()->setValue( curinstmachinename, pv ); curinstantiatedmachine->setName(curinstmachinename, false ); // not recursive ! curinstantiatedmachine.reset(); curinstmachinename.clear(); } void StateGraphParser::seenmachinetypename( iter_t begin, iter_t end ) { assert( curmachinebuilder == 0 ); std::string name( begin, end ); machinebuilders_t::iterator i = machinebuilders.find( name ); if ( i == machinebuilders.end() ) ORO_THROW( parse_exception_semantic_error( "StateMachine \"" + name + "\" not defined." )); curmachinebuilder = i->second; } void StateGraphParser::seeninstmachinename( iter_t begin, iter_t end ) { assert( curmachinebuilder != 0 ); assert( curinstmachinename.empty() ); curinstmachinename = std::string( begin, end ); } void StateGraphParser::seenmachineinstargumentname( iter_t begin, iter_t end ) { assert( curmachineinstargumentname.empty() ); std::string name( begin, end ); curmachineinstargumentname = name; } void StateGraphParser::seenmachineinstargumentvalue() { DataSourceBase::shared_ptr value = expressionparser->getResult(); // let's not forget this... expressionparser->dropResult(); if ( curinstmachineparams.find( curmachineinstargumentname ) != curinstmachineparams.end() ) ORO_THROW( parse_exception_semantic_error( "In initialisation of StateMachine \"" + curinstmachinename + "\": Parameter \"" + curmachineinstargumentname +"\" initialised twice..." )); curinstmachineparams[curmachineinstargumentname] = value; curmachineinstargumentname.clear(); } void StateGraphParser::seenmachineinstantiation() { // TODO : move this code to the ParsedStateMachine builder. // Create a full depth copy (including subMachines) // if RootMachine, make special copy which fixes attributes such // that on subsequent copy() they keep pointing to same var. // use shared_ptr to release on throw's below. ParsedStateMachinePtr nsc( curmachinebuilder->build( isroot ) ); // we stored the attributes which are params of nsc // in the build operation : machineparams_t params = nsc->getParameters(); // first run over the given parameters to see if they all exist in // the context we're instantiating... for ( machineparamvalues_t::iterator i = curinstmachineparams.begin(); i != curinstmachineparams.end(); ++i ) { machineparams_t::iterator j = params.find( i->first ); if ( j == params.end() ) ORO_THROW( parse_exception_semantic_error( "No parameter \"" + i->first + "\" in this StateMachine." ) ); } for ( machineparams_t::iterator i = params.begin(); i != params.end(); ++i ) { machineparamvalues_t::iterator j = curinstmachineparams.find( i->first ); if ( j == curinstmachineparams.end() ) ORO_THROW( parse_exception_semantic_error( "No value given for argument \"" + i->first + "\" in instantiation of this StateMachine." ));#ifndef ORO_EMBEDDED try { paraminitcommands.push_back( i->second->getDataSource()->updateCommand( j->second.get() ) ); } catch( const bad_assignment& e ) { throw parse_exception_semantic_error("Attempt to initialize parameter '"+i->first+"' with a value which is of a different type." ); }#else CommandInterface* ret = i->second->getDataSource()->updateCommand( j->second.get()); if (ret) paraminitcommands.push_back( ret ); else return;#endif } curinstantiatedmachine = nsc; // prepend the commands for initialising the subMachine // parameters if ( paraminitcommands.size() > 0 ) { CommandComposite* comcom = new CommandComposite; for ( std::vector<CommandInterface*>::iterator i = paraminitcommands.begin(); i != paraminitcommands.end(); ++i ) comcom->add( *i ); // init the vars as last (if any), so that they can be inited by an expression containing the params : if ( curinstantiatedmachine->getInitCommand() ) comcom->add( curinstantiatedmachine->getInitCommand() ); curinstantiatedmachine->setInitCommand( comcom ); } paraminitcommands.clear(); curmachinebuilder = 0; curinstmachineparams.clear(); // set the TaskContext name to the instance name : curinstantiatedmachine->getTaskObject()->setName(curinstmachinename ); } void StateGraphParser::seenmachinevariable() { std::vector<CommandInterface*> acv = valuechangeparser->assignCommands(); for(std::vector<CommandInterface*>::iterator it = acv.begin(); it!=acv.end(); ++it) varinitcommands.push_back( *it ); // this only clears the last parsed variables, not the 'store' (see reset()) valuechangeparser->clear(); } void StateGraphParser::seenmachineparam() { std::vector<std::string> pnames = valuechangeparser->definedNames(); std::vector<AttributeBase*> tbases = valuechangeparser->definedValues(); assert( pnames.size() == tbases.size() ); for (unsigned int i = 0; i < pnames.size(); ++i) curtemplate->addParameter( pnames[i] , tbases[i] ); // this only clears the last parsed variables, not the 'store' (see reset()) valuechangeparser->clear(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -