ExpressionParser.h
Go to the documentation of this file.
1 #ifndef _utl_ExpressionParser_h_
2 #define _utl_ExpressionParser_h_
3 
12 #include <utl/SymbolTable.h>
13 
14 #include <utl/ExpressionParser.h>
15 #include <utl/AugerUnits.h>
16 #include <utl/AugerException.h>
17 #include <utl/ErrorLogger.h>
18 
19 // #define BOOST_SPIRIT_DEBUG
20 
21 #include <boost/version.hpp>
22 #if BOOST_VERSION >= 103800
23 # define BOOST_SPIRIT_USE_OLD_NAMESPACE
24 # include <boost/spirit/include/classic_parser.hpp>
25 # include <boost/spirit/include/classic.hpp>
26 # include <boost/spirit/include/phoenix1_binders.hpp>
27 # include <boost/spirit/include/phoenix1_functions.hpp>
28 #else
29 # include <boost/spirit/core/parser.hpp>
30 # include <boost/spirit.hpp>
31 # include <boost/spirit/phoenix/binders.hpp>
32 # include <boost/spirit/phoenix/primitives.hpp>
33 # include <boost/spirit/phoenix/functions.hpp>
34 #endif
35 
36 #include <string>
37 #include <map>
38 #include <iostream>
39 #include <iomanip>
40 #include <sstream>
41 
42 
43 namespace utl {
44 
45  template<class Grammar, class Symbols>
47 
48  public:
49  ExpressionParser() = default;
50  ExpressionParser(utl::SymbolTable& variables) : fVariables(variables) { }
51 
52  double
53  Evaluate(const std::string& expression_in)
54  const
55  {
56  double result = 0;
57  std::string expression = expression_in; // todo: non-const really needed ???
58  std::string::iterator firstChar = expression.begin();
59  const std::string::iterator lastChar = expression.end();
60  boost::spirit::parse_info<std::string::iterator> info;
61  do {
62  info =
63  boost::spirit::parse(
64  firstChar, lastChar,
65  (fVariables.empty() ?
66  Grammar(result, Symbols::GetSymbolMap()) :
67  Grammar(result, Symbols::GetSymbolMap(), fVariables)),
68  boost::spirit::space_p
69  );
70  if (!info.hit) { // not successful parsing
71  std::ostringstream err;
72  const int errPosition = info.stop - firstChar;
73  const char errChar = expression[errPosition];
74  if (errChar == '-' || errChar == '+')
75  err << "Bad symbol";
76  if (errChar == '(' || errChar == ')')
77  err << "Bad bracket";
78  else
79  err << "Parsing error";
80  err << " at location " << errPosition << " \'" << errChar << "\'";
81  ERROR(err);
82  throw XMLParseException(err.str());
83  firstChar = info.stop; // next start point
84  } else if (!info.full) { // ok, but no full match
85  const std::string err = "Parsing incomplete";
86  ERROR(err);
87  throw XMLParseException(err);
88  }
89  } while(!info.full && info.hit); // full match and parsing is ok
90  return result;
91  }
92 
94  const SymbolTable& GetVariables() const { return fVariables; }
95  int GetNVariables() const { return fVariables.size(); }
96 
97  bool HasVariable(const std::string& name) const { return fVariables.count(name); }
98  void SetVariable(const std::string& name, const double& v) { fVariables[name] = v; }
99  double GetVariable(const std::string& name) const { return fVariables.find(name)->second; }
100 
101  private:
103 
104  };
105 
106 }
107 
108 
109 #endif
boost::spirit::parse_info< std::string::iterator > info
std::string::iterator firstChar
Exception for errors encountered when parsing XML.
int GetNVariables() const
void SetVariable(const std::string &name, const double &v)
ExpressionParser()=default
std::map< std::string, double > SymbolTable
Definition: SymbolTable.h:10
const SymbolTable & GetVariables() const
const std::string::iterator lastChar
ExpressionParser(utl::SymbolTable &variables)
utl::SymbolTable fVariables
double GetVariable(const std::string &name) const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
bool HasVariable(const std::string &name) const
SymbolTable & GetVariables()

, generated on Tue Sep 26 2023.