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 );
290 assigncommands.push_back( ac );
292 conditions.push_back(cond);
297 (
"Attempt to initialize a var "+var->
getDataSource()->getTypeName()+
" with a "+ expr->getTypeName() +
"." );
306 for(std::vector<std::string>::iterator it = alldefinednames.begin();
307 it != alldefinednames.end(); ++it) {
309 if ( o->getValue( *it ) == 0 ) {
310 o->setValue( mstore->getValue(*it)->clone() );
320 vector<string> predefinednames = s->getAttributeNames();
321 for(std::vector<std::string>::iterator it = predefinednames.begin();
322 it != predefinednames.end(); ++it) {
323 if (mstore->getValue(*it) == 0) {
325 mstore->setValue( s->getValue(*it)->clone() );
326 alldefinednames.push_back( *it );
331 void ValueChangeParser::cleanup()
333 for_each(assigncommands.begin(), assigncommands.end(), boost::lambda::bind(boost::lambda::delete_ptr(), boost::lambda::_1));
338 assigncommands.clear();
341 definedvalues.clear();
343 definednames.clear();
349 for(std::vector<std::string>::iterator it = alldefinednames.begin();
350 it != alldefinednames.end(); ++it) {
351 mstore->removeValue( *it );
353 alldefinednames.clear();
363 return valuechange_parsers;
368 return constantdefinition;
373 return aliasdefinition;
378 return variabledefinition;
383 return paramdefinition;
388 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 interface represents the concept of a condition which can be evaluated and return true or false...
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.
ConditionInterface * getCmdResult()
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.