Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon May 10 19:10:37 CEST 2004 ValueParser.cxx 00003 00004 ValueParser.cxx - description 00005 ------------------- 00006 begin : Mon May 10 2004 00007 copyright : (C) 2004 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, * 00024 * Suite 330, Boston, MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 #include "parser-debug.hpp" 00029 #include "parse_exception.hpp" 00030 #include "ValueParser.hpp" 00031 #include "../Attribute.hpp" 00032 00033 #include "../TaskContext.hpp" 00034 #include "../Service.hpp" 00035 #include "../types/GlobalsRepository.hpp" 00036 00037 #include <boost/bind.hpp> 00038 #include <boost/lexical_cast.hpp> 00039 00040 #include <iostream> 00041 using namespace std; 00042 00043 namespace RTT 00044 { 00045 using boost::bind; 00046 using namespace detail; 00047 00048 ValueParser::ValueParser( TaskContext* tc, CommonParser& cp) 00049 : commonparser(cp), peerparser(tc,cp), propparser(cp), context(tc) 00050 { 00051 BOOST_SPIRIT_DEBUG_RULE( constant ); 00052 BOOST_SPIRIT_DEBUG_RULE( const_float ); 00053 BOOST_SPIRIT_DEBUG_RULE( const_double ); 00054 BOOST_SPIRIT_DEBUG_RULE( const_int ); 00055 BOOST_SPIRIT_DEBUG_RULE( const_hex ); 00056 BOOST_SPIRIT_DEBUG_RULE( const_uint ); 00057 BOOST_SPIRIT_DEBUG_RULE( const_char ); 00058 BOOST_SPIRIT_DEBUG_RULE( const_bool ); 00059 BOOST_SPIRIT_DEBUG_RULE( const_string ); 00060 BOOST_SPIRIT_DEBUG_RULE( named_constant ); 00061 00062 // note the order is important: commonparser.identifier throws a 00063 // useful "cannot use x as identifier" error if it fails, so we 00064 // must first show all non-identifier rules. 00065 constant = 00066 const_float 00067 | const_double 00068 | const_hex 00069 | const_int 00070 | const_uint 00071 | const_bool 00072 | const_char 00073 | const_string 00074 | named_constant; 00075 00076 const_float = 00077 strict_real_p [ 00078 boost::bind( &ValueParser::seenfloatconstant, this, _1 ) ] >> ch_p('f'); 00079 00080 const_double = 00081 strict_real_p [ 00082 boost::bind( &ValueParser::seendoubleconstant, this, _1 ) ]; 00083 00084 const_hex = (str_p("0x") | str_p("0X")) >> 00085 hex_p [ 00086 boost::bind( &ValueParser::seenhexconstant, this, _1 ) ]; 00087 00088 const_int = 00089 int_p [ 00090 boost::bind( &ValueParser::seenintconstant, this, _1 ) ]; 00091 00092 const_uint = 00093 uint_p [ 00094 boost::bind( &ValueParser::seenuintconstant, this, _1 ) ] >> ch_p('u'); 00095 00096 const_bool = 00097 ( keyword_p( "true" ) | keyword_p("false") )[ 00098 boost::bind( &ValueParser::seenboolconstant, this, _1, _2 ) ]; 00099 00100 const_char = (ch_p('\'') >> ch_p('\\') >> ch_p('0') >> ch_p('\''))[boost::bind( &ValueParser::seennull,this)] | 00101 confix_p( "'", (c_escape_ch_p[ boost::bind( &ValueParser::seencharconstant, this, _1 ) ]) , "'" ); 00102 00103 const_string = lexeme_d[confix_p( 00104 ch_p( '"' ), *c_escape_ch_p[ boost::bind( &ValueParser::push_str_char, this, _1 ) ], '"' )[ boost::bind( &ValueParser::seenstring, this ) ]]; 00105 00106 named_constant = 00107 ( keyword_p("done")[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ] 00108 | 00109 ( peerparser.locator()[boost::bind( &ValueParser::seenpeer, this) ] 00110 >> propparser.locator() 00111 >> commonparser.identifier[boost::bind( &ValueParser::seennamedconstant, this, _1, _2 ) ]) ) 00112 ; 00113 } 00114 00115 void ValueParser::seenpeer() { 00116 // inform propparser of new peer : 00117 //std::cerr << "ValueParser: seenpeer : "<< peerparser.taskObject()->getName() 00118 // <<" has props :" << (peerparser.taskObject()->properties() != 0) << std::endl; 00119 propparser.setPropertyBag( peerparser.taskObject()->properties() ); 00120 } 00121 00122 void ValueParser::seenboolconstant( iter_t begin, iter_t end ) 00123 { 00124 std::string value( begin, end ); 00125 assert( value == "true" || value == "false" ); 00126 if ( value == "true" ) 00127 ret = 00128 new ConstantDataSource<bool>( true ); 00129 else 00130 ret = 00131 new ConstantDataSource<bool>( false ); 00132 } 00133 00134 void ValueParser::seennamedconstant( iter_t begin, iter_t end ) 00135 { 00136 std::string name( begin, end ); 00137 Service::shared_ptr task = peerparser.taskObject(); 00138 peerparser.reset(); 00139 //std::cerr << "ValueParser: seenvar : "<< name 00140 // <<" is bag : " << (propparser.bag() != 0) << " is prop: "<< (propparser.property() != 0) << std::endl; 00141 // in case our task is a taskcontext: 00142 if ( task && propparser.bag() && propparser.property() ) { 00143 // nested property case : 00144 if ( ! propparser.bag()->find( name ) ) { 00145 //std::cerr << "In "<<peer->getName() <<" : " << name << " not present"<<std::endl; 00146 throw parse_exception_semantic_error("Property " + name + " not present in PropertyBag "+propparser.property()->getName()+" in "+ task->getName()+"."); 00147 } 00148 ret = propparser.bag()->find( name )->getDataSource(); 00149 propparser.reset(); 00150 return; 00151 } 00152 00153 // non-nested property or attribute case : 00154 if ( task && task->hasAttribute( name ) ) { 00155 ret = task->getValue(name)->getDataSource(); 00156 return; 00157 } 00158 if ( task && task->hasProperty( name ) ) { 00159 ret = task->properties()->find(name)->getDataSource(); 00160 return; 00161 } 00162 00163 // Global variable case: 00164 if ( GlobalsRepository::Instance()->hasAttribute( name ) ) { 00165 ret = GlobalsRepository::Instance()->getValue(name)->getDataSource(); 00166 return; 00167 } 00168 00169 throw_(begin, "Value " + name + " not defined in "+ task->getName()+"."); 00170 } 00171 00172 void ValueParser::seennull() 00173 { 00174 ret = new ConstantDataSource<char>( '\0' ); 00175 } 00176 00177 void ValueParser::seencharconstant( iter_t c ) 00178 { 00179 ret = new ConstantDataSource<char>( *c ); 00180 } 00181 00182 void ValueParser::seenhexconstant( unsigned int i ) 00183 { 00184 ret = new ConstantDataSource<unsigned int>( i ); 00185 } 00186 00187 void ValueParser::seenintconstant( int i ) 00188 { 00189 ret = new ConstantDataSource<int>( i ); 00190 } 00191 00192 void ValueParser::seenuintconstant( unsigned int i ) // RobWork uint -> unsigned int 00193 { 00194 ret = new ConstantDataSource<unsigned int>( i ); // RobWork uint -> unsigned int 00195 } 00196 00197 void ValueParser::seenfloatconstant( double i ) 00198 { 00199 ret = new ConstantDataSource<float>( float(i) ); 00200 } 00201 00202 void ValueParser::seendoubleconstant( double i ) 00203 { 00204 ret = new ConstantDataSource<double>( i ); 00205 } 00206 00207 ValueParser::~ValueParser() 00208 { 00209 clear(); 00210 } 00211 00212 void ValueParser::clear() 00213 { 00214 propparser.reset(); 00215 } 00216 00217 rule_t& ValueParser::parser() 00218 { 00219 return constant; 00220 } 00221 00222 void ValueParser::push_str_char( char c ) 00223 { 00224 mcurstring += c; 00225 } 00226 00227 void ValueParser::seenstring() 00228 { 00229 // due to our config parse rule, the '"' terminating a 00230 // string will be in mcurstring, and we don't want it, so we 00231 // remove it.. 00232 mcurstring.erase( mcurstring.end() - 1 ); 00233 ret = new ConstantDataSource<std::string>( mcurstring ); 00234 //deleter.reset( ret ); 00235 mcurstring.clear(); 00236 } 00237 }