Orocos Real-Time Toolkit  2.8.3
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), context(tc)
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_char );
58  BOOST_SPIRIT_DEBUG_RULE( const_bool );
59  BOOST_SPIRIT_DEBUG_RULE( const_string );
60  BOOST_SPIRIT_DEBUG_RULE( named_constant );
61 
62  // note the order is important: commonparser.identifier throws a
63  // useful "cannot use x as identifier" error if it fails, so we
64  // must first show all non-identifier rules.
65  constant =
66  const_float
67  | const_double
68  | const_hex
69  | const_int
70  | const_uint
71  | const_bool
72  | const_char
73  | const_string
74  | named_constant;
75 
76  const_float =
77  strict_real_p [
78  boost::bind( &ValueParser::seenfloatconstant, this, _1 ) ] >> ch_p('f');
79 
80  const_double =
81  strict_real_p [
82  boost::bind( &ValueParser::seendoubleconstant, this, _1 ) ];
83 
84  const_hex = (str_p("0x") | str_p("0X")) >>
85  hex_p [
86  boost::bind( &ValueParser::seenhexconstant, this, _1 ) ];
87 
88  const_int =
89  int_p [
90  boost::bind( &ValueParser::seenintconstant, this, _1 ) ];
91 
92  const_uint =
93  uint_p [
94  boost::bind( &ValueParser::seenuintconstant, this, _1 ) ] >> ch_p('u');
95 
96  const_bool =
97  ( keyword_p( "true" ) | keyword_p("false") )[
98  boost::bind( &ValueParser::seenboolconstant, this, _1, _2 ) ];
99 
100  const_char = (ch_p('\'') >> ch_p('\\') >> ch_p('0') >> ch_p('\''))[boost::bind( &ValueParser::seennull,this)] |
101  confix_p( "'", (c_escape_ch_p[ boost::bind( &ValueParser::seencharconstant, this, _1 ) ]) , "'" );
102 
103  const_string = lexeme_d[confix_p(
104  ch_p( '"' ), *c_escape_ch_p[ boost::bind( &ValueParser::push_str_char, this, _1 ) ], '"' )[ boost::bind( &ValueParser::seenstring, this ) ]];
105 
106  named_constant =
107  ( keyword_p("done")[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ]
108  |
109  ( peerparser.locator()[boost::bind( &ValueParser::seenpeer, this) ]
110  >> propparser.locator()
111  >> commonparser.identifier[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ]) )
112  ;
113  }
114 
115  void ValueParser::seenpeer() {
116  // inform propparser of new peer :
117  //std::cerr << "ValueParser: seenpeer : "<< peerparser.taskObject()->getName()
118  // <<" has props :" << (peerparser.taskObject()->properties() != 0) << std::endl;
119  propparser.setPropertyBag( peerparser.taskObject()->properties() );
120  }
121 
122  void ValueParser::seenboolconstant( iter_t begin, iter_t end )
123  {
124  std::string value( begin, end );
125  assert( value == "true" || value == "false" );
126  if ( value == "true" )
127  ret =
128  new ConstantDataSource<bool>( true );
129  else
130  ret =
131  new ConstantDataSource<bool>( false );
132  }
133 
134  void ValueParser::seennamedconstant( iter_t begin, iter_t end )
135  {
136  std::string name( begin, end );
137  Service::shared_ptr task = peerparser.taskObject();
138  peerparser.reset();
139  //std::cerr << "ValueParser: seenvar : "<< name
140  // <<" is bag : " << (propparser.bag() != 0) << " is prop: "<< (propparser.property() != 0) << std::endl;
141  // in case our task is a taskcontext:
142  if ( task && propparser.bag() && propparser.property() ) {
143  // nested property case :
144  if ( ! propparser.bag()->find( name ) ) {
145  //std::cerr << "In "<<peer->getName() <<" : " << name << " not present"<<std::endl;
146  throw parse_exception_semantic_error("Property " + name + " not present in PropertyBag "+propparser.property()->getName()+" in "+ task->getName()+".");
147  }
148  ret = propparser.bag()->find( name )->getDataSource();
149  propparser.reset();
150  return;
151  }
152 
153  // non-nested property or attribute case :
154  if ( task && task->hasAttribute( name ) ) {
155  ret = task->getValue(name)->getDataSource();
156  return;
157  }
158  if ( task && task->hasProperty( name ) ) {
159  ret = task->properties()->find(name)->getDataSource();
160  return;
161  }
162 
163  // Global variable case:
164  if ( GlobalsRepository::Instance()->hasAttribute( name ) ) {
165  ret = GlobalsRepository::Instance()->getValue(name)->getDataSource();
166  return;
167  }
168 
169  throw_(begin, "Value " + name + " not defined in "+ task->getName()+".");
170  }
171 
172  void ValueParser::seennull()
173  {
174  ret = new ConstantDataSource<char>( '\0' );
175  }
176 
177  void ValueParser::seencharconstant( iter_t c )
178  {
179  ret = new ConstantDataSource<char>( *c );
180  }
181 
182  void ValueParser::seenhexconstant( unsigned int i )
183  {
184  ret = new ConstantDataSource<unsigned int>( i );
185  }
186 
187  void ValueParser::seenintconstant( int i )
188  {
189  ret = new ConstantDataSource<int>( i );
190  }
191 
192  void ValueParser::seenuintconstant( unsigned int i ) // RobWork uint -> unsigned int
193  {
194  ret = new ConstantDataSource<unsigned int>( i ); // RobWork uint -> unsigned int
195  }
196 
197  void ValueParser::seenfloatconstant( double i )
198  {
199  ret = new ConstantDataSource<float>( float(i) );
200  }
201 
202  void ValueParser::seendoubleconstant( double i )
203  {
204  ret = new ConstantDataSource<double>( i );
205  }
206 
208  {
209  clear();
210  }
211 
213  {
214  propparser.reset();
215  }
216 
218  {
219  return constant;
220  }
221 
222  void ValueParser::push_str_char( char c )
223  {
224  mcurstring += c;
225  }
226 
227  void ValueParser::seenstring()
228  {
229  // due to our config parse rule, the '"' terminating a
230  // string will be in mcurstring, and we don't want it, so we
231  // remove it..
232  mcurstring.erase( mcurstring.end() - 1 );
233  ret = new ConstantDataSource<std::string>( mcurstring );
234  //deleter.reset( ret );
235  mcurstring.clear();
236  }
237 }
#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:51
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.