31 #ifdef ORO_PRAGMA_INTERFACE 32 #pragma implementation 38 #include "../types/Operators.hpp" 40 #include "../internal/DataSourceCommand.hpp" 42 #include "../internal/GlobalService.hpp" 46 #include "../TaskContext.hpp" 48 #include "../types/Types.hpp" 51 #include <boost/lambda/lambda.hpp> 53 #include <boost/bind.hpp> 54 #include <boost/ref.hpp> 63 using namespace detail;
67 boost::spirit::classic::assertion<std::string> expect_open(
"Open brace expected.");
68 boost::spirit::classic::assertion<std::string> expect_close(
"Closing brace expected ( or could not find out what this line means ).");
69 boost::spirit::classic::assertion<std::string> expect_type(
"Unknown type. Please specify a type.");
70 boost::spirit::classic::assertion<std::string> expect_expr(
"Expected a valid expression.");
71 boost::spirit::classic::assertion<std::string> expect_ident(
"Expected a valid identifier.");
72 boost::spirit::classic::assertion<std::string> expect_init(
"Expected an initialisation value of the value.");
73 boost::spirit::classic::assertion<std::string> expect_comma(
"Expected the ',' separator after expression.");
74 boost::spirit::classic::assertion<std::string> expect_timespec(
"Expected a time specification (e.g. > 10s or > varname ) after 'time' .");
76 guard<std::string> my_guard;
82 : ret(), mhandle(), mcmdcnd(0), mobject(), mmethod(),
83 mcaller( caller ? caller : c->engine()), mcalltype(DEFAULT_CALLTYPE), commonparser(cp), expressionparser( p ),
84 peerparser( c, cp, false )
86 BOOST_SPIRIT_DEBUG_RULE( datacall );
87 BOOST_SPIRIT_DEBUG_RULE( arguments );
88 BOOST_SPIRIT_DEBUG_RULE( peerpath );
89 BOOST_SPIRIT_DEBUG_RULE(
object );
90 BOOST_SPIRIT_DEBUG_RULE( method );
101 peerpath = peerparser.
locator();
102 object= (commonparser.
identifier >>
".")[boost::bind(&DataCallParser::seenobjectname,
this, _1, _2)];
103 method= ( commonparser.
keyword | expect_ident(commonparser.
tidentifier))[boost::bind( &DataCallParser::seenmethodname,
this, _1, _2 ) ];
105 ( peerpath >> !
object >> method[ boost::bind( &DataCallParser::seendataname,
this ) ] >> !arguments)[ boost::bind( &DataCallParser::seendatacall,
this ) ];
108 void DataCallParser::seenobjectname(
iter_t begin,
iter_t end )
110 std::string name( begin, end );
111 mobject = name.substr(0, name.length() - 1);
114 void DataCallParser::seenmethodname(
iter_t begin,
iter_t end )
116 std::string name( begin, end );
117 if ( name ==
"send" ) {
118 mcalltype = CALLTYPE_SEND;
121 }
else if (name ==
"cmd" ) {
122 mcalltype = CALLTYPE_CMD;
125 }
else if (name ==
"call" ) {
126 mcalltype = CALLTYPE_CALL;
130 mcalltype = DEFAULT_CALLTYPE;
136 void DataCallParser::seendataname()
139 mobject = peerparser.
object();
147 if ( (mcalltype != DEFAULT_CALLTYPE) && ops)
148 mobject = ops->getName();
151 if (mmethod !=
"collect" && mmethod !=
"collectIfDone" ) {
152 if ( ops == 0 || (mobject !=
"this" && ops->getName() != mobject ) ) {
156 if ( ops->hasMember(mmethod) == false ) {
159 mobject =
"GlobalService";
162 if ( ops == peerparser.
taskObject() && ops->hasService(
"scripting") && ops->provides(
"scripting")->hasMember(mmethod) ) {
163 mobject =
"scripting";
164 ops = ops->provides(
"scripting");
167 if ( mobject !=
"this" )
189 argparsers.push( argspar );
193 arguments = argspar->parser();
196 void DataCallParser::seendatacall()
202 std::vector<DataSourceBase::shared_ptr> args = argspar->
result();
205 assert(peer &&
"peer may never be null.");
217 if ( (meth ==
"collect" || meth ==
"collectIfDone") && !ops->hasMember(mmethod) ) {
218 if ( ops->hasAttribute(obj) ) {
223 if (meth ==
"collect")
233 unsigned int arity = ops->getCollectArity(meth);
235 case DEFAULT_CALLTYPE:
237 ret = ops->produce( meth, args, mcaller );
241 ret = ops->produceSend( meth, args, mcaller );
242 mhandle.reset(
new SendHandleAlias( meth, ops->produceHandle(meth), ops->getPart(meth)) );
247 args.push_back( sendds );
248 for (
unsigned int i =0; i != arity; ++i) {
249 args.push_back( ops->getOperation(meth)->getCollectType( i + 1 )->buildValue() );
273 catch(
const std::exception& e)
286 while ( ! argparsers.empty() )
288 delete argparsers.top();
294 : commonparser(cp), expressionparser( p )
296 BOOST_SPIRIT_DEBUG_RULE( type_name );
297 BOOST_SPIRIT_DEBUG_RULE( arguments );
308 while ( ! argparsers.empty() )
310 delete argparsers.top();
318 std::string name( begin, end );
321 throw_(
iter_t(),
"\"" + name +
"\" is an unknown type...");
328 argparsers.push( argspar );
332 arguments = argspar->
parser();
341 std::vector<DataSourceBase::shared_ptr> args = argspar->
result();
353 static void abort_rule(
const string& reason) {
357 static error_status<> fail_rule(
scanner_t const& scan, parser_error<std::string, iter_t>&e )
359 return error_status<>( error_status<>::fail );
365 datacallparser( *this, cp, pc, caller ),
366 constrparser(*this, cp),
368 valueparser( pc, cp ),
373 BOOST_SPIRIT_DEBUG_RULE( expression );
374 BOOST_SPIRIT_DEBUG_RULE( unarynotexp );
375 BOOST_SPIRIT_DEBUG_RULE( unaryminusexp );
376 BOOST_SPIRIT_DEBUG_RULE( unaryplusexp );
377 BOOST_SPIRIT_DEBUG_RULE( div_or_mul );
378 BOOST_SPIRIT_DEBUG_RULE( modexp );
379 BOOST_SPIRIT_DEBUG_RULE( plus_or_min );
380 BOOST_SPIRIT_DEBUG_RULE( smallereqexp );
381 BOOST_SPIRIT_DEBUG_RULE( smallerexp );
382 BOOST_SPIRIT_DEBUG_RULE( greatereqexp );
383 BOOST_SPIRIT_DEBUG_RULE( greaterexp );
384 BOOST_SPIRIT_DEBUG_RULE( equalexp );
385 BOOST_SPIRIT_DEBUG_RULE( notequalexp );
386 BOOST_SPIRIT_DEBUG_RULE( orexp );
387 BOOST_SPIRIT_DEBUG_RULE( andexp );
388 BOOST_SPIRIT_DEBUG_RULE( ifthenelseexp );
389 BOOST_SPIRIT_DEBUG_RULE( groupexp );
390 BOOST_SPIRIT_DEBUG_RULE( dotexp );
391 BOOST_SPIRIT_DEBUG_RULE( atomicexpression );
392 BOOST_SPIRIT_DEBUG_RULE( time_expression );
393 BOOST_SPIRIT_DEBUG_RULE( time_spec );
394 BOOST_SPIRIT_DEBUG_RULE( indexexp );
395 BOOST_SPIRIT_DEBUG_RULE( comma );
396 BOOST_SPIRIT_DEBUG_RULE( close_brace );
397 BOOST_SPIRIT_DEBUG_RULE( value_expression );
398 BOOST_SPIRIT_DEBUG_RULE( call_expression );
399 BOOST_SPIRIT_DEBUG_RULE( constructor_expression );
401 comma = expect_comma( ch_p(
',') );
402 close_brace = expect_close( ch_p(
')') );
403 expression = assignexp;
413 assignexp = andexp >> *( ch_p(
'=' ) >> eps_p(~ch_p(
'=' ))
414 >> assignexp)[ bind( &ExpressionParser::seen_assign,
this)];
416 orexp >> *( ( str_p(
"&&" ) ) >> orexp[
417 boost::bind( &ExpressionParser::seen_binary,
this,
"&&" ) ] );
419 notequalexp >> *( ( str_p(
"||" ) ) >> notequalexp[
420 boost::bind( &ExpressionParser::seen_binary,
this,
"||" ) ] );
422 equalexp >> *(
"!=" >> equalexp[
423 boost::bind( &ExpressionParser::seen_binary,
this,
"!=" ) ] );
426 >> *(
"==" >> greatereqexp[
427 boost::bind( &ExpressionParser::seen_binary,
this,
"==" ) ] );
430 >> *(
">=" >> greaterexp[
431 boost::bind( &ExpressionParser::seen_binary,
this,
">=" ) ] );
434 >> *(
'>' >> smallereqexp[
435 boost::bind( &ExpressionParser::seen_binary,
this,
">" ) ] );
438 >> *(
"<=" >> smallerexp[
439 boost::bind( &ExpressionParser::seen_binary,
this,
"<=" ) ] );
441 plus_or_min >> *(
'<' >> plus_or_min[
442 boost::bind( &ExpressionParser::seen_binary,
this,
"<" ) ] );
445 modexp >> *( (
'-' >> modexp[
446 boost::bind( &ExpressionParser::seen_binary,
this,
"-" ) ] )
448 boost::bind( &ExpressionParser::seen_binary,
this,
"+" ) ] ) );
451 div_or_mul >> *(
'%' >> div_or_mul[
452 boost::bind( &ExpressionParser::seen_binary,
this,
"%" ) ] );
454 unaryplusexp >> *( (
'/' >> unaryplusexp[
455 boost::bind( &ExpressionParser::seen_binary,
this,
"/" ) ] )
456 | (
'*' >> unaryplusexp[
457 boost::bind( &ExpressionParser::seen_binary,
this,
"*" ) ] ) );
460 '+' >> unaryminusexp[
461 boost::bind( &ExpressionParser::seen_unary,
this,
"+" ) ]
465 boost::bind( &ExpressionParser::seen_unary,
this,
"-" ) ]
468 ch_p(
'!') >> atomicexpression[
469 boost::bind( &ExpressionParser::seen_unary,
this,
"!" ) ]
482 | constructor_expression
485 ) >> *( dotexp | indexexp);
487 constructor_expression = my_guard( constrparser.
parser()[ boost::bind(&ExpressionParser::seenconstructor,
this)])[&fail_rule];
490 value_expression = my_guard( valueparser.
parser() >> !(
'.' >> commonparser.
keyword[boost::bind(&abort_rule,
"Rule must be handled by datacallparser.")]))[ &fail_rule ]
491 [ bind( &ExpressionParser::seenvalue,
this ) ];
492 call_expression = my_guard( datacallparser.
parser() )[&fail_rule]
493 [bind( &ExpressionParser::seendatacall,
this ) ];
496 (ch_p(
'[') >> expression[bind(&ExpressionParser::seen_index,
this)] >> expect_close( ch_p(
']') ) );
499 ( ch_p(
'.') >> commonparser.
identifier[ boost::bind(&ExpressionParser::seen_dotmember,
this, _1, _2)]);
503 groupexp =
'(' >> expression >> close_brace;
508 (str_p(
"time")>>eps_p(~commonparser.
identchar | eol_p | end_p ))[bind(&ExpressionParser::seentimeexpr,
this)]
510 ( (eps_p[boost::lambda::var(commonparser.
skipeol) =
false] >> uint_p[ bind( &ExpressionParser::seentimespec,
this, _1 ) ]
511 >> (str_p(
"s" ) |
"ms" |
"us" |
"ns" )[boost::lambda::var(commonparser.
skipeol) =
true][boost::bind( &ExpressionParser::seentimeunit,
this, _1, _2 ) ])
512 | (eps_p[boost::lambda::var(commonparser.
skipeol) =
true] >> nothing_p)
529 void ExpressionParser::inverttime()
534 void ExpressionParser::seentimeexpr()
548 void ExpressionParser::seentimeunit(
iter_t begin,
iter_t end)
558 case 'm': total = tsecs / 1000.0;
560 case 'u': total = tsecs / 1000000.0;
562 case 'n': total = tsecs / 1000000000.0;
565 std::string arg(begin, end);
577 void ExpressionParser::seentimespec(
int n )
582 void ExpressionParser::seenvalue()
585 parsestack.push( ds );
588 void ExpressionParser::seendatacall()
591 parsestack.push( n );
596 void ExpressionParser::seenconstructor()
599 parsestack.push( n );
606 while ( !parsestack.empty() )
617 assert( !parsestack.empty() );
618 return parsestack.top();
623 assert( !parsestack.empty() );
629 assert( !parsestack.empty() );
633 void ExpressionParser::seen_unary(
const std::string& op )
638 opreg->applyUnary( op, arg.get() );
641 "\" to " + arg->getType() +
"." );
642 parsestack.push( ret );
645 void ExpressionParser::seen_dotmember(
iter_t s,
iter_t f )
647 std::string member(s,f);
655 parsestack.push( ret );
658 void ExpressionParser::seen_binary(
const std::string& op )
668 opreg->applyBinary( op, arg2.get(), arg1.get() );
671 " "+arg1->getType() +
"." );
672 parsestack.push( ret );
675 void ExpressionParser::seen_assign()
683 if (arg2->getTypeName() ==
"SendHandle" && mhandle) {
686 for( ConfigurationInterface::AttributeObjects::iterator it = attrs.begin(); it != attrs.end(); ++it) {
687 if ( (*it)->getDataSource() == arg2 ) {
689 string name = (*it)->getName();
695 mhandle->getFactory()->produceCollect(std::vector<DataSourceBase::shared_ptr>(1,arg1),
new ValueDataSource<bool>(
false)),
696 mhandle->getFactory() ) );
697 parsestack.push( arg1 );
712 act = arg2->updateAction( arg1.get() );
715 " "+arg1->getType() +
"." );
719 " "+arg1->getType() );
721 if (arg2->getTypeInfo()->getTypeName() !=
"unknown_t")
722 ret = arg2->getTypeInfo()->buildActionAlias(act, arg2);
726 parsestack.push( ret );
729 void ExpressionParser::seen_index()
741 +arg1->getType() +
" ]." );
742 parsestack.push( ret );
bool setValue(base::AttributeBase *ab)
Transfer the ownership of an attribute to the repository.
std::vector< base::DataSourceBase::shared_ptr > result()
Get the parsed internal::DataSource's.
DataSource is a base class representing a generic way to read data of type T.
virtual result_t get() const =0
Return the data as type T.
rule_t tidentifier
recursive template def.
std::string object()
Returns the last matching object name.
DataCallParser(ExpressionParser &p, CommonParser &cp, TaskContext *pc, ExecutionEngine *caller)
ConfigurationInterface * attributes()
Returns the attributes of this TaskContext as an ConfigurationInterface.
void reset()
After reset, peer() == current context and object() == "this".
This interface represents the concept of a condition which can be evaluated and return true or false...
bool skipeol
Saves eol skipping state.
A internal::DataSource which returns the time elapsed since the last reset in Seconds.
void seen_constructor(void)
parse_exception class that is used for various semantic errors for which it was not worth defining a ...
virtual DataSourceBase::shared_ptr getDataSource() const =0
Return a internal::DataSource which contains the same contents.
base::DataSourceBase::shared_ptr getDataSource() const
Return a internal::DataSource which contains the same contents.
This is a parser that you construct to parse a set of arguments.
ConditionInterface * getCmdResult()
base::DataSourceBase * getParseResult()
void removeAttribute(const std::string &name)
Remove an attribute from the repository.
This class contains some very common parser definitions.
TaskContext * peer()
Returns the last matching peer.
This class builds on upon construction all expression operators known to Orocos.
An execution engine serialises (executes one after the other) the execution of all commands...
rule_t & locator()
The locator tries to go as far as possible in the peer-to-object path and will never throw...
boost::shared_ptr< Service > shared_ptr
void seen_type_name(iter_t begin, iter_t end)
scanner< iter_t, scanner_pol_t > scanner_t
OperationInterfacePart * getFactory() const
How we parse: this parser works like a stack-based RPN calculator.
An attribute is a minimalistic, named placeholder for data.
boost::shared_ptr< base::AttributeBase > getHandle()
In case the parsed result returns a SendHandle, ask the parser to also create a handle for it...
AttributeObjects const & getValues() const
Returns all attributes in this repository.
A DataSource which is used to execute an action and then return the value of another DataSource...
rule_t type_name
See notassertingidentifier, but in lexeme parsing mode.
ServicePtr taskObject()
Returns the last matching Service or zero if not found.
Based on the software pattern 'command', this interface allows execution of action objects...
base::DataSourceBase::shared_ptr getResult()
A class for representing a user type, and which can build instances of that type. ...
ConditionInterface * getParseCmdResult()
TypeInfoRepository::shared_ptr Types()
Obtain a pointer to the global type system.
base::DataSourceBase * getParseResult()
Keeps track of a DataSource which has a SendHandle and the factory for creating the collect functions...
A Command which evaluates a base::DataSourceBase and always returns true.
virtual base::DataSourceBase::shared_ptr produceCollect(const std::vector< base::DataSourceBase::shared_ptr > &args, internal::DataSource< bool >::shared_ptr blocking) const =0
Create a DataSource for collecting the results of a Send.
ExpressionParser(TaskContext *pc, ExecutionEngine *caller, CommonParser &common_parser)
parse_exception class that is used for fatal semantic errors for which it was not worth defining a pr...
A DataSource which holds a constant value and returns it in its get() method.
double Seconds
The type used to store SI unit time keeping.
static shared_ptr Instance()
A class that wraps a Command in a internal::DataSource<bool> interface.
std::vector< base::AttributeBase * > AttributeObjects
A vector containing pointers to all attribute objects stored in this repository.
ConstructorParser(ExpressionParser &p, CommonParser &cp)
The TaskContext is the C++ representation of an Orocos component.
Service::shared_ptr object()
Exception thrown when a factory is requested to create an object, but a wrong argument type was given...
Exception thrown when a factory is requested to create an object but the wrong number of arguments wa...
boost::intrusive_ptr< DataSourceBase > shared_ptr
Use this type to store a pointer to a DataSourceBase.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
A simple, yet very useful DataSource, which keeps a value, and returns it in its get() method...
A DataSource that collects the result of a CmdFunction.
const base::DataSourceBase::shared_ptr lastParsed() const
boost::shared_ptr< SendHandleAlias > getParseHandle()
static RTT_API Service::shared_ptr Instance()
virtual const std::string & getName() const
Returns the name of this TaskContext.
void setName(std::string const &new_name)
Get the name of this instance.