1 #ifndef _utl_UnitGrammar_h
2 #define _utl_UnitGrammar_h
12 #include <utl/AugerException.h>
13 #include <utl/ErrorLogger.h>
14 #include <utl/SymbolTable.h>
16 #include <boost/version.hpp>
17 #if BOOST_VERSION >= 103800
18 # define BOOST_SPIRIT_USE_OLD_NAMESPACE
19 # include <boost/spirit/include/classic.hpp>
20 # include <boost/spirit/include/phoenix1_binders.hpp>
21 # include <boost/spirit/include/phoenix1_functions.hpp>
23 # include <boost/spirit.hpp>
24 # include <boost/spirit/phoenix/binders.hpp>
25 # include <boost/spirit/phoenix/primitives.hpp>
26 # include <boost/spirit/phoenix/functions.hpp>
37 template<
typename T1,
typename T2>
40 template<
typename T1,
typename T2>
51 struct UnitGrammar :
public boost::spirit::grammar<UnitGrammar> {
56 #warning remove this! replace by singleton logic
61 const std::string
err =
"Cannot initialize UnitGrammar with variables!";
69 struct SValueClosure :
public boost::spirit::closure<SValueClosure, double> {
74 struct SAssignmentClosure :
public boost::spirit::closure<SAssignmentClosure, std::string, double> {
80 struct SStringClosure :
public boost::spirit::closure<SStringClosure, std::string> {
85 template<
typename ScannerT>
96 = boost::spirit::lexeme_d[(boost::spirit::alpha_p |
'_')
97 >> *(boost::spirit::alnum_p |
'_')][
98 identifier.name = phoenix::construct_<std::string>(phoenix::arg1, phoenix::arg2)
104 >> (boost::spirit::end_p |
';')
108 = boost::spirit::longest_d[boost::spirit::int_p[
literal.value = phoenix::arg1]
109 | boost::spirit::real_p[
literal.value = phoenix::arg1]]
115 |
identifier[
factor.value = phoenix::bind(&UnitGrammar::Lookup)(
self, phoenix::arg1)]
119 =
factor[term.value = phoenix::arg1] >>
121 (
'^' >>
factor[term.value =
power(term.value, phoenix::arg1)])
128 (
'*' >> term[
expression.value *= phoenix::arg1])
129 | (
'/' >> term[
expression.value /= phoenix::arg1])
137 boost::spirit::rule<ScannerT, SStringClosure::context_t>
identifier;
145 Lookup(
const std::string& symbol)
148 const SymbolTable::const_iterator it =
fSymbols->find(symbol);
154 "The symbol '" + symbol +
"' "
155 "is not defined during the evaluaion with the UnitGrammer\n";
169 #include <utl/AugerUnits.h>
170 #include <utl/ExpressionParser.h>
boost::spirit::rule< ScannerT > statement
UnitGrammar(double &result, const utl::SymbolTable &symbols)
throw XMLParseException(err)
boost::spirit::rule< ScannerT, SValueClosure::context_t > factor
double pow(const double x, const unsigned int i)
definition(UnitGrammar const &self)
const phoenix::function< PowerToImpl > power
boost::spirit::rule< ScannerT > const & start() const
boost::spirit::rule< ScannerT, SValueClosure::context_t > term
void SaveResult(const double val) const
UnitGrammar(double &result, const utl::SymbolTable &symbols, utl::SymbolTable &)
const SymbolTable * fSymbols
std::map< std::string, double > SymbolTable
boost::spirit::rule< ScannerT, SStringClosure::context_t > identifier
boost::spirit::rule< ScannerT, SValueClosure::context_t > expression
Boost spirit definition template (Read Boost Spirit documentation)
ExpressionParser< UnitGrammar, AugerUnits > AugerUnitParser
boost::spirit::rule< ScannerT, SValueClosure::context_t > group
boost::spirit::rule< ScannerT, SValueClosure::context_t > literal
T1 operator()(T1 &t1, T2 &t2) const