00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00063
00064
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 ( str_p( "true" ) | "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 ( str_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
00117
00118
00119 propparser.setPropertyBag( peerparser.peer()->provides()->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
00140
00141
00142 if ( task && propparser.bag() && propparser.property() ) {
00143
00144 if ( ! propparser.bag()->find( name ) ) {
00145
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
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
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 )
00193 {
00194 ret = new ConstantDataSource<unsigned int>( i );
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
00230
00231
00232 mcurstring.erase( mcurstring.end() - 1 );
00233 ret = new ConstantDataSource<std::string>( mcurstring );
00234
00235 mcurstring.clear();
00236 }
00237 }