18 #ifndef UNIT_CONVERTER_TEMPLATE_HH_
19 #define UNIT_CONVERTER_TEMPLATE_HH_
22 #include <boost/bind.hpp>
23 #include <boost/function.hpp>
24 #include <boost/version.hpp>
27 #if BOOST_VERSION >= 103800
28 #include <boost/spirit/include/classic_core.hpp>
29 #include <boost/spirit/include/classic_confix.hpp>
30 #include <boost/spirit/include/classic_escape_char.hpp>
31 #include <boost/spirit/include/classic_multi_pass.hpp>
32 #include <boost/spirit/include/classic_position_iterator.hpp>
33 #define spirit_namespace boost::spirit::classic
35 #include <boost/spirit/core.hpp>
36 #include <boost/spirit/utility/confix.hpp>
37 #include <boost/spirit/utility/escape_char.hpp>
38 #include <boost/spirit/iterator/multi_pass.hpp>
39 #include <boost/spirit/iterator/position_iterator.hpp>
40 #define spirit_namespace boost::spirit
47 const spirit_namespace::int_parser < boost::int64_t >
int64_p = spirit_namespace::int_parser < boost::int64_t >();
48 const spirit_namespace::uint_parser< boost::uint64_t >
uint64_p = spirit_namespace::uint_parser< boost::uint64_t >();
72 template<
class Iter_type >
86 std::string key =
get_str(begin, end);
121 std::stringstream ss;
122 ss <<
"Value of exponent '" <<
get_str( begin, end ) <<
"' is not integer";
123 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
129 std::stringstream ss;
131 ss <<
"Missing declaration of shortcut '.." <<
get_str( begin-4, end+4 ) <<
"..'";
133 ss <<
"Invalid shortcut of unit '" <<
get_str( begin, end ) <<
"'";
135 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
141 std::stringstream ss;
142 ss <<
"Invalid expression '" <<
get_str( begin, end ) <<
"', missing '='";
143 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
160 formula_it !=
it->second.factors_.end(); ++formula_it)
162 if (formula_it->factor_ ==
it->first) {
163 std::stringstream ss;
164 ss <<
"Cyclic declaration of unit '" <<
it->first <<
"'";
165 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
169 std::stringstream ss;
170 ss <<
"Shortcut '" << formula_it->factor_ <<
"' is in conflict with predefined unit";
171 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
173 formula_it->basic_ =
false;
176 std::stringstream ss;
177 ss <<
"Unit '" << formula_it->factor_ <<
"' is not defined";
178 THROW( ExcInvalidUnit() << EI_UnitError(ss.str()) );
192 inline std::string
get_str( std::string::const_iterator begin, std::string::const_iterator end )
const
194 return std::string( begin, end );
209 template<
class Iter_type >
210 class UnitSIGrammer :
public spirit_namespace::grammar< UnitSIGrammer< Iter_type > >
224 template<
typename ScannerT >
236 typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
237 typedef boost::function< void(
double ) > Real_action;
238 typedef boost::function< void( boost::int64_t ) > Int_action;
264 | ( alpha_p >> *( anychar_p - ch_p(
';') - ch_p(
'*') - ch_p(
'/') - ch_p(
'=') - ch_p(
'^') - space_p ) )
280 = +( anychar_p - ch_p(
';') )
284 = strict_real_p[ new_multipl ]
294 = +( anychar_p - ch_p(
';') - ch_p(
'*') - ch_p(
'/') - space_p )
298 = *( anychar_p - ch_p(
';') - ch_p(
'*') - ch_p(
'/') - ch_p(
';') - ch_p(
'^') )
302 = *( alnum_p | ch_p(
'_') )
303 >> ( anychar_p - alnum_p - ch_p(
'_') - ch_p(
';') - ch_p(
'*') - ch_p(
'/') - ch_p(
'=') - ch_p(
'^') - space_p )
304 >> *( alnum_p | ch_p(
'_') )
312 const spirit_namespace::rule< ScannerT >&
start()
const {
return unit_; }