CMS 3D CMS Logo

GlobalLogicParser.cc
Go to the documentation of this file.
1 
15 // this class header
17 
18 // system include files
19 #include <stack>
20 
21 #include <iostream>
22 #include <sstream>
23 
24 #include <boost/algorithm/string.hpp>
25 
26 // user include files
27 
28 
31 
32 // forward declarations
33 
34 // constructor(s)
35 
36 // default constructor
38 
39  // empty, default C++ initialization for string and vector are enough
40 }
41 
42 
43 // from the RPN vector and the operand token vector
44 // no checks for consistency, empty logical and numerical expressions
45 // requires special care when used
47  const std::vector<OperandToken>& opTokenVector)
48 {
49  m_rpnVector = rpnVec;
50  m_operandTokenVector = opTokenVector;
51 
52 }
53 
54 
55 // from a constant logical expression
56 // numerical expression will be empty
58 {
59 
60  // checks also for syntactic correctness of the logical expression
61 
62  if ( !setLogicalExpression(logicalExpressionVal) ) {
63 
64  // error(s) in logical expression - printed in the relevant place
65  throw cms::Exception("FailModule")
66  << "\nError in parsing the logical expression = " << logicalExpressionVal
67  << std::endl;
68 
69  }
70 
71 }
72 
73 // from a non-constant logical expression - add/remove spaces if needed
74 // numerical expression will be empty
76 {
77 
78  // checks also for syntactic correctness of the logical expression
79 
80  // add spaces around brackets
81  std::string logicalExpressionBS;
82  addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
83 
84  // trim leading or trailing spaces
85  boost::trim(logicalExpressionBS);
86 
87  if ( !buildRpnVector(logicalExpressionBS) ) {
88  // error(s) in logical expression
89  throw cms::Exception("FailModule")
90  << "\nError in parsing the logical expression = " << logicalExpressionVal
91  << std::endl;
92  }
93 
94  //LogDebug("L1TGlobal")
95  // << "\nInitial logical expression = '" << logicalExpressionVal << "'"
96  // << "\nFinal logical expression = '" << logicalExpressionBS << "'\n"
97  // << std::endl;
98 
99  logicalExpressionVal = logicalExpressionBS;
100  m_logicalExpression = logicalExpressionVal;
101 
102  // build operand token vector
103  // dummy tokenNumber; tokenResult false
105 
106 }
107 
108 // from a logical and a numerical expression
110  const std::string numericalExpressionVal) {
111  // checks also for correctness
112 
113  if ( !setLogicalExpression(logicalExpressionVal) ) {
114 
115  // error(s) in logical expression - printed in the relevant place
116  throw cms::Exception("FailModule")
117  << "\nError in parsing the logical expression = " << logicalExpressionVal
118  << std::endl;
119 
120  }
121 
122  if ( !setNumericalExpression(numericalExpressionVal) ) {
123 
124  // error(s) in numerical expression - printed in the relevant place
125  throw cms::Exception("FileModule")
126  << "\nError in parsing the numerical expression = " << numericalExpressionVal
127  << std::endl;
128  }
129 
130 }
131 
132 // from a logical and a numerical expression
133 // no checks for correctness - use it only after the correctness was tested
135  const std::string& numericalExpressionVal, const bool dummy) {
136 
137  clearRpnVector();
138  if ( !buildRpnVector(logicalExpressionVal) ) {
139  throw cms::Exception("FileModule")
140  << "\nError in building RPN vector for the logical expression = "
141  << logicalExpressionVal
142  << std::endl;
143  }
144 
145  m_logicalExpression = logicalExpressionVal;
146  m_numericalExpression = numericalExpressionVal;
147 
148 }
149 
150 
151 // destructor
153 {
154  // empty now
155 }
156 
157 // public methods
158 
159 // check a logical expression for correctness - add/remove spaces if needed
161 
162  // add spaces around brackets
163  std::string logicalExpressionBS;
164  addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
165 
166  // trim leading or trailing spaces
167  boost::trim(logicalExpressionBS);
168 
169  clearRpnVector();
170 
171  if ( !buildRpnVector(logicalExpressionBS) ) {
172  return false;
173  }
174 
175  LogDebug("L1TGlobal") << "\nGtLogicParser::checkLogicalExpression - "
176  << "\nInitial logical expression = '" << logicalExpressionVal << "'"
177  << "\nFinal logical expression = '" << logicalExpressionBS << "'\n"
178  << std::endl;
179 
180  logicalExpressionVal = logicalExpressionBS;
181 
182 
183  return true;
184 
185 }
186 
196 bool GlobalLogicParser::buildRpnVector(const std::string& logicalExpressionVal)
197 {
198 
199  //LogDebug("L1TGlobal")
200  //<< "\nGtLogicParser::buildRpnVector - "
201  //<< "\nLogical expression = '" << logicalExpressionVal << "'\n"
202  //<< std::endl;
203 
204  OperationType actualOperation = OP_NULL;
205  OperationType lastOperation = OP_NULL;
206 
207  // token as string and as TokenRPN, stack to form the postfix notation
208  std::string tokenString;
209  TokenRPN rpnToken;
210  std::stack<TokenRPN> operatorStack;
211 
212  static const std::string whitespaces=" \r\v\n\t";
213 
214  // clear possible old rpn vector
215  clearRpnVector();
216 
217  // stringstream to separate all tokens
218  std::istringstream exprStringStream(logicalExpressionVal);
219 
220  while ( !exprStringStream.eof() ) {
221 
222  exprStringStream >> std::skipws >> std::ws >> tokenString;
223 
224  // skip the end
225  if (tokenString.find_first_not_of(whitespaces) == std::string::npos ||
226  tokenString.length() == 0) {
227 
228  //LogTrace("L1TGlobal")
229  //<< " Break for token string = " << tokenString
230  //<< std::endl;
231 
232  break;
233  }
234 
235  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
236 
237  //LogTrace("L1TGlobal")
238  //<< " Token string = '" << tokenString << "'"
239  //<< "\tActual Operation = " << actualOperation
240  //<< std::endl;
241 
242  // http://en.wikipedia.org/wiki/Postfix_notation#Converting_from_infix_notation
243 
244  switch (actualOperation) {
245  case OP_OPERAND: {
246  // operands get pushed to the postfix notation immediately
247  m_rpnVector.push_back(rpnToken);
248  }
249 
250  break;
251  case OP_INVALID: {
252 
253  int errorPosition = exprStringStream.tellg();
254 
255 
256  edm::LogError("L1TGlobal")
257  << "\nLogical expression = '" << logicalExpressionVal << "'"
258  << "\n Syntax error during parsing: "
259  << "\n " << exprStringStream.str().substr(0,errorPosition)
260  << "\n " << exprStringStream.str().substr(errorPosition)
261  << "\n Returned empty RPN vector and result false."
262  << std::endl;
263 
264  // clear the rpn vector before returning
265  clearRpnVector();
266 
267  return false;
268  }
269 
270  break;
271  case OP_NOT: {
272  operatorStack.push(rpnToken);
273  // there are no operators with higher precedence
274  }
275 
276  break;
277  case OP_XOR: {
278  // first pop operators with higher precedence (NOT)
279  while (!operatorStack.empty() && operatorStack.top().operation == OP_NOT) {
280  m_rpnVector.push_back(operatorStack.top());
281  operatorStack.pop();
282  }
283  operatorStack.push(rpnToken);
284  }
285 
286  break;
287  case OP_AND: {
288  // first pop operators with higher precedence (XOR, NOT)
289  while (!operatorStack.empty() &&
290  ( operatorStack.top().operation == OP_NOT ||
291  operatorStack.top().operation == OP_AND) ) {
292 
293  m_rpnVector.push_back(operatorStack.top());
294  operatorStack.pop();
295  }
296  operatorStack.push(rpnToken);
297  }
298 
299  break;
300  case OP_OR: {
301  // pop operators with higher precedence (AND, XOR, NOT)
302  while (!operatorStack.empty() &&
303  (operatorStack.top().operation == OP_NOT ||
304  operatorStack.top().operation == OP_XOR ||
305  operatorStack.top().operation == OP_AND) ) {
306 
307  m_rpnVector.push_back(operatorStack.top());
308  operatorStack.pop();
309  }
310  // push operator on stack
311  operatorStack.push(rpnToken);
312  }
313 
314  break;
315  case OP_OPENBRACKET: {
316 
317  // just push it on stack
318  operatorStack.push(rpnToken);
319  }
320 
321  break;
322  case OP_CLOSEBRACKET: {
323  // check if the operatorStack is empty
324  if (operatorStack.empty()) {
325 
326  int errorPosition = exprStringStream.tellg();
327 
328  edm::LogError("L1TGlobal")
329  << "\nLogical expression = '" << logicalExpressionVal << "'"
330  << "\n Syntax error during parsing - misplaced ')':"
331  << "\n " << exprStringStream.str().substr(0,errorPosition)
332  << "\n " << exprStringStream.str().substr(errorPosition)
333  << "\n Returned empty RPN vector and result false."
334  << std::endl;
335 
336  // clear the rpn vector before returning
337  clearRpnVector();
338 
339  return false;
340  }
341 
342  // pop stack until a left parenthesis is found
343  do {
344  if (operatorStack.top().operation != OP_OPENBRACKET) {
345  m_rpnVector.push_back(operatorStack.top()); // pop
346  operatorStack.pop();
347  }
348  if (operatorStack.empty()) { // the operatorStack must not be empty
349 
350  int errorPosition = exprStringStream.tellg();
351 
352  edm::LogError("L1TGlobal")
353  << "\nLogical expression = '" << logicalExpressionVal << "'"
354  << "\n Syntax error during parsing - misplaced ')':"
355  << "\n " << exprStringStream.str().substr(0,errorPosition)
356  << "\n " << exprStringStream.str().substr(errorPosition)
357  << "\n Returned empty RPN vector and result false."
358  << std::endl;
359 
360  // clear the rpn vector before returning
361  clearRpnVector();
362  return false;
363  }
364  } while (operatorStack.top().operation != OP_OPENBRACKET);
365 
366  operatorStack.pop(); // pop the open bracket.
367  }
368 
369  break;
370  default: {
371  // empty
372  }
373  break;
374  }
375 
376  lastOperation = actualOperation; // for the next turn
377 
378  }
379 
380  // pop the rest of the operator stack
381  while (!operatorStack.empty()) {
382  if (operatorStack.top().operation == OP_OPENBRACKET) {
383 
384  edm::LogError("L1TGlobal")
385  << "\nLogical expression = '" << logicalExpressionVal << "'"
386  << "\n Syntax error during parsing - missing ')':"
387  << "\n Returned empty RPN vector and result false."
388  << std::endl;
389 
390  // clear the rpn vector before returning
391  clearRpnVector();
392  return false;
393  }
394 
395  m_rpnVector.push_back(operatorStack.top());
396  operatorStack.pop();
397  }
398 
399  // count all operations and check if the result is 1
400  int counter = 0;
401  for(RpnVector::iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
402  if (it->operation == OP_OPERAND)
403  counter++;
404  if (it->operation == OP_OR || it->operation == OP_AND || it->operation == OP_XOR)
405  counter--;
406  if (counter < 1) {
407 
408  edm::LogError("L1TGlobal")
409  << "\nLogical expression = '" << logicalExpressionVal << "'"
410  << "\n Syntax error during parsing - too many operators"
411  << "\n Returned empty RPN vector and result false."
412  << std::endl;
413 
414  // clear the rpn vector before returning
415  clearRpnVector();
416  return false;
417  }
418  }
419 
420  if (counter > 1) {
421 
422  edm::LogError("L1TGlobal")
423  << "\nLogical expression = '" << logicalExpressionVal << "'"
424  << "\n Syntax error during parsing - too many operands"
425  << "\n Returned empty RPN vector and result false."
426  << std::endl;
427 
428  // clear the rpn vector before returning
429  clearRpnVector();
430  return false;
431  }
432  return true;
433 }
434 
435 
436 // clear rpn vector
438 {
439 
440  m_rpnVector.clear();
441 
442 }
443 
444 
445 // build from the RPN vector the operand token vector
446 // dummy tokenNumber and token result
448 {
449 
450  //LogTrace("L1TGlobal")
451  //<< "\nGtLogicParser::buildOperandTokenVector - "
452  //<< std::endl;
453 
454  // reserve memory
455  size_t rpnVectorSize = m_rpnVector.size();
456  m_operandTokenVector.reserve(rpnVectorSize);
457 
458  int opNumber = 0;
459 
460  for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
461 
462  //LogTrace("L1TGlobal")
463  //<< "\nit->operation = " << it->operation
464  //<< "\nit->operand = '" << it->operand << "'\n"
465  //<< std::endl;
466 
467  switch (it->operation) {
468 
469  case OP_OPERAND: {
470  OperandToken opToken;
471  opToken.tokenName = it->operand;
472  opToken.tokenNumber = opNumber;
473  opToken.tokenResult = false;
474 
475  m_operandTokenVector.push_back(opToken);
476 
477  }
478 
479  break;
480  case OP_NOT: {
481  // do nothing
482  }
483 
484  break;
485  case OP_OR: {
486  // do nothing
487  }
488 
489  break;
490  case OP_AND: {
491  // do nothing
492  }
493  case OP_XOR: {
494  // do nothing
495  }
496 
497  break;
498  default: {
499  // should not arrive here
500  }
501 
502  break;
503  }
504 
505  opNumber++;
506  }
507 
508 }
509 
510 
511 // return the position index of the operand in the logical expression
512 int GlobalLogicParser::operandIndex(const std::string& operandNameVal) const
513 {
514 
515  int result = -1;
516 
517  OperationType actualOperation = OP_NULL;
518  OperationType lastOperation = OP_NULL;
519 
520  std::string tokenString;
521  TokenRPN rpnToken; // token to be used by getOperation
522 
523  // stringstream to separate all tokens
524  std::istringstream exprStringStream(m_logicalExpression);
525 
526  // temporary index for usage in the loop
527  int tmpIndex = -1;
528 
529  while (!exprStringStream.eof()) {
530 
531  exprStringStream >> tokenString;
532 
533  //LogTrace("L1TGlobal")
534  //<< "Token string = " << tokenString
535  //<< std::endl;
536 
537  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
538  if (actualOperation == OP_INVALID) {
539 
540  // it should never be invalid
541  edm::LogError("L1TGlobal")
542  << "\nLogical expression = '" << m_logicalExpression << "'"
543  << "\n Invalid operation/operand " << operandNameVal
544  << "\n Returned index is by default out of range (-1)."
545  << std::endl;
546 
547  return result;
548 
549  }
550 
551  if (actualOperation != OP_OPERAND) {
552 
553  // do nothing
554 
555  } else {
556 
557  tmpIndex++;
558  if (rpnToken.operand == operandNameVal) {
559  result = tmpIndex;
560 
561  //LogDebug("L1TGlobal")
562  //<< "\nGtLogicParser::operandIndex - "
563  //<< "\nLogical expression = '" << m_logicalExpression << "'"
564  //<< "\nIndex of operand " << operandNameVal << " = " << result
565  //<< std::endl;
566 
567  return result;
568  }
569  }
570  lastOperation = actualOperation;
571  }
572 
573  //
574  edm::LogError("L1TGlobal")
575  << "\nLogical expression = '" << m_logicalExpression << "'"
576  << "\n Operand " << operandNameVal << " not found in the logical expression"
577  << "\n Returned index is by default out of range (-1)."
578  << std::endl;
579 
580  return result;
581 }
582 
583 // return the name of the (iOperand)th operand in the logical expression
585 {
586 
588 
589  OperationType actualOperation = OP_NULL;
590  OperationType lastOperation = OP_NULL;
591 
592  std::string tokenString;
593  TokenRPN rpnToken; // token to be used by getOperation
594 
595  // stringstream to separate all tokens
596  std::istringstream exprStringStream(m_logicalExpression);
597 
598  // temporary index for usage in the loop
599  int tmpIndex = -1;
600 
601  while (!exprStringStream.eof()) {
602 
603  exprStringStream >> tokenString;
604 
605  //LogTrace("L1TGlobal")
606  //<< "Token string = " << tokenString
607  //<< std::endl;
608 
609  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
610  if (actualOperation == OP_INVALID) {
611 
612  // it should never be invalid
613  edm::LogError("L1TGlobal")
614  << "\nLogical expression = '" << m_logicalExpression << "'"
615  << "\n Invalid operation/operand at position " << iOperand
616  << "\n Returned empty name by default."
617  << std::endl;
618 
619  return result;
620 
621  }
622 
623  if (actualOperation != OP_OPERAND) {
624 
625  // do nothing
626 
627  } else {
628 
629  tmpIndex++;
630  if (tmpIndex == iOperand) {
631  result = rpnToken.operand;
632 
633  //LogDebug("L1TGlobal")
634  //<< "\nGtLogicParser::operandName - "
635  //<< "\nLogical expression = '" << m_logicalExpression << "'"
636  //<< "\nOperand with index " << iOperand << " = " << result
637  //<< std::endl;
638 
639  return result;
640  }
641  }
642  lastOperation = actualOperation;
643  }
644 
645  //
646  edm::LogError("L1TGlobal")
647  << "\nLogical expression = '" << m_logicalExpression << "'"
648  << "\n No operand found at position " << iOperand
649  << "\n Returned empty name by default."
650  << std::endl;
651 
652  return result;
653 
654 }
655 
656 // return the result for an operand with name operandNameVal
657 // in the logical expression using the operand token vector
658 bool GlobalLogicParser::operandResult(const std::string& operandNameVal) const {
659 
660  for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
661 
662  if ((m_operandTokenVector[i]).tokenName == operandNameVal) {
663  return (m_operandTokenVector[i]).tokenResult;
664  }
665  }
666 
667  // return false - should not arrive here
668  edm::LogError("L1TGlobal")
669  << "\n Operand " << operandNameVal << " not found in the operand token vector"
670  << "\n Returned false by default."
671  << std::endl;
672 
673  return false;
674 
675 }
676 
677 // return the result for an operand with tokenNumberVal
678 // using the operand token vector
679 bool GlobalLogicParser::operandResult(const int tokenNumberVal) const {
680 
681  for (size_t i = 0; i < m_operandTokenVector.size(); ++i) {
682 
683  if ((m_operandTokenVector[i]).tokenNumber == tokenNumberVal) {
684  return (m_operandTokenVector[i]).tokenResult;
685  }
686  }
687 
688  // return false - should not arrive here
689  edm::LogError("L1TGlobal")
690  << "\n No operand with token number " << tokenNumberVal
691  << " found in the operand token vector"
692  << "\n Returned false by default."
693  << std::endl;
694 
695  return false;
696 
697 }
698 
699 // return the result for the logical expression
700 // require a proper operand token vector
702 {
703 
704  //LogTrace("L1TGlobal")
705  //<< "\nGtLogicParser::expressionResult - "
706  //<< std::endl;
707 
708  // return false if there is no RPN vector built
709  if ( m_rpnVector.empty() ) {
710  edm::LogError("L1TGlobal")
711  << "\n No built RPN vector exists."
712  << "\n Returned false by default."
713  << std::endl;
714  return false;
715  }
716 
717  // stack containing temporary results
718  std::stack<bool> resultStack;
719  bool b1, b2;
720 
721 
722  for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
723 
724  //LogTrace("L1TGlobal")
725  //<< "\nit->operation = " << it->operation
726  //<< "\nit->operand = '" << it->operand << "'\n"
727  //<< std::endl;
728 
729  switch (it->operation) {
730 
731  case OP_OPERAND: {
732  resultStack.push(operandResult(it->operand));
733  }
734 
735  break;
736  case OP_NOT: {
737  b1 = resultStack.top();
738  resultStack.pop(); // pop the top
739  resultStack.push(!b1); // and push the result
740  }
741 
742  break;
743  case OP_OR: {
744  b1 = resultStack.top();
745  resultStack.pop();
746  b2 = resultStack.top();
747  resultStack.pop();
748  resultStack.push(b1 || b2);
749  }
750 
751  break;
752  case OP_XOR: {
753  b1 = resultStack.top();
754  resultStack.pop();
755  b2 = resultStack.top();
756  resultStack.pop();
757  resultStack.push(b1 ^ b2);
758  }
759 
760  break;
761  case OP_AND: {
762  b1 = resultStack.top();
763  resultStack.pop();
764  b2 = resultStack.top();
765  resultStack.pop();
766  resultStack.push(b1 && b2);
767  }
768 
769  break;
770  default: {
771  // should not arrive here
772  }
773 
774  break;
775  }
776 
777  }
778 
779  // get the result in the top of the stack
780 
781  //LogTrace("L1TGlobal")
782  //<< "\nGtLogicParser::expressionResult - "
783  //<< "\nResult = " << resultStack.top()
784  //<< std::endl;
785 
786  return resultStack.top();
787 
788 
789 }
790 
791 
792 // return the result for an operand with name operandNameVal
793 // in the logical expression using a numerical expression
794 bool GlobalLogicParser::operandResultNumExp(const std::string& operandNameVal) const
795 {
796 
797  bool result = false;
798 
799  // get the position index of the operand in the logical string
800  const int iOperand = operandIndex(operandNameVal);
801 
802  result = operandResult(iOperand);
803 
804  return result;
805 
806 }
807 
808 // return the result for an operand with index iOperand
809 // in the logical expression using a numerical expression
810 bool GlobalLogicParser::operandResultNumExp(const int iOperand) const
811 {
812 
813  bool result = false;
814 
815  // parse the numerical expression
816 
817  OperationType actualOperation = OP_NULL;
818  OperationType lastOperation = OP_NULL;
819 
820  std::string tokenString;
821  TokenRPN rpnToken; // token to be used by getOperation
822 
823  // stringstream to separate all tokens
824  std::istringstream exprStringStream(m_numericalExpression);
825 
826  // temporary index for usage in the loop
827  int tmpIndex = -1;
828 
829  while (!exprStringStream.eof()) {
830 
831  exprStringStream >> tokenString;
832 
833  //LogTrace("L1TGlobal")
834  //<< "Token string = " << tokenString
835  //<< std::endl;
836 
837  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
838  if (actualOperation == OP_INVALID) {
839 
840  // it should never be invalid
841  edm::LogError("L1TGlobal")
842  << "\nNumerical expression = '" << m_numericalExpression << "'"
843  << "\n Invalid operation/operand at position " << iOperand
844  << "\n Returned false by default."
845  << std::endl;
846 
847  result = false;
848  return result;
849  }
850 
851  if (actualOperation != OP_OPERAND) {
852 
853  // do nothing
854 
855  } else {
856 
857  tmpIndex++;
858  if (tmpIndex == iOperand) {
859 
860  if (rpnToken.operand == "1") {
861  result = true;
862  } else {
863  if (rpnToken.operand == "0") {
864  result = false;
865  } else {
866  // something went wrong - break
867  //
868  edm::LogError("L1TGlobal")
869  << "\nNumerical expression = '" << m_numericalExpression << "'"
870  << "\n Invalid result for operand at position " << iOperand
871  << ": " << rpnToken.operand
872  << "\n It must be 0 or 1"
873  << "\n Returned false by default."
874  << std::endl;
875 
876  result = false;
877  return result;
878  }
879  }
880 
881  //LogDebug("L1TGlobal")
882  //<< "\nGtLogicParser::operandResult - "
883  //<< "\nNumerical expression = '" << m_numericalExpression << "'"
884  //<< "\nResult for operand with index " << iOperand
885  //<< " = " << result << "'\n"
886  //<< std::endl;
887 
888  return result;
889  }
890  }
891  lastOperation = actualOperation;
892  }
893 
894  //
895  edm::LogError("L1TGlobal")
896  << "\nNumerical expression = '" << m_numericalExpression << "'"
897  << "\n No operand found at position " << iOperand
898  << "\n Returned false by default."
899  << std::endl;
900 
901  return result;
902 
903 
904 }
905 
906 // build from the RPN vector the operand token vector
907 // using a numerical expression
909 {
910 
911  //LogTrace("L1TGlobal")
912  //<< "\nGtLogicParser::buildOperandTokenVector - "
913  //<< std::endl;
914 
915  // reserve memory
916  size_t rpnVectorSize = m_rpnVector.size();
917  m_operandTokenVector.reserve(rpnVectorSize);
918 
919  int opNumber = 0;
920 
921  for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
922 
923  //LogTrace("L1TGlobal")
924  //<< "\nit->operation = " << it->operation
925  //<< "\nit->operand = '" << it->operand << "'\n"
926  //<< std::endl;
927 
928  switch (it->operation) {
929 
930  case OP_OPERAND: {
931  OperandToken opToken;
932  opToken.tokenName = it->operand;
933  opToken.tokenNumber = opNumber;
934  opToken.tokenResult = operandResultNumExp(it->operand);
935 
936  m_operandTokenVector.push_back(opToken);
937 
938  }
939 
940  break;
941  case OP_NOT: {
942  // do nothing
943  }
944 
945  break;
946  case OP_OR: {
947  // do nothing
948  }
949 
950  break;
951  case OP_XOR: {
952  // do nothing
953  }
954 
955  break;
956  case OP_AND: {
957  // do nothing
958  }
959 
960  break;
961  default: {
962  // should not arrive here
963  }
964 
965  break;
966  }
967 
968  opNumber++;
969  }
970 
971 }
972 
973 
974 
975 // return the result for the logical expression
977 {
978 
979  //LogTrace("L1TGlobal")
980  //<< "\nGtLogicParser::expressionResult - "
981  //<< std::endl;
982 
983  // return false if there is no expression
984  if ( m_rpnVector.empty() ) {
985  edm::LogError("L1TGlobal")
986  << "\n No built RPN vector exists."
987  << "\n Returned false by default."
988  << std::endl;
989  return false;
990  }
991 
992  // stack containing temporary results
993  std::stack<bool> resultStack;
994  bool b1, b2;
995 
996 
997  for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
998 
999  //LogTrace("L1TGlobal")
1000  //<< "\nit->operation = " << it->operation
1001  //<< "\nit->operand = '" << it->operand << "'\n"
1002  //<< std::endl;
1003 
1004  switch (it->operation) {
1005 
1006  case OP_OPERAND: {
1007  resultStack.push(operandResultNumExp(it->operand));
1008  }
1009 
1010  break;
1011  case OP_NOT: {
1012  b1 = resultStack.top();
1013  resultStack.pop(); // pop the top
1014  resultStack.push(!b1); // and push the result
1015  }
1016 
1017  break;
1018  case OP_OR: {
1019  b1 = resultStack.top();
1020  resultStack.pop();
1021  b2 = resultStack.top();
1022  resultStack.pop();
1023  resultStack.push(b1 || b2);
1024  }
1025 
1026  break;
1027  case OP_XOR: {
1028  b1 = resultStack.top();
1029  resultStack.pop();
1030  b2 = resultStack.top();
1031  resultStack.pop();
1032  resultStack.push(b1 ^ b2);
1033  }
1034 
1035  break;
1036  case OP_AND: {
1037  b1 = resultStack.top();
1038  resultStack.pop();
1039  b2 = resultStack.top();
1040  resultStack.pop();
1041  resultStack.push(b1 && b2);
1042  }
1043 
1044  break;
1045  default: {
1046  // should not arrive here
1047  }
1048 
1049  break;
1050  }
1051 
1052  }
1053 
1054  // get the result in the top of the stack
1055 
1056  //LogTrace("L1TGlobal")
1057  //<< "\nGtLogicParser::expressionResult - "
1058  //<< "\nLogical expression = '" << m_logicalExpression << "'"
1059  //<< "\nNumerical expression = '" << m_numericalExpression << "'"
1060  //<< "\nResult = " << resultStack.top()
1061  //<< std::endl;
1062 
1063  return resultStack.top();
1064 
1065 
1066 }
1067 
1068 // convert the logical expression composed with names to
1069 // a logical expression composed with int numbers using
1070 // a (string, int) map
1071 
1073  const std::map<std::string, int>& nameToIntMap)
1074 {
1075 
1076 
1077  if (m_logicalExpression.empty()) {
1078 
1079  return;
1080  }
1081 
1082  // non-empty logical expression
1083 
1084  OperationType actualOperation = OP_NULL;
1085  OperationType lastOperation = OP_NULL;
1086 
1087  std::string tokenString;
1088  TokenRPN rpnToken; // token to be used by getOperation
1089 
1090  int intValue = -1;
1091 
1092  // stringstream to separate all tokens
1093  std::istringstream exprStringStream(m_logicalExpression);
1094  std::string convertedLogicalExpression;
1095 
1096  while (!exprStringStream.eof()) {
1097 
1098  exprStringStream >> tokenString;
1099 
1100  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
1101  if (actualOperation == OP_INVALID) {
1102 
1103  // it should never be invalid
1104  edm::LogError("L1TGlobal")
1105  << "\nLogical expression = '" << m_logicalExpression << "'"
1106  << "\n Invalid operation/operand in logical expression."
1107  << "\n Return empty logical expression."
1108  << std::endl;
1109 
1110  m_logicalExpression.clear();
1111  return;
1112 
1113  }
1114 
1115  if (actualOperation != OP_OPERAND) {
1116 
1117  convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
1118 
1119  } else {
1120 
1121  typedef std::map<std::string, int>::const_iterator CIter;
1122 
1123  CIter it = nameToIntMap.find(rpnToken.operand);
1124  if (it != nameToIntMap.end()) {
1125 
1126  intValue = it->second;
1127  std::stringstream intStr;
1128  intStr << intValue;
1129  convertedLogicalExpression.append(intStr.str());
1130 
1131  } else {
1132 
1133  // it should never be happen
1134  edm::LogError("L1TGlobal")
1135  << "\nLogical expression = '" << m_logicalExpression << "'"
1136  << "\n Could not convert " << rpnToken.operand << " to integer!"
1137  << "\n Return empty logical expression."
1138  << std::endl;
1139 
1140  m_logicalExpression.clear();
1141  return;
1142  }
1143 
1144  }
1145 
1146  convertedLogicalExpression.append(" "); // one whitespace after each token
1147  lastOperation = actualOperation;
1148  }
1149 
1150  // remove the last space
1151  //convertedLogicalExpression.erase(convertedLogicalExpression.size() - 1);
1152  boost::trim(convertedLogicalExpression);
1153 
1154  LogDebug("L1TGlobal")
1155  << "\nGtLogicParser::convertNameToIntLogicalExpression - "
1156  << "\nLogical expression (strings) = '" << m_logicalExpression << "'"
1157  << "\nLogical expression (int) = '" << convertedLogicalExpression << "'\n"
1158  << std::endl;
1159 
1160  // replace now the logical expression with strings with
1161  // the converted logical expression
1162 
1163  m_logicalExpression = convertedLogicalExpression;
1164 
1165  return;
1166 
1167 }
1168 
1169 // convert a logical expression composed with integer numbers to
1170 // a logical expression composed with names using a map (int, string)
1171 
1173  const std::map<int, std::string>& intToNameMap) {
1174 
1175  if (m_logicalExpression.empty()) {
1176 
1177  return;
1178  }
1179 
1180  // non-empty logical expression
1181 
1182  OperationType actualOperation = OP_NULL;
1183  OperationType lastOperation = OP_NULL;
1184 
1185  std::string tokenString;
1186  TokenRPN rpnToken; // token to be used by getOperation
1187 
1188  // stringstream to separate all tokens
1189  std::istringstream exprStringStream(m_logicalExpression);
1190  std::string convertedLogicalExpression;
1191 
1192  while (!exprStringStream.eof()) {
1193 
1194  exprStringStream >> tokenString;
1195 
1196  actualOperation = getOperation(tokenString, lastOperation, rpnToken);
1197  if (actualOperation == OP_INVALID) {
1198 
1199  // it should never be invalid
1200  edm::LogError("L1TGlobal") << "\nLogical expression = '" << m_logicalExpression
1201  << "'" << "\n Invalid operation/operand in logical expression."
1202  << "\n Return empty logical expression." << std::endl;
1203 
1204  m_logicalExpression.clear();
1205  return;
1206 
1207  }
1208 
1209  if (actualOperation != OP_OPERAND) {
1210 
1211  convertedLogicalExpression.append(getRuleFromType(actualOperation)->opString);
1212 
1213  } else {
1214 
1215  typedef std::map<int, std::string>::const_iterator CIter;
1216 
1217  // convert string to int
1218  int indexInt;
1219  std::istringstream iss(rpnToken.operand);
1220  iss >> std::dec >> indexInt;
1221 
1222  CIter it = intToNameMap.find(indexInt);
1223  if (it != intToNameMap.end()) {
1224 
1225  convertedLogicalExpression.append(it->second);
1226 
1227  } else {
1228 
1229  // it should never be happen
1230  edm::LogError("L1TGlobal") << "\nLogical expression = '"
1231  << m_logicalExpression << "'" << "\n Could not convert "
1232  << rpnToken.operand << " to string!"
1233  << "\n Return empty logical expression." << std::endl;
1234 
1235  m_logicalExpression.clear();
1236  return;
1237  }
1238 
1239  }
1240 
1241  convertedLogicalExpression.append(" "); // one whitespace after each token
1242  lastOperation = actualOperation;
1243  }
1244 
1245  // remove the last space
1246  //convertedLogicalExpression.erase(convertedLogicalExpression.size() - 1);
1247  boost::trim(convertedLogicalExpression);
1248 
1249  //LogDebug("L1TGlobal")
1250  // << "\nGtLogicParser::convertIntToNameLogicalExpression - "
1251  // << "\nLogical expression (int) = '" << m_logicalExpression << "'"
1252  // << "\nLogical expression (string) = '" << convertedLogicalExpression << "'\n"
1253  // << std::endl;
1254 
1255  // replace now the logical expression with int with
1256  // the converted logical expression
1257 
1258  m_logicalExpression = convertedLogicalExpression;
1259 
1260  return;
1261 
1262 }
1263 
1264 // return the list of operand tokens for the logical expression
1265 // which are to be used as seeds
1266 std::vector<GlobalLogicParser::OperandToken>
1268 
1269  //LogDebug("L1TGlobal")
1270  //<< "\nGtLogicParser::expressionSeedsOperandList - "
1271  //<< "\nLogical expression = '" << m_logicalExpression << "'"
1272  //<< "\nm_rpnVector.size() = " << m_rpnVector.size()
1273  //<< "\nm_operandTokenVector.size() = " << m_operandTokenVector.size()
1274  //<< std::endl;
1275 
1276  // seed list
1277  std::vector<OperandToken> opVector;
1278  opVector.reserve(m_operandTokenVector.size());
1279 
1280  // temporary results
1281  std::stack<OperandToken> tmpStack;
1282  std::vector<OperandToken> tmpVector;
1283  tmpVector.reserve(m_operandTokenVector.size());
1284 
1285  OperandToken b1, b2;
1286 
1287  bool newOperandBlock = true;
1288  bool oneBlockOnly = true;
1289  bool operandOnly = true;
1290 
1291  int iOperand = -1;
1292 
1293  OperandToken dummyToken;
1294  dummyToken.tokenName = "dummy";
1295  dummyToken.tokenNumber = -1;
1296  dummyToken.tokenResult = false;
1297 
1298  for(RpnVector::const_iterator it = m_rpnVector.begin(); it != m_rpnVector.end(); it++) {
1299 
1300  //LogTrace("L1TGlobal")
1301  //<< "\nit->operation = " << it->operation
1302  //<< "\nit->operand = '" << it->operand << "'\n"
1303  //<< std::endl;
1304 
1305  switch (it->operation) {
1306 
1307  // RPN always start a block with an operand
1308  case OP_OPERAND: {
1309 
1310  // more blocks with operations
1311  // push operands from previous block, if any in the tmpVector
1312  // (reverse order to compensate the stack push/top/pop)
1313  if ( (!newOperandBlock) ) {
1314 
1315  for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
1316  itOp != tmpVector.rend(); itOp++) {
1317 
1318  opVector.push_back(*itOp);
1319 
1320  //LogTrace("L1TGlobal")
1321  //<< " Push operand " << (*itOp).tokenName
1322  //<<" on the seed operand list"
1323  //<< std::endl;
1324 
1325  }
1326 
1327  tmpVector.clear();
1328 
1329  newOperandBlock = true;
1330  oneBlockOnly = false;
1331 
1332  }
1333 
1334 
1335  iOperand++;
1336 
1337  //LogTrace("L1TGlobal")
1338  //<< " Push operand " << (m_operandTokenVector.at(iOperand)).tokenName
1339  //<< " on the operand stack"
1340  //<< std::endl;
1341 
1342  tmpStack.push(m_operandTokenVector.at(iOperand));
1343  }
1344 
1345  break;
1346  case OP_NOT: {
1347 
1348  newOperandBlock = false;
1349  operandOnly = false;
1350 
1351  b1 = tmpStack.top();
1352  tmpStack.pop(); // pop the top
1353 
1354  tmpStack.push(dummyToken); // and push dummy result
1355 
1356  //LogTrace("L1TGlobal")
1357  //<< " Clear tmp operand list"
1358  //<< std::endl;
1359 
1360  tmpVector.clear();
1361 
1362  }
1363 
1364  break;
1365  case OP_OR: {
1366 
1367  newOperandBlock = false;
1368  operandOnly = false;
1369 
1370  b1 = tmpStack.top();
1371  tmpStack.pop();
1372  b2 = tmpStack.top();
1373  tmpStack.pop();
1374 
1375  tmpStack.push(dummyToken); // and push dummy result
1376 
1377  if ( b1.tokenNumber >= 0 ) {
1378  tmpVector.push_back(b1);
1379 
1380  //LogTrace("L1TGlobal")
1381  //<< " Push operand " << b1.tokenName
1382  //<<" on the tmp list"
1383  //<< std::endl;
1384  }
1385 
1386  if ( b2.tokenNumber >= 0 ) {
1387  tmpVector.push_back(b2);
1388 
1389  //LogTrace("L1TGlobal")
1390  //<< " Push operand " << b2.tokenName
1391  //<<" on the tmp list"
1392  //<< std::endl;
1393  }
1394 
1395  }
1396 
1397  break;
1398  case OP_XOR: {
1399 
1400  newOperandBlock = false;
1401  operandOnly = false;
1402 
1403  b1 = tmpStack.top();
1404  tmpStack.pop();
1405  b2 = tmpStack.top();
1406  tmpStack.pop();
1407 
1408  tmpStack.push(dummyToken); // and push dummy result
1409 
1410  if ( b1.tokenNumber >= 0 ) {
1411  tmpVector.push_back(b1);
1412 
1413  //LogTrace("L1TGlobal")
1414  //<< " Push operand " << b1.tokenName
1415  //<<" on the tmp list"
1416  //<< std::endl;
1417  }
1418 
1419  if ( b2.tokenNumber >= 0 ) {
1420  tmpVector.push_back(b2);
1421 
1422  //LogTrace("L1TGlobal")
1423  //<< " Push operand " << b2.tokenName
1424  //<<" on the tmp list"
1425  //<< std::endl;
1426  }
1427 
1428  }
1429 
1430  break;
1431  case OP_AND: {
1432 
1433  newOperandBlock = false;
1434  operandOnly = false;
1435 
1436  b1 = tmpStack.top();
1437  tmpStack.pop();
1438  b2 = tmpStack.top();
1439  tmpStack.pop();
1440 
1441  tmpStack.push(dummyToken);
1442 
1443 
1444  if ( b1.tokenNumber >= 0 ) {
1445  tmpVector.push_back(b1);
1446 
1447  //LogTrace("L1TGlobal")
1448  //<< " Push operand " << b1.tokenName
1449  //<<" on the tmp list"
1450  //<< std::endl;
1451  }
1452 
1453  if ( b2.tokenNumber >= 0 ) {
1454  tmpVector.push_back(b2);
1455 
1456  //LogTrace("L1TGlobal")
1457  //<< " Push operand " << b2.tokenName
1458  //<<" on the tmp list"
1459  //<< std::endl;
1460  }
1461 
1462  }
1463 
1464  break;
1465  default: {
1466  // should not arrive here
1467  }
1468 
1469  break;
1470  }
1471 
1472  }
1473 
1474 
1475  // one block only or one operand only
1476  if ( oneBlockOnly || operandOnly ) {
1477 
1478  // one operand only -
1479  // there can be only one operand, otherwise one needs an operation
1480  if (operandOnly) {
1481  b1 = tmpStack.top();
1482  tmpVector.push_back(b1);
1483  }
1484 
1485  //
1486  for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
1487  itOp != tmpVector.rend(); itOp++) {
1488 
1489  opVector.push_back(*itOp);
1490 
1491  //LogTrace("L1TGlobal")
1492  //<< " One block or one operand only: push operand " << (*itOp).tokenName
1493  //<<" on the seed operand list"
1494  //<< std::endl;
1495 
1496  }
1497 
1498  } else {
1499 
1500  //LogTrace("L1TGlobal")
1501  // << " More blocks: push the last block on the seed operand list" << std::endl;
1502 
1503  for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin();
1504  itOp != tmpVector.rend(); itOp++) {
1505 
1506  opVector.push_back(*itOp);
1507 
1508  //LogTrace("L1TGlobal")
1509  //<< " Push operand: " << (*itOp).tokenName
1510  //<<" on the seed operand list"
1511  //<< std::endl;
1512 
1513  }
1514 
1515  }
1516 
1517 
1518  // remove duplicates from the seed vector
1519  // slow...
1520  std::vector<OperandToken> opVectorU;
1521  opVectorU.reserve(opVector.size());
1522 
1523  for (std::vector<OperandToken>::const_iterator constIt = opVector.begin(); constIt
1524  != opVector.end(); constIt++) {
1525 
1526  bool tokenIncluded = false;
1527 
1528  for (std::vector<OperandToken>::iterator itOpU = opVectorU.begin(); itOpU
1529  != opVectorU.end(); itOpU++) {
1530 
1531  if ( ( *itOpU ).tokenName == ( *constIt ).tokenName) {
1532  tokenIncluded = true;
1533  break;
1534  }
1535  }
1536 
1537  if (!tokenIncluded) {
1538  opVectorU.push_back(*constIt);
1539  }
1540 
1541  }
1542 
1543 
1544  return opVectorU;
1545 
1546 }
1547 
1548 
1549 // private methods
1550 
1563  const std::string& tokenString,
1564  OperationType lastOperation, TokenRPN& rpnToken) const
1565 {
1566 
1567  OperationType actualOperation = OP_OPERAND; // default value
1568 
1569  int i = 0;
1570 
1571  while (m_operationRules[i].opType != OP_OPERAND) {
1572  if (tokenString == m_operationRules[i].opString) {
1573  actualOperation = (OperationType) m_operationRules[i].opType;
1574  break;
1575  }
1576  i++;
1577  }
1578 
1579  // check if the operation is allowed
1580  if (m_operationRules[i].forbiddenLastOperation & lastOperation) {
1581  return OP_INVALID;
1582  }
1583 
1584  //
1585  if (actualOperation == OP_OPERAND) {
1586 
1587  rpnToken.operand = tokenString;
1588 
1589  } else {
1590 
1591  rpnToken.operand = "";
1592  }
1593 
1594  rpnToken.operation = actualOperation;
1595 
1596  // else we got a valid operation
1597  return actualOperation;
1598 }
1599 
1611 {
1612 
1613 
1614  int i = 0;
1615 
1616  while (
1617  (m_operationRules[i].opType != oType) &&
1618  (m_operationRules[i].opType != OP_NULL) ) {
1619  i++;
1620  }
1621 
1622  if (m_operationRules[i].opType == OP_NULL) {
1623  return nullptr;
1624  }
1625 
1626  return &(m_operationRules[i]);
1627 }
1628 
1629 
1630 // add spaces before and after parentheses - make separation easier
1632  std::string& dstExpression) {
1633 
1634  static const std::string brackets = "()"; // the brackets to be found
1635 
1636  dstExpression = srcExpression; // copy the string
1637 
1638  size_t position = 0;
1639  while ((position = dstExpression.find_first_of(brackets, position))
1640  != std::string::npos) {
1641 
1642  // add space after if none is there
1643  if (((position + 1) != std::string::npos) && (dstExpression[position
1644  + 1] != ' ')) {
1645  dstExpression.insert(position + 1, " ");
1646  }
1647 
1648  // add space before if none is there
1649  if ((position != 0) && (dstExpression[position - 1] != ' ')) {
1650  dstExpression.insert(position, " ");
1651  position++;
1652  }
1653  position++;
1654  }
1655 }
1656 
1657 
1658 // set the logical expression - check for correctness the input string
1659 bool GlobalLogicParser::setLogicalExpression(const std::string& logicalExpressionVal)
1660 {
1661 
1662  // add spaces around brackets
1663  std::string logicalExpressionBS;
1664  addBracketSpaces(logicalExpressionVal, logicalExpressionBS);
1665 
1666  // trim leading or trailing spaces
1667  boost::trim(logicalExpressionBS);
1668 
1669  clearRpnVector();
1670 
1671  if ( !buildRpnVector(logicalExpressionBS) ) {
1672  m_logicalExpression = "";
1673  return false;
1674  }
1675 
1676  m_logicalExpression = logicalExpressionBS;
1677 
1678  //LogDebug("L1TGlobal")
1679  //<< "\nGtLogicParser::setLogicalExpression - "
1680  //<< "\nLogical expression = '" << m_logicalExpression << "'\n"
1681  //<< std::endl;
1682 
1683  return true;
1684 
1685 }
1686 
1687 // set the numerical expression (the logical expression with each operand
1688 // replaced with the value) from a string
1689 // check also for correctness the input string
1690 bool GlobalLogicParser::setNumericalExpression(const std::string& numericalExpressionVal)
1691 {
1692 
1693  // add spaces around brackets
1694  std::string numericalExpressionBS;
1695  addBracketSpaces(numericalExpressionVal, numericalExpressionBS);
1696 
1697  // check for consistency with the logical expression
1698  // TODO FIXME
1699 
1700  // trim leading or trailing spaces
1701  boost::trim(numericalExpressionBS);
1702 
1703  m_numericalExpression = numericalExpressionBS;
1704 
1705  //LogDebug("L1TGlobal")
1706  //<< "\nGtLogicParser::setNumericalExpression - "
1707  //<< "\nNumerical Expression = '" << m_numericalExpression << "'\n"
1708  //<< std::endl;
1709 
1710  return true;
1711 
1712 }
1713 
1714 
1715 // static members
1716 
1717 // rules for operations
1718 // 1st column: operation string
1719 // 2nd column: operation type
1720 // 3rd column: forbiddenLastOperation (what operation the operator/operand must not follow)
1721 const struct GlobalLogicParser::OperationRule GlobalLogicParser::m_operationRules[] =
1722  {
1723  { "AND", OP_AND, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL },
1724  { "OR", OP_OR, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL },
1725  { "XOR", OP_XOR, OP_AND | OP_OR | OP_XOR | OP_NOT | OP_OPENBRACKET | OP_NULL },
1726  { "NOT", OP_NOT, OP_OPERAND | OP_CLOSEBRACKET },
1729  { nullptr, OP_OPERAND, OP_OPERAND | OP_CLOSEBRACKET },
1730  { nullptr, OP_NULL, OP_NULL }
1731  };
#define LogDebug(id)
RpnVector m_rpnVector
RPN vector - equivalent to the logical expression.
virtual const bool expressionResult() const
const OperationRule * getRuleFromType(OperationType t)
get the rule entry to an operation type
std::vector< OperandToken > m_operandTokenVector
vector of operand tokens
signed integer value
Definition: value.h:26
void buildOperandTokenVectorNumExp()
static void trim(std::string &s)
virtual const bool expressionResultNumExp() const
bool setLogicalExpression(const std::string &)
set the logical expression - check for correctness the input string
std::string m_numericalExpression
std::vector< GlobalLogicParser::OperandToken > expressionSeedsOperandList()
void clearRpnVector()
clear possible old rpn vector
bool buildRpnVector(const std::string &)
build the rpn vector
std::string m_logicalExpression
logical expression to be parsed
int operandIndex(const std::string &operandNameVal) const
return the position index of the operand in the logical expression
void convertIntToNameLogicalExpression(const std::map< int, std::string > &intToNameMap)
void addBracketSpaces(const std::string &, std::string &)
add spaces before and after parantheses
std::vector< TokenRPN > RpnVector
bool checkLogicalExpression(std::string &)
check a logical expression for correctness - add/remove spaces if needed
void convertNameToIntLogicalExpression(const std::map< std::string, int > &nameToIntMap)
bool operandResultNumExp(const std::string &operandNameVal) const
bool operandResult(const std::string &operandNameVal) const
static int position[264][3]
Definition: ReadPGInfo.cc:509
GlobalLogicParser()
constructor(s)
virtual ~GlobalLogicParser()
destructor
static const struct OperationRule m_operationRules[]
std::string operandName(const int iOperand) const
return the name of the (iOperand)th operand in the logical expression
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle brackets
Definition: Activities.doc:4
virtual OperationType getOperation(const std::string &tokenString, OperationType lastOperation, TokenRPN &rpnToken) const
bool setNumericalExpression(const std::string &)