32 #include "../Service.hpp" 33 #include "../types/Types.hpp" 34 #include "../Attribute.hpp" 35 #include "../TaskContext.hpp" 36 #include "../types/GlobalsRepository.hpp" 39 #include <boost/bind.hpp> 40 #include <boost/lambda/bind.hpp> 41 #include <boost/lambda/construct.hpp> 50 using namespace detail;
54 using namespace boost;
57 boost::spirit::classic::assertion<std::string> expect_open(
"Open brace expected.");
58 boost::spirit::classic::assertion<std::string> expect_close(
"Closing brace expected (or could not find out what this line means).");
59 boost::spirit::classic::assertion<std::string> expect_type(
"Unknown type. Please specify a type.");
60 boost::spirit::classic::assertion<std::string> expect_def(
"Expected a type definition. Please specify a type.");
61 boost::spirit::classic::assertion<std::string> expect_expr(
"Expected a valid expression.");
62 boost::spirit::classic::assertion<std::string> expect_ident(
"Expected a valid identifier.");
63 boost::spirit::classic::assertion<std::string> expect_init(
"Expected an initialisation value of the variable.");
64 boost::spirit::classic::assertion<std::string> expect_cis(
"Expected a initialisation ('=') of const.");
65 boost::spirit::classic::assertion<std::string> expect_ais(
"Expected a initialisation ('=') of alias.");
66 boost::spirit::classic::assertion<std::string> expect_index(
"Expected an index: [index].");
67 boost::spirit::classic::assertion<std::string> expect_integer(
"Expected a positive integer expression.");
68 boost::spirit::classic::assertion<std::string> expect_change(
"Expected a variable assignment after 'set'.");
69 boost::spirit::classic::assertion<std::string> expect_decl(
"Expected a declaration list.");
74 : type( 0 ), context( pc ), mstore( storage ? storage : pc->provides() ),
75 expressionparser( pc, caller, cp ), commonparser(cp), sizehint(-1),
78 BOOST_SPIRIT_DEBUG_RULE( constantdefinition );
79 BOOST_SPIRIT_DEBUG_RULE( aliasdefinition );
80 BOOST_SPIRIT_DEBUG_RULE( variabledefinition );
81 BOOST_SPIRIT_DEBUG_RULE( paramdefinition );
82 BOOST_SPIRIT_DEBUG_RULE( baredefinition );
83 BOOST_SPIRIT_DEBUG_RULE( constdecl );
84 BOOST_SPIRIT_DEBUG_RULE( vardecl );
85 BOOST_SPIRIT_DEBUG_RULE( baredecl );
94 # define RULE( name, def ) \ 95 boost_spirit::contiguous<boost_spirit::positive<boost_spirit::chset<char> > > name = (def) 103 chset<> identchar(
"a-zA-Z-_0-9/<>." );
104 RULE( type_name, lexeme_d[ +identchar ] );
106 valuechange_parsers = constantdefinition
113 >> expect_type( type_name[boost::bind( &ValueChangeParser::seentype,
this, _1, _2 ) ])
114 >> constdecl[boost::bind( &ValueChangeParser::seenconstantdefinition,
this )]
115 >> *(ch_p(
',') >> constdecl[boost::bind( &ValueChangeParser::seenconstantdefinition,
this )] );
121 >> expect_type(type_name [ boost::bind( &ValueChangeParser::seentype,
this, _1, _2 ) ])
123 >> expect_ident( commonparser.
identifier[ boost::bind( &ValueChangeParser::storedefinitionname,
this, _1, _2 ) ])
124 >> expect_ais( ch_p(
'=') )
126 >> expect_init( expressionparser.
parser() )[ boost::bind( &ValueChangeParser::seenaliasdefinition,
this ) ];
130 >> expect_type( type_name[boost::bind( &ValueChangeParser::seentype,
this, _1, _2 ) ])
131 >> vardecl[boost::bind( &ValueChangeParser::seenvariabledefinition,
this ) ]
132 >> *(ch_p(
',') >> vardecl[boost::bind( &ValueChangeParser::seenvariabledefinition,
this ) ] );
136 >> expect_type( type_name[boost::bind( &ValueChangeParser::seentype,
this, _1, _2 ) ])
137 >> baredecl[boost::bind( &ValueChangeParser::seenbaredefinition,
this ) ]
138 >> *(ch_p(
',') >> baredecl[boost::bind( &ValueChangeParser::seenbaredefinition,
this ) ] );
141 type_name[ boost::bind( &ValueChangeParser::seentype,
this, _1, _2 )]
142 >> baredecl[boost::bind( &ValueChangeParser::seenbaredefinition,
this )];
145 expect_ident( commonparser.
identifier[ boost::bind( &ValueChangeParser::storedefinitionname,
this, _1, _2 )] )
146 >> !( ch_p(
'(') >> expect_integer( expressionparser.
parser()[boost::bind( &ValueChangeParser::seensizehint,
this)]) >> expect_close( ch_p(
')')) ) ;
149 baredecl >> !( ch_p(
'=') >> expect_init( expressionparser.
parser() ) );
152 baredecl >> expect_cis( ch_p(
'=') ) >> expect_init( expressionparser.
parser() );
156 void ValueChangeParser::seensizehint()
160 assert( expr.get() );
164 if ( i.get() == 0 ) {
167 (
"Attempt to initialize "+typen+
" "+valuename+
" with a "+expr->getTypeName()+
", expected an integer expression. Use ' = "+expr->getTypeName()+
"( arg )' instead to use the constructor." );
169 if ( i->get() < 0 ) {
170 std::stringstream value;
174 (
"Attempt to initialize "+typen+
" "+valuename+
" with an expression leading to a negative number "+value.str()
175 +
". Initialization expressions are evaluated once at parse time !" );
177 if ( i->get() == 0 ) {
179 "Attempt to initialize "<<typen<<
" "<<valuename<<
" with an expression leading to zero (0)" 180 <<
". Initialization expressions are evaluated once at parse time !" <<
Logger::endl;
185 void ValueChangeParser::seenconstantdefinition()
201 (
"Attempt to initialize a const "+type->
getTypeName()+
" with a "+expr->getTypeName()+
"." );
204 mstore->setValue( var );
205 definedvalues.push_back( var );
206 definednames.push_back( valuename );
207 alldefinednames.push_back( valuename );
210 void ValueChangeParser::storedefinitionname(
iter_t begin,
iter_t end )
212 std::string name( begin, end );
213 if ( mstore->getValue( name ) ) {
216 "\" is already defined in " + mstore->getName() );
222 void ValueChangeParser::seentype(
iter_t begin,
iter_t end )
224 std::string name( begin, end );
225 type = typerepos->type( name );
230 void ValueChangeParser::seenaliasdefinition()
236 alias = type->
buildAlias( valuename, expr.get() );
240 "Attempt to define an alias of type "+type->
getTypeName()+
" to an expression of type "+expr->getTypeName()+
"." );
242 mstore->setValue( alias );
243 definedvalues.push_back( alias );
244 definednames.push_back( valuename );
245 alldefinednames.push_back( valuename );
247 assigncommands.push_back( nc );
250 void ValueChangeParser::seenbaredefinition()
261 mstore->setValue( var );
262 definedvalues.push_back( var );
263 definednames.push_back( valuename );
264 alldefinednames.push_back( valuename );
267 void ValueChangeParser::seenvariabledefinition()
277 mstore->setValue( var );
278 definedvalues.push_back( var );
279 definednames.push_back( valuename );
280 alldefinednames.push_back( valuename );
289 assigncommands.push_back( ac );
294 (
"Attempt to initialize a var "+var->
getDataSource()->getTypeName()+
" with a "+ expr->getTypeName() +
"." );
303 for(std::vector<std::string>::iterator it = alldefinednames.begin();
304 it != alldefinednames.end(); ++it) {
306 if ( o->getValue( *it ) == 0 ) {
307 o->setValue( mstore->getValue(*it)->clone() );
317 vector<string> predefinednames = s->getAttributeNames();
318 for(std::vector<std::string>::iterator it = predefinednames.begin();
319 it != predefinednames.end(); ++it) {
320 if (mstore->getValue(*it) == 0) {
322 mstore->setValue( s->getValue(*it)->clone() );
323 alldefinednames.push_back( *it );
328 void ValueChangeParser::cleanup()
330 for_each(assigncommands.begin(), assigncommands.end(), boost::lambda::bind(boost::lambda::delete_ptr(), boost::lambda::_1));
335 assigncommands.clear();
337 definedvalues.clear();
339 definednames.clear();
345 for(std::vector<std::string>::iterator it = alldefinednames.begin();
346 it != alldefinednames.end(); ++it) {
347 mstore->removeValue( *it );
349 alldefinednames.clear();
359 return valuechange_parsers;
364 return constantdefinition;
369 return aliasdefinition;
374 return variabledefinition;
379 return paramdefinition;
384 return baredefinition;
#define keyword_p(word)
Returns a rule which parses a keyword followed by a non-identifier character, newline or semicolon...
rule_t & parser()
Returns the full parser, as it is used most.
DataSource is a base class representing a generic way to read data of type T.
void load(Service::shared_ptr source)
Loads all defined names from a service.
rule_t & aliasDefinitionParser()
The parser that parses alias definitions.
const std::string & getTypeName() const
Return the type name which was first registered.
rule_t & bareDefinitionParser()
The parser that parses a bare variable definition.
This class contains all known types to Orocos.
void reset()
Completely clear all data and erase all parsed definitions from the taskcontext given in the construc...
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.
This class contains some very common parser definitions.
This exception is thrown if the target and source type of an assignment of a DataSource with a base::...
An execution engine serialises (executes one after the other) the execution of all commands...
boost::shared_ptr< Service > shared_ptr
void store(Service::shared_ptr other)
Store allDefinedNames() in a service.
An attribute is a minimalistic, named placeholder for data.
base::AttributeBase * buildConstant(std::string name, base::DataSourceBase::shared_ptr source, int sizehint) const
Build a non modifyable instance of this type.
static std::ostream & endl(std::ostream &__os)
Based on the software pattern 'command', this interface allows execution of action objects...
base::DataSourceBase::shared_ptr getResult()
base::AttributeBase * buildAlias(std::string name, base::DataSourceBase::shared_ptr b) const
build an alias with b as the value.
boost::intrusive_ptr< DataSource< T > > shared_ptr
base::AttributeBase * buildVariable(std::string name, int sizehint) const
Build a modifyable instance of this type.
void clear()
Clear assignCommands(), definedValues() and definedNames().
rule_t & paramDefinitionParser()
The parser that parses state context parameter definitions.
rule_t & constantDefinitionParser()
the parser that parses definitions of constants.
rule_t & variableDefinitionParser()
the parser that parses variable definitions, don't forget to check assignCommand after a variable def...
static Logger & log()
As Instance(), but more userfriendly.
The TaskContext is the C++ representation of an Orocos component.
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.
ValueChangeParser(TaskContext *tc, CommonParser &cp, Service::shared_ptr storage, ExecutionEngine *caller)
Create a ValueChangeParser which operates and stores values in a task.