UnitGrammar.h
Go to the documentation of this file.
1 #ifndef _utl_UnitGrammar_h
2 #define _utl_UnitGrammar_h
3 
12 #include <utl/AugerException.h>
13 #include <utl/ErrorLogger.h>
14 #include <utl/SymbolTable.h>
15 
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>
22 #else
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>
27 #endif
28 
29 #include <string>
30 #include <map>
31 #include <cmath>
32 
33 namespace utl {
34 
35  // Raise X to power of Y template
36  struct PowerToImpl {
37  template<typename T1, typename T2>
38  struct result { typedef double type; };
39 
40  template<typename T1, typename T2>
41  T1 operator()(T1& t1, T2& t2) const
42  { return std::pow(t1, t2); }
43  };
44 
45 
46  // Create it as a constant Phoenix Function
47  const phoenix::function<PowerToImpl> power = PowerToImpl();
48 
49 
50  // Unit Grammar Structure
51  struct UnitGrammar : public boost::spirit::grammar<UnitGrammar> {
52 
53  UnitGrammar(double& result, const utl::SymbolTable& symbols)
54  : fSymbols(&symbols), fResult(&result) { }
55 
56 #warning remove this! replace by singleton logic
57  UnitGrammar(double& result, const utl::SymbolTable& symbols, utl::SymbolTable& ) :
58  fSymbols(&symbols),
59  fResult(&result)
60  {
61  const std::string err = "Cannot initialize UnitGrammar with variables!";
62  ERROR(err);
63  throw XMLParseException(err);
64  }
65 
66  //double GetResult() const { return fResult; }
67 
69  struct SValueClosure : public boost::spirit::closure<SValueClosure, double> {
70  member1 value;
71  };
72 
74  struct SAssignmentClosure : public boost::spirit::closure<SAssignmentClosure, std::string, double> {
75  member1 name;
76  member2 value;
77  };
78 
80  struct SStringClosure : public boost::spirit::closure<SStringClosure, std::string> {
81  member1 name;
82  };
83 
85  template<typename ScannerT>
86  struct definition {
87  definition(UnitGrammar const& self)
88  {
89  group
90  = '('
91  >> expression[group.value = phoenix::arg1]
92  >> ')'
93  ;
94 
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)
99  ]
100  ;
101 
102  statement
103  = expression[phoenix::bind(&UnitGrammar::SaveResult)(self, phoenix::arg1)]
104  >> (boost::spirit::end_p | ';')
105  ;
106 
107  literal
108  = boost::spirit::longest_d[boost::spirit::int_p[literal.value = phoenix::arg1]
109  | boost::spirit::real_p[literal.value = phoenix::arg1]]
110  ;
111 
112  factor
113  = literal[factor.value = phoenix::arg1]
114  | group[factor.value = phoenix::arg1]
115  | identifier[factor.value = phoenix::bind(&UnitGrammar::Lookup)(self, phoenix::arg1)]
116  ;
117 
118  term
119  = factor[term.value = phoenix::arg1] >>
120  *(
121  ('^' >> factor[term.value = power(term.value, phoenix::arg1)])
122  )
123  ;
124 
125  expression
126  = term[expression.value = phoenix::arg1] >>
127  *(
128  ('*' >> term[expression.value *= phoenix::arg1])
129  | ('/' >> term[expression.value /= phoenix::arg1])
130  )
131  ;
132 
133  }
134 
135  boost::spirit::rule<ScannerT> const& start() const { return statement; }
136  boost::spirit::rule<ScannerT> statement;
137  boost::spirit::rule<ScannerT, SStringClosure::context_t> identifier;
138  boost::spirit::rule<ScannerT, SValueClosure::context_t> expression, factor, group, literal, term;
139  };
140 
141  void SaveResult(const double val) const { *fResult = val; }
142 
144  double
145  Lookup(const std::string& symbol)
146  const
147  {
148  const SymbolTable::const_iterator it = fSymbols->find(symbol);
149  if (it != fSymbols->end()) {
150  return it->second;
151  }
152  // issue exception
153  std::string err =
154  "The symbol '" + symbol + "' "
155  "is not defined during the evaluaion with the UnitGrammer\n";
156  ERROR(err);
157  throw XMLParseException(err);
158  return 1;
159  }
160 
161  private:
163  mutable double* fResult;
164  };
165 
166 }
167 
168 
169 #include <utl/AugerUnits.h>
170 #include <utl/ExpressionParser.h>
171 
172 
173 namespace utl {
175 }
176 
177 
178 #endif
boost::spirit::rule< ScannerT > statement
Definition: UnitGrammar.h:136
UnitGrammar(double &result, const utl::SymbolTable &symbols)
Definition: UnitGrammar.h:53
throw XMLParseException(err)
boost::spirit::rule< ScannerT, SValueClosure::context_t > factor
Definition: UnitGrammar.h:138
std::string err
Definition: UnitGrammar.h:153
double pow(const double x, const unsigned int i)
definition(UnitGrammar const &self)
Definition: UnitGrammar.h:87
const phoenix::function< PowerToImpl > power
Definition: UnitGrammar.h:47
boost::spirit::rule< ScannerT > const & start() const
Definition: UnitGrammar.h:135
const Data result[]
boost::spirit::rule< ScannerT, SValueClosure::context_t > term
Definition: UnitGrammar.h:138
void SaveResult(const double val) const
Definition: UnitGrammar.h:141
UnitGrammar(double &result, const utl::SymbolTable &symbols, utl::SymbolTable &)
Definition: UnitGrammar.h:57
const SymbolTable * fSymbols
Definition: UnitGrammar.h:162
std::map< std::string, double > SymbolTable
Definition: SymbolTable.h:10
a second level trigger
Definition: XbT2.h:8
Assignment closure set.
Definition: UnitGrammar.h:74
boost::spirit::rule< ScannerT, SStringClosure::context_t > identifier
Definition: UnitGrammar.h:137
boost::spirit::rule< ScannerT, SValueClosure::context_t > expression
Definition: UnitGrammar.h:138
String closure set.
Definition: UnitGrammar.h:80
Boost spirit definition template (Read Boost Spirit documentation)
Definition: UnitGrammar.h:86
ExpressionParser< UnitGrammar, AugerUnits > AugerUnitParser
Definition: UnitGrammar.h:174
double * fResult
Definition: UnitGrammar.h:163
boost::spirit::rule< ScannerT, SValueClosure::context_t > group
Definition: UnitGrammar.h:138
boost::spirit::rule< ScannerT, SValueClosure::context_t > literal
Definition: UnitGrammar.h:138
T1 operator()(T1 &t1, T2 &t2) const
Definition: UnitGrammar.h:41

, generated on Tue Sep 26 2023.