31 #ifdef ORO_PRAGMA_INTERFACE 32 #pragma implementation 38 #include "../types/Operators.hpp" 40 #include "../internal/DataSourceCommand.hpp" 41 #include "../internal/GlobalService.hpp" 44 #include "../TaskContext.hpp" 46 #include "../types/Types.hpp" 49 #include <boost/lambda/lambda.hpp> 51 #include <boost/bind.hpp> 52 #include <boost/ref.hpp> 61 using namespace detail;
65 boost::spirit::classic::assertion<std::string> expect_open(
"Open brace expected.");
66 boost::spirit::classic::assertion<std::string> expect_close(
"Closing brace expected ( or could not find out what this line means ).");
67 boost::spirit::classic::assertion<std::string> expect_type(
"Unknown type. Please specify a type.");
68 boost::spirit::classic::assertion<std::string> expect_expr(
"Expected a valid expression.");
69 boost::spirit::classic::assertion<std::string> expect_ident(
"Expected a valid identifier.");
70 boost::spirit::classic::assertion<std::string> expect_init(
"Expected an initialisation value of the value.");
71 boost::spirit::classic::assertion<std::string> expect_comma(
"Expected the ',' separator after expression.");
72 boost::spirit::classic::assertion<std::string> expect_timespec(
"Expected a time specification (e.g. > 10s or > varname ) after 'time' .");
74 guard<std::string> my_guard;
80 : mcaller( caller ? caller : c->engine()), mis_send(false), commonparser(cp), expressionparser( p ),
81 peerparser( c, cp, false )
83 BOOST_SPIRIT_DEBUG_RULE( datacall );
84 BOOST_SPIRIT_DEBUG_RULE( arguments );
85 BOOST_SPIRIT_DEBUG_RULE( peerpath );
86 BOOST_SPIRIT_DEBUG_RULE(
object );
87 BOOST_SPIRIT_DEBUG_RULE( method );
98 peerpath = peerparser.
locator();
99 object= (commonparser.
identifier >>
".")[boost::bind(&DataCallParser::seenobjectname,
this, _1, _2)];
100 method= ( commonparser.
keyword | expect_ident(commonparser.
tidentifier))[boost::bind( &DataCallParser::seenmethodname,
this, _1, _2 ) ];
102 ( peerpath >> !
object >> method[ boost::bind( &DataCallParser::seendataname,
this ) ] >> !arguments)[ boost::bind( &DataCallParser::seendatacall,
this ) ];
105 void DataCallParser::seensend() {
109 void DataCallParser::seenobjectname(
iter_t begin,
iter_t end )
111 std::string name( begin, end );
112 mobject = name.substr(0, name.length() - 1);
115 void DataCallParser::seenmethodname(
iter_t begin,
iter_t end )
117 std::string name( begin, end );
118 if ( name ==
"send") {
129 void DataCallParser::seendataname()
132 mobject = peerparser.
object();
141 mobject = ops->getName();
144 if (mmethod !=
"collect" && mmethod !=
"collectIfDone" ) {
145 if ( ops == 0 || (mobject !=
"this" && ops->getName() != mobject ) ) {
149 if ( ops->hasMember(mmethod) == false ) {
152 mobject =
"GlobalService";
155 if ( ops == peerparser.
taskObject() && ops->hasService(
"scripting") && ops->provides(
"scripting")->hasMember(mmethod) ) {
156 mobject =
"scripting";
157 ops = ops->provides(
"scripting");
160 if ( mobject !=
"this" )
181 argparsers.push( argspar );
185 arguments = argspar->parser();
188 void DataCallParser::seendatacall()
194 std::vector<DataSourceBase::shared_ptr> args = argspar->
result();
197 assert(peer &&
"peer may never be null.");
209 if ( (meth ==
"collect" || meth ==
"collectIfDone") && !ops->hasMember(mmethod) ) {
210 if ( ops->hasAttribute(obj) ) {
215 if (meth ==
"collect")
225 ret = ops->produce( meth, args, mcaller );
228 ret = ops->produceSend( meth, args, mcaller );
229 mhandle.reset(
new SendHandleAlias( meth, ops->produceHandle(meth), ops->getPart(meth)) );
242 catch(
const std::exception& e)
255 while ( ! argparsers.empty() )
257 delete argparsers.top();
263 : commonparser(cp), expressionparser( p )
265 BOOST_SPIRIT_DEBUG_RULE( type_name );
266 BOOST_SPIRIT_DEBUG_RULE( arguments );
277 while ( ! argparsers.empty() )
279 delete argparsers.top();
287 std::string name( begin, end );
290 throw_(
iter_t(),
"\"" + name +
"\" is an unknown type...");
297 argparsers.push( argspar );
301 arguments = argspar->
parser();
310 std::vector<DataSourceBase::shared_ptr> args = argspar->
result();
322 static void abort_rule(
const string& reason) {
326 static error_status<> fail_rule(
scanner_t const& scan, parser_error<std::string, iter_t>&e )
328 return error_status<>( error_status<>::fail );
333 : datacallparser( *this, cp, pc, caller ),
334 constrparser(*this, cp),
336 valueparser( pc, cp ),
341 BOOST_SPIRIT_DEBUG_RULE( expression );
342 BOOST_SPIRIT_DEBUG_RULE( unarynotexp );
343 BOOST_SPIRIT_DEBUG_RULE( unaryminusexp );
344 BOOST_SPIRIT_DEBUG_RULE( unaryplusexp );
345 BOOST_SPIRIT_DEBUG_RULE( div_or_mul );
346 BOOST_SPIRIT_DEBUG_RULE( modexp );
347 BOOST_SPIRIT_DEBUG_RULE( plus_or_min );
348 BOOST_SPIRIT_DEBUG_RULE( smallereqexp );
349 BOOST_SPIRIT_DEBUG_RULE( smallerexp );
350 BOOST_SPIRIT_DEBUG_RULE( greatereqexp );
351 BOOST_SPIRIT_DEBUG_RULE( greaterexp );
352 BOOST_SPIRIT_DEBUG_RULE( equalexp );
353 BOOST_SPIRIT_DEBUG_RULE( notequalexp );
354 BOOST_SPIRIT_DEBUG_RULE( orexp );
355 BOOST_SPIRIT_DEBUG_RULE( andexp );
356 BOOST_SPIRIT_DEBUG_RULE( ifthenelseexp );
357 BOOST_SPIRIT_DEBUG_RULE( groupexp );
358 BOOST_SPIRIT_DEBUG_RULE( dotexp );
359 BOOST_SPIRIT_DEBUG_RULE( atomicexpression );
360 BOOST_SPIRIT_DEBUG_RULE( time_expression );
361 BOOST_SPIRIT_DEBUG_RULE( time_spec );
362 BOOST_SPIRIT_DEBUG_RULE( indexexp );
363 BOOST_SPIRIT_DEBUG_RULE( comma );
364 BOOST_SPIRIT_DEBUG_RULE( close_brace );
365 BOOST_SPIRIT_DEBUG_RULE( value_expression );
366 BOOST_SPIRIT_DEBUG_RULE( call_expression );
367 BOOST_SPIRIT_DEBUG_RULE( constructor_expression );
369 comma = expect_comma( ch_p(
',') );
370 close_brace = expect_close( ch_p(
')') );
371 expression = assignexp;
381 assignexp = andexp >> *( ch_p(
'=' ) >> eps_p(~ch_p(
'=' ))
382 >> assignexp)[ bind( &ExpressionParser::seen_assign,
this)];
384 orexp >> *( ( str_p(
"&&" ) ) >> orexp[
385 boost::bind( &ExpressionParser::seen_binary,
this,
"&&" ) ] );
387 notequalexp >> *( ( str_p(
"||" ) ) >> notequalexp[
388 boost::bind( &ExpressionParser::seen_binary,
this,
"||" ) ] );
390 equalexp >> *(
"!=" >> equalexp[
391 boost::bind( &ExpressionParser::seen_binary,
this,
"!=" ) ] );
394 >> *(
"==" >> greatereqexp[
395 boost::bind( &ExpressionParser::seen_binary,
this,
"==" ) ] );
398 >> *(
">=" >> greaterexp[
399 boost::bind( &ExpressionParser::seen_binary,
this,
">=" ) ] );
402 >> *(
'>' >> smallereqexp[
403 boost::bind( &ExpressionParser::seen_binary,
this,
">" ) ] );
406 >> *(
"<=" >> smallerexp[
407 boost::bind( &ExpressionParser::seen_binary,
this,
"<=" ) ] );
409 plus_or_min >> *(
'<' >> plus_or_min[
410 boost::bind( &ExpressionParser::seen_binary,
this,
"<" ) ] );
413 modexp >> *( (
'-' >> modexp[
414 boost::bind( &ExpressionParser::seen_binary,
this,
"-" ) ] )
416 boost::bind( &ExpressionParser::seen_binary,
this,
"+" ) ] ) );
419 div_or_mul >> *(
'%' >> div_or_mul[
420 boost::bind( &ExpressionParser::seen_binary,
this,
"%" ) ] );
422 unaryplusexp >> *( (
'/' >> unaryplusexp[
423 boost::bind( &ExpressionParser::seen_binary,
this,
"/" ) ] )
424 | (
'*' >> unaryplusexp[
425 boost::bind( &ExpressionParser::seen_binary,
this,
"*" ) ] ) );
428 '+' >> unaryminusexp[
429 boost::bind( &ExpressionParser::seen_unary,
this,
"+" ) ]
433 boost::bind( &ExpressionParser::seen_unary,
this,
"-" ) ]
436 ch_p(
'!') >> atomicexpression[
437 boost::bind( &ExpressionParser::seen_unary,
this,
"!" ) ]
450 | constructor_expression
453 ) >> *( dotexp | indexexp);
455 constructor_expression = my_guard( constrparser.
parser()[ boost::bind(&ExpressionParser::seenconstructor,
this)])[&fail_rule];
458 value_expression = my_guard( valueparser.
parser() >> !(
'.' >> commonparser.
keyword[boost::bind(&abort_rule,
"Rule must be handled by datacallparser.")]))[ &fail_rule ]
459 [ bind( &ExpressionParser::seenvalue,
this ) ];
460 call_expression = my_guard( datacallparser.
parser() )[&fail_rule]
461 [bind( &ExpressionParser::seendatacall,
this ) ];
464 (ch_p(
'[') >> expression[bind(&ExpressionParser::seen_index,
this)] >> expect_close( ch_p(
']') ) );
467 ( ch_p(
'.') >> commonparser.
identifier[ boost::bind(&ExpressionParser::seen_dotmember,
this, _1, _2)]);
471 groupexp =
'(' >> expression >> close_brace;
476 (str_p(
"time")>>eps_p(~commonparser.
identchar | eol_p | end_p ))[bind(&ExpressionParser::seentimeexpr,
this)]
478 ( (eps_p[boost::lambda::var(commonparser.
skipeol) =
false] >> uint_p[ bind( &ExpressionParser::seentimespec,
this, _1 ) ]
479 >> (str_p(
"s" ) |
"ms" |
"us" |
"ns" )[boost::lambda::var(commonparser.
skipeol) =
true][boost::bind( &ExpressionParser::seentimeunit,
this, _1, _2 ) ])
480 | (eps_p[boost::lambda::var(commonparser.
skipeol) =
true] >> nothing_p)
497 void ExpressionParser::inverttime()
502 void ExpressionParser::seentimeexpr()
516 void ExpressionParser::seentimeunit(
iter_t begin,
iter_t end)
526 case 'm': total = tsecs / 1000.0;
528 case 'u': total = tsecs / 1000000.0;
530 case 'n': total = tsecs / 1000000000.0;
533 std::string arg(begin, end);
545 void ExpressionParser::seentimespec(
int n )
550 void ExpressionParser::seenvalue()
553 parsestack.push( ds );
556 void ExpressionParser::seendatacall()
559 parsestack.push( n );
563 void ExpressionParser::seenconstructor()
566 parsestack.push( n );
573 while ( !parsestack.empty() )
584 assert( !parsestack.empty() );
585 return parsestack.top();
590 assert( !parsestack.empty() );
594 void ExpressionParser::seen_unary(
const std::string& op )
599 opreg->applyUnary( op, arg.get() );
602 "\" to " + arg->getType() +
"." );
603 parsestack.push( ret );
606 void ExpressionParser::seen_dotmember(
iter_t s,
iter_t f )
608 std::string member(s,f);
616 parsestack.push( ret );
619 void ExpressionParser::seen_binary(
const std::string& op )
629 opreg->applyBinary( op, arg2.get(), arg1.get() );
632 " "+arg1->getType() +
"." );
633 parsestack.push( ret );
636 void ExpressionParser::seen_assign()
644 if (arg2->getTypeName() ==
"SendHandle" && mhandle) {
647 for( ConfigurationInterface::AttributeObjects::iterator it = attrs.begin(); it != attrs.end(); ++it) {
648 if ( (*it)->getDataSource() == arg2 ) {
650 string name = (*it)->getName();
664 act = arg2->updateAction( arg1.get() );
667 " "+arg1->getType() +
"." );
671 " "+arg1->getType() );
673 if (arg2->getTypeInfo()->getTypeName() !=
"unknown_t")
674 ret = arg2->getTypeInfo()->buildActionAlias(act, arg2);
678 parsestack.push( ret );
681 void ExpressionParser::seen_index()
693 +arg1->getType() +
" ]." );
694 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.
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".
bool skipeol
Saves eol skipping state.
A internal::DataSource which returns the time elapsed since the last reset in Seconds.
boost::shared_ptr< base::AttributeBase > getParseHandle()
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.
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.
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. ...
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...
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...
const base::DataSourceBase::shared_ptr lastParsed() const
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.