Orocos Real-Time Toolkit  2.9.0
ValueParser.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon May 10 19:10:37 CEST 2004 ValueParser.cxx
3 
4  ValueParser.cxx - description
5  -------------------
6  begin : Mon May 10 2004
7  copyright : (C) 2004 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, *
24  * Suite 330, Boston, MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 #include "parser-debug.hpp"
29 #include "parse_exception.hpp"
30 #include "ValueParser.hpp"
31 #include "../Attribute.hpp"
32 
33 #include "../TaskContext.hpp"
34 #include "../Service.hpp"
35 #include "../types/GlobalsRepository.hpp"
36 
37 #include <boost/bind.hpp>
38 #include <boost/lexical_cast.hpp>
39 
40 #include <iostream>
41 using namespace std;
42 
43 namespace RTT
44 {
45  using boost::bind;
46  using namespace detail;
47 
48  ValueParser::ValueParser( TaskContext* tc, CommonParser& cp)
49  : commonparser(cp), peerparser(tc,cp), propparser(cp)
50  {
51  BOOST_SPIRIT_DEBUG_RULE( constant );
52  BOOST_SPIRIT_DEBUG_RULE( const_float );
53  BOOST_SPIRIT_DEBUG_RULE( const_double );
54  BOOST_SPIRIT_DEBUG_RULE( const_int );
55  BOOST_SPIRIT_DEBUG_RULE( const_hex );
56  BOOST_SPIRIT_DEBUG_RULE( const_uint );
57  BOOST_SPIRIT_DEBUG_RULE( const_llong );
58  BOOST_SPIRIT_DEBUG_RULE( const_ullong );
59  BOOST_SPIRIT_DEBUG_RULE( const_char );
60  BOOST_SPIRIT_DEBUG_RULE( const_bool );
61  BOOST_SPIRIT_DEBUG_RULE( const_string );
62  BOOST_SPIRIT_DEBUG_RULE( named_constant );
63 
64  // note the order is important: commonparser.identifier throws a
65  // useful "cannot use x as identifier" error if it fails, so we
66  // must first show all non-identifier rules.
67  constant =
68  const_float
69  | const_double
70  | const_hex
71  | const_ullong
72  | const_llong
73  | const_uint
74  | const_int
75  | const_bool
76  | const_char
77  | const_string
78  | named_constant;
79 
80  const_float =
81  strict_real_p [
82  boost::bind( &ValueParser::seenfloatconstant, this, _1 ) ] >> ch_p('f');
83 
84  const_double =
85  strict_real_p [
86  boost::bind( &ValueParser::seendoubleconstant, this, _1 ) ];
87 
88  const_hex = (str_p("0x") | str_p("0X")) >>
89  hex_p [
90  boost::bind( &ValueParser::seenhexconstant, this, _1 ) ];
91 
92  const_ullong =
93  uint_parser<unsigned long long>() [
94  boost::bind( &ValueParser::seenullongconstant, this, _1 ) ] >> str_p("ull");
95 
96  const_llong =
97  uint_parser<long long>() [
98  boost::bind( &ValueParser::seenllongconstant, this, _1 ) ] >> str_p("ll");
99 
100  const_uint =
101  uint_parser<unsigned int>() [
102  boost::bind( &ValueParser::seenuintconstant, this, _1 ) ] >> ch_p('u');
103 
104  const_int =
105  int_parser<int>() [
106  boost::bind( &ValueParser::seenintconstant, this, _1 ) ];
107 
108  const_bool =
109  ( keyword_p( "true" ) | keyword_p("false") )[
110  boost::bind( &ValueParser::seenboolconstant, this, _1, _2 ) ];
111 
112  const_char = (ch_p('\'') >> ch_p('\\') >> ch_p('0') >> ch_p('\''))[boost::bind( &ValueParser::seennull,this)] |
113  confix_p( "'", (c_escape_ch_p[ boost::bind( &ValueParser::seencharconstant, this, _1 ) ]) , "'" );
114 
115  const_string = lexeme_d[confix_p(
116  ch_p( '"' ), *c_escape_ch_p[ boost::bind( &ValueParser::push_str_char, this, _1 ) ], '"' )[ boost::bind( &ValueParser::seenstring, this ) ]];
117 
118  named_constant =
119  ( keyword_p("done")[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ]
120  |
121  ( peerparser.locator()[boost::bind( &ValueParser::seenpeer, this) ]
122  >> propparser.locator()
123  >> commonparser.identifier[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ]) )
124  ;
125  }
126 
127  void ValueParser::seenpeer() {
128  // inform propparser of new peer :
129  //std::cerr << "ValueParser: seenpeer : "<< peerparser.taskObject()->getName()
130  // <<" has props :" << (peerparser.taskObject()->properties() != 0) << std::endl;
131  propparser.setPropertyBag( peerparser.taskObject()->properties() );
132  }
133 
134  void ValueParser::seenboolconstant( iter_t begin, iter_t end )
135  {
136  std::string value( begin, end );
137  assert( value == "true" || value == "false" );
138  if ( value == "true" )
139  ret =
140  new ConstantDataSource<bool>( true );
141  else
142  ret =
143  new ConstantDataSource<bool>( false );
144  }
145 
146  void ValueParser::seennamedconstant( iter_t begin, iter_t end )
147  {
148  std::string name( begin, end );
149  Service::shared_ptr task = peerparser.taskObject();
150  peerparser.reset();
151  //std::cerr << "ValueParser: seenvar : "<< name
152  // <<" is bag : " << (propparser.bag() != 0) << " is prop: "<< (propparser.property() != 0) << std::endl;
153  // in case our task is a taskcontext:
154  if ( task && propparser.bag() && propparser.property() ) {
155  // nested property case :
156  if ( ! propparser.bag()->find( name ) ) {
157  //std::cerr << "In "<<peer->getName() <<" : " << name << " not present"<<std::endl;
158  throw parse_exception_semantic_error("Property " + name + " not present in PropertyBag "+propparser.property()->getName()+" in "+ task->getName()+".");
159  }
160  ret = propparser.bag()->find( name )->getDataSource();
161  propparser.reset();
162  return;
163  }
164 
165  // non-nested property or attribute case :
166  if ( task && task->hasAttribute( name ) ) {
167  ret = task->getValue(name)->getDataSource();
168  return;
169  }
170  if ( task && task->hasProperty( name ) ) {
171  ret = task->properties()->find(name)->getDataSource();
172  return;
173  }
174 
175  // Global variable case:
176  if ( GlobalsRepository::Instance()->hasAttribute( name ) ) {
177  ret = GlobalsRepository::Instance()->getValue(name)->getDataSource();
178  return;
179  }
180 
181  throw_(begin, "Value " + name + " not defined in "+ task->getName()+".");
182  }
183 
184  void ValueParser::seennull()
185  {
186  ret = new ConstantDataSource<char>( '\0' );
187  }
188 
189  void ValueParser::seencharconstant( iter_t c )
190  {
191  ret = new ConstantDataSource<char>( *c );
192  }
193 
194  void ValueParser::seenhexconstant( unsigned int i )
195  {
196  ret = new ConstantDataSource<unsigned int>( i );
197  }
198 
199  void ValueParser::seenintconstant( int i )
200  {
201  ret = new ConstantDataSource<int>( i );
202  }
203 
204  void ValueParser::seenuintconstant( unsigned int i ) // RobWork uint -> unsigned int
205  {
206  ret = new ConstantDataSource<unsigned int>( i ); // RobWork uint -> unsigned int
207  }
208 
209  void ValueParser::seenllongconstant( long long i )
210  {
211  ret = new ConstantDataSource<long long>( i );
212  }
213 
214  void ValueParser::seenullongconstant( unsigned long long i )
215  {
217  }
218 
219  void ValueParser::seenfloatconstant( double i )
220  {
221  ret = new ConstantDataSource<float>( float(i) );
222  }
223 
224  void ValueParser::seendoubleconstant( double i )
225  {
226  ret = new ConstantDataSource<double>( i );
227  }
228 
230  {
231  clear();
232  }
233 
235  {
236  propparser.reset();
237  }
238 
240  {
241  return constant;
242  }
243 
244  void ValueParser::push_str_char( char c )
245  {
246  mcurstring += c;
247  }
248 
249  void ValueParser::seenstring()
250  {
251  // due to our config parse rule, the '"' terminating a
252  // string will be in mcurstring, and we don't want it, so we
253  // remove it..
254  mcurstring.erase( mcurstring.end() - 1 );
255  ret = new ConstantDataSource<std::string>( mcurstring );
256  //deleter.reset( ret );
257  mcurstring.clear();
258  }
259 }
#define keyword_p(word)
Returns a rule which parses a keyword followed by a non-identifier character, newline or semicolon...
void clear()
Clears this parser, not the repository where it stores its results.
void reset()
After reset, peer() == current context and object() == "this".
Definition: PeerParser.cpp:151
STL namespace.
base::PropertyBase * property() const
parse_exception class that is used for various semantic errors for which it was not worth defining a ...
This class contains some very common parser definitions.
rule_t & locator()
The locator tries to go as far as possible in the peer-to-object path and will never throw...
Definition: PeerParser.cpp:220
void reset()
After reset, property() == 0 and bag == 0.
boost::shared_ptr< Service > shared_ptr
Definition: Service.hpp:101
base::PropertyBase * find(const std::string &name) const
Find the base::PropertyBase with name name.
ServicePtr taskObject()
Returns the last matching Service or zero if not found.
Definition: PeerParser.cpp:230
void setPropertyBag(PropertyBag *pb)
Change the bag we want to traverse.
rule< scanner_t > rule_t
PropertyBag * bag() const
A DataSource which holds a constant value and returns it in its get() method.
rule_t & locator()
The locator tries to go as far as possible in the bag-to-property path and will never throw...
The TaskContext is the C++ representation of an Orocos component.
Definition: TaskContext.hpp:93
const std::string & getName() const
Get the name of the property.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
our_pos_iter_t iter_t
virtual DataSourceBase::shared_ptr getDataSource() const =0
Get an assignable base::DataSource through which this PropertyBase can be manipulated.