virtualsensor.cpp 2.54 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * virtualsensor.cpp
 *
 *  Created on: Jan 15, 2016
 *      Author: Axel Auweter
 */

#include "virtualsensor.h"
#include "virtualsensor_internal.h"

namespace DCDB {

/*
 * Implementations for VSExpressionParserException class.
 */
std::string VSExpressionParserException::msg_;
const char* VSExpressionParserException::what() const throw() {
   msg_ = runtime_error::what();
   msg_ += where_;
   msg_ += "\n";
   return msg_.c_str();
}

/*
 * Implementations for VSensor class.
 */
VSensor::VSensor(std::string expr) {
  impl = new VirtualSensor::VSensorImpl(expr);
}

VSensor::~VSensor() {
  if (impl) {
    delete impl;
  }
}

namespace VirtualSensor {
/*
 * Implementations for VSensorImpl class.
 */
void VSensorImpl::validateExpression(std::string expr)
{
  /* Try to generate AST */
  typedef std::string::const_iterator StringIterator;
  typedef ExpressionGrammar<StringIterator> Grammar;

  ascii::space_type space;
  Grammar grammar;

  StringIterator it = expr.begin();
  StringIterator end = expr.end();
  bool success = phrase_parse(it, end, grammar, space, opseq);

  if ((!success) || (it != end)) {
      std::string rest(it, end);
      throw VSExpressionParserException(rest);
  }

  /* Success - opseq now represents the top level of our AST */
}

void VSensorImpl::dumpAST()
{
  /* Declare a struct describing the action for each object in the AST when it comes to printing */
  struct ASTPrinter {
    typedef void result_type;
    void operator()(AST::Nil) const {}
    void operator()(unsigned int n) const { std::cout << n; }
    void operator()(AST::Op const& x) const {
      boost::apply_visitor(*this, x.oprnd);
      switch (x.oprtr) {
      case '+': std::cout << " add"; break;
      case '-': std::cout << " sub"; break;
      case '*': std::cout << " mul"; break;
      case '/': std::cout << " div"; break;
      }
    }
    void operator()(AST::Signd const& x) const {
      boost::apply_visitor(*this, x.oprnd);
      switch (x.sgn) {
      case '-': std::cout << " neg"; break;
      case '+': std::cout << " pos"; break;
      }
    }
    void operator()(AST::Opseq const& x) const {
      boost::apply_visitor(*this, x.frst);
      BOOST_FOREACH(AST::Op const& o, x.rst) {
        std::cout << ' ';
        (*this)(o);
      }
    }
  };

  ASTPrinter printer;
  printer(opseq);
  std::cout << std::endl;
}

VSensorImpl::VSensorImpl(std::string expr)
{
  /* Check if the expression is valid */
  validateExpression(expr);

  /* Dump AST */
  dumpAST();
}

VSensorImpl::~VSensorImpl()
{
}

} /* End of namespace VirtualSensor */
} /* End of namespace DCDB */