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_; }
UnitsMap units_map_
Define all base and derived units given by their symbol.
static const BasicFactors basic_factors
Define all base and derived units given by their symbol.
Class manages parsing of user defined field unit.
std::string unit_data_key_
key of actual item of unit_data_
UnitData unit_data_
Full parsed data.
void check_unit_data()
Check unit_data_ object.
void new_div_factor(Iter_type begin, Iter_type end)
Add new factor of unit (factor is dividing)
void throw_not_equating(Iter_type begin, Iter_type end)
Throw exception if sign '=' missing in definition.
void new_exp(boost::int64_t i)
Compute exponent to actual factor of unit.
Semantic_actions()
Constructor.
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end) const
void throw_not_shortcut(Iter_type begin, Iter_type end)
Throw exception if shortcut of factor is not in correct format.
void throw_exp_not_int(Iter_type begin, Iter_type end)
Throw exception if exponent is not in correct format.
void new_mult_factor(Iter_type begin, Iter_type end)
Add new factor of unit (factor is multiplying)
void new_shortcut(Iter_type begin, Iter_type end)
Add new definition of formula.
int factor_idx_
index to actual item of subvector of factors of unit_data_
void new_multipl(double d)
Add multipicative coeficient of unit.
UnitData unit_data() const
Semantic_actions & operator=(const Semantic_actions &)
spirit_namespace::rule< ScannerT > exp_
spirit_namespace::rule< ScannerT > formula_
spirit_namespace::rule< ScannerT > constant_multiplicator_
spirit_namespace::rule< ScannerT > forbidden_char_
const spirit_namespace::rule< ScannerT > & start() const
spirit_namespace::rule< ScannerT > constant_value_
definition(const UnitSIGrammer &self)
spirit_namespace::rule< ScannerT > constant_
spirit_namespace::rule< ScannerT > shortcut_err_
spirit_namespace::rule< ScannerT > constant_err_
spirit_namespace::rule< ScannerT > exp_err_
spirit_namespace::rule< ScannerT > formula_factor_
spirit_namespace::rule< ScannerT > unit_
Definition of unit grammar.
UnitSIGrammer & operator=(const UnitSIGrammer &)
UnitSIGrammer(Semantic_actions_t &semantic_actions)
Constructor.
Semantic_actions< Iter_type > Semantic_actions_t
Semantic_actions_t & actions_
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p
const spirit_namespace::int_parser< boost::int64_t > int64_p
Store structure given by parser.