7 #include <boost/tokenizer.hpp>
12 TrigConf::LogicParser::LogicParser()
16 void printSubExpr(
const std::string &
id,
const std::vector<std::string> & tokExpr,
size_t & front,
const size_t back) {
17 std::cout <<
id <<
": ";
18 for(
size_t i = front;
i<=back;
i++) {
19 std::cout << tokExpr[
i] <<
" ";
21 std::cout << std::endl;
24 size_t findMatchingClosingParenthesis(
const std::vector<std::string> & tokExpr,
size_t front,
size_t back) {
25 if(tokExpr[front]!=
"(") {
30 size_t matchingClosingPar = 0;
31 while(++
pos <= back) {
32 if(tokExpr[
pos]==
"(") {
35 if(tokExpr[
pos]==
")") {
39 matchingClosingPar =
pos;
43 if( matchingClosingPar == 0 ) {
44 printSubExpr(
"Search for matching parenthesis", tokExpr, front, back);
47 return matchingClosingPar;
52 std::shared_ptr<TrigConf::Logic>
54 std::unique_ptr<TrigConf::Logic>
node(
nullptr );
57 node = buildTree(exprTok);
58 node->setExpression(expr);
59 }
catch (LogicParsingException & ex) {
60 std::cerr <<
"Error in expression " << expr <<
":" << ex.msg() << std::endl;
64 return std::shared_ptr<TrigConf::Logic>(std::move(
node));
67 std::vector<std::string>
69 std::vector<std::string>
tokens;
71 for (
auto & tok : boost::tokenizer<boost::char_separator<char> > (expr, boost::char_separator<char>(
" ",
"()&|!")) ) {
79 std::unique_ptr<TrigConf::Logic>
80 TrigConf::LogicParser::buildTree(
const std::vector<std::string> & tokExpr)
const {
83 size_t back = tokExpr.size()-1;
84 return buildNode(tokExpr,front,back);
88 std::unique_ptr<TrigConf::Logic>
89 TrigConf::LogicParser::buildNode(
const std::vector<std::string> & tokExpr,
size_t front,
size_t back)
const {
91 auto logicLeft = findSubExpr(tokExpr,front, back);
97 std::string token = tokExpr[front];
98 if( token!=
"&" && token !=
"|" ) {
99 throw LogicParsingException(std::string(
"Did expect a & or | here, but got a ") + token +
".");
104 LogicOPS * logic = token==
"&" ?
static_cast<LogicOPS*
>(
new LogicAND(std::move(logicLeft))) :
static_cast<LogicOPS*
>(
new LogicOR(std::move(logicLeft)));
106 auto logicRight = buildNode(tokExpr, front, back);
108 if(logicRight->nodeType() == logic->nodeType()) {
109 auto subLogics =
static_cast<LogicOPS*
>(logicRight.get())->takeSubLogics();
110 for(
auto && sublogic : std::move(subLogics)) {
111 logic->addSubLogic(std::move(sublogic));
114 logic->addSubLogic(std::move(logicRight));
117 return std::unique_ptr<TrigConf::Logic>( logic );
127 std::unique_ptr<TrigConf::Logic>
128 TrigConf::LogicParser::findSubExpr(
const std::vector<std::string> & tokExpr,
size_t & front,
const size_t back)
const {
130 std::string token = tokExpr[front];
132 auto logic = std::unique_ptr<TrigConf::Logic>(
nullptr );
136 token = tokExpr[front];
138 logic = findSubExpr(tokExpr,front, back);
141 logic = std::unique_ptr<TrigConf::Logic>(
new LogicLeaf(token));
144 }
else if(token==
"(") {
145 size_t parEnd = findMatchingClosingParenthesis(tokExpr, front, back);
146 logic = buildNode(tokExpr,front+1,parEnd-1);
149 logic = std::unique_ptr<TrigConf::Logic>(
new LogicLeaf(token));