24 #include <boost/algorithm/string.hpp>
55 throw cms::Exception(
"FailModule") <<
"\nError in parsing the logical expression = " << logicalExpressionVal
74 throw cms::Exception(
"FailModule") <<
"\nError in parsing the logical expression = " << logicalExpressionVal
83 logicalExpressionVal = logicalExpressionBS;
97 throw cms::Exception(
"FailModule") <<
"\nError in parsing the logical expression = " << logicalExpressionVal
103 throw cms::Exception(
"FileModule") <<
"\nError in parsing the numerical expression = " << numericalExpressionVal
115 throw cms::Exception(
"FileModule") <<
"\nError in building RPN vector for the logical expression = "
116 << logicalExpressionVal << std::endl;
145 LogDebug(
"L1TGlobal") <<
"\nGtLogicParser::checkLogicalExpression - "
146 <<
"\nInitial logical expression = '" << logicalExpressionVal <<
"'"
147 <<
"\nFinal logical expression = '" << logicalExpressionBS <<
"'\n"
150 logicalExpressionVal = logicalExpressionBS;
176 std::stack<TokenRPN> operatorStack;
178 static const std::string whitespaces =
" \r\v\n\t";
184 std::istringstream exprStringStream(logicalExpressionVal);
186 while (!exprStringStream.eof()) {
187 exprStringStream >> std::skipws >>
std::ws >> tokenString;
190 if (tokenString.find_first_not_of(whitespaces) == std::string::npos || tokenString.length() == 0) {
198 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
207 switch (actualOperation) {
215 int errorPosition = exprStringStream.tellg();
217 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
218 <<
"\n Syntax error during parsing: "
219 <<
"\n " << exprStringStream.str().substr(0, errorPosition) <<
"\n "
220 << exprStringStream.str().substr(errorPosition)
221 <<
"\n Returned empty RPN vector and result false." << std::endl;
231 operatorStack.push(rpnToken);
238 while (!operatorStack.empty() && operatorStack.top().operation ==
OP_NOT) {
242 operatorStack.push(rpnToken);
248 while (!operatorStack.empty() &&
249 (operatorStack.top().operation ==
OP_NOT || operatorStack.top().operation ==
OP_AND)) {
253 operatorStack.push(rpnToken);
259 while (!operatorStack.empty() &&
260 (operatorStack.top().operation ==
OP_NOT || operatorStack.top().operation ==
OP_XOR ||
261 operatorStack.top().operation ==
OP_AND)) {
266 operatorStack.push(rpnToken);
272 operatorStack.push(rpnToken);
278 if (operatorStack.empty()) {
279 int errorPosition = exprStringStream.tellg();
281 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
282 <<
"\n Syntax error during parsing - misplaced ')':"
283 <<
"\n " << exprStringStream.str().substr(0, errorPosition) <<
"\n "
284 << exprStringStream.str().substr(errorPosition)
285 <<
"\n Returned empty RPN vector and result false." << std::endl;
299 if (operatorStack.empty()) {
301 int errorPosition = exprStringStream.tellg();
303 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
304 <<
"\n Syntax error during parsing - misplaced ')':"
305 <<
"\n " << exprStringStream.str().substr(0, errorPosition) <<
"\n "
306 << exprStringStream.str().substr(errorPosition)
307 <<
"\n Returned empty RPN vector and result false." << std::endl;
324 lastOperation = actualOperation;
328 while (!operatorStack.empty()) {
330 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
331 <<
"\n Syntax error during parsing - missing ')':"
332 <<
"\n Returned empty RPN vector and result false." << std::endl;
348 if (it->operation ==
OP_OR || it->operation ==
OP_AND || it->operation ==
OP_XOR)
351 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
352 <<
"\n Syntax error during parsing - too many operators"
353 <<
"\n Returned empty RPN vector and result false." << std::endl;
362 edm::LogError(
"L1TGlobal") <<
"\nLogical expression = '" << logicalExpressionVal <<
"'"
363 <<
"\n Syntax error during parsing - too many operands"
364 <<
"\n Returned empty RPN vector and result false." << std::endl;
395 switch (it->operation) {
452 while (!exprStringStream.eof()) {
453 exprStringStream >> tokenString;
459 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
463 <<
"\n Invalid operation/operand " << operandNameVal
464 <<
"\n Returned index is by default out of range (-1)." << std::endl;
474 if (rpnToken.
operand == operandNameVal) {
486 lastOperation = actualOperation;
491 <<
"\n Operand " << operandNameVal <<
" not found in the logical expression"
492 <<
"\n Returned index is by default out of range (-1)." << std::endl;
513 while (!exprStringStream.eof()) {
514 exprStringStream >> tokenString;
520 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
524 <<
"\n Invalid operation/operand at position " << iOperand
525 <<
"\n Returned empty name by default." << std::endl;
535 if (tmpIndex == iOperand) {
547 lastOperation = actualOperation;
552 <<
"\n No operand found at position " << iOperand <<
"\n Returned empty name by default."
568 edm::LogError(
"L1TGlobal") <<
"\n Operand " << operandNameVal <<
" not found in the operand token vector"
569 <<
"\n Returned false by default." << std::endl;
584 edm::LogError(
"L1TGlobal") <<
"\n No operand with token number " << tokenNumberVal
585 <<
" found in the operand token vector"
586 <<
"\n Returned false by default." << std::endl;
600 edm::LogError(
"L1TGlobal") <<
"\n No built RPN vector exists."
601 <<
"\n Returned false by default." << std::endl;
606 std::stack<bool> resultStack;
615 switch (it->operation) {
622 b1 = resultStack.top();
624 resultStack.push(!b1);
629 b1 = resultStack.top();
631 b2 = resultStack.top();
633 resultStack.push(b1 || b2);
638 b1 = resultStack.top();
640 b2 = resultStack.top();
642 resultStack.push(b1 ^ b2);
647 b1 = resultStack.top();
649 b2 = resultStack.top();
651 resultStack.push(b1 && b2);
670 return resultStack.top();
705 while (!exprStringStream.eof()) {
706 exprStringStream >> tokenString;
712 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
716 <<
"\n Invalid operation/operand at position " << iOperand
717 <<
"\n Returned false by default." << std::endl;
728 if (tmpIndex == iOperand) {
738 <<
"\n Invalid result for operand at position " << iOperand <<
": "
739 << rpnToken.
operand <<
"\n It must be 0 or 1"
740 <<
"\n Returned false by default." << std::endl;
757 lastOperation = actualOperation;
762 <<
"\n No operand found at position " << iOperand <<
"\n Returned false by default."
787 switch (it->operation) {
838 edm::LogError(
"L1TGlobal") <<
"\n No built RPN vector exists."
839 <<
"\n Returned false by default." << std::endl;
844 std::stack<bool> resultStack;
853 switch (it->operation) {
860 b1 = resultStack.top();
862 resultStack.push(!b1);
867 b1 = resultStack.top();
869 b2 = resultStack.top();
871 resultStack.push(b1 || b2);
876 b1 = resultStack.top();
878 b2 = resultStack.top();
880 resultStack.push(b1 ^ b2);
885 b1 = resultStack.top();
887 b2 = resultStack.top();
889 resultStack.push(b1 && b2);
910 return resultStack.top();
936 while (!exprStringStream.eof()) {
937 exprStringStream >> tokenString;
939 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
943 <<
"\n Invalid operation/operand in logical expression."
944 <<
"\n Return empty logical expression." << std::endl;
951 convertedLogicalExpression.append(
getRuleFromType(actualOperation)->opString);
954 typedef std::map<std::string, int>::const_iterator CIter;
956 CIter it = nameToIntMap.find(rpnToken.
operand);
957 if (it != nameToIntMap.end()) {
958 intValue = it->second;
959 std::stringstream intStr;
961 convertedLogicalExpression.append(intStr.str());
966 <<
"\n Could not convert " << rpnToken.
operand <<
" to integer!"
967 <<
"\n Return empty logical expression." << std::endl;
974 convertedLogicalExpression.append(
" ");
975 lastOperation = actualOperation;
982 LogDebug(
"L1TGlobal") <<
"\nGtLogicParser::convertNameToIntLogicalExpression - "
984 <<
"\nLogical expression (int) = '" << convertedLogicalExpression <<
"'\n"
1015 while (!exprStringStream.eof()) {
1016 exprStringStream >> tokenString;
1018 actualOperation =
getOperation(tokenString, lastOperation, rpnToken);
1022 <<
"\n Invalid operation/operand in logical expression."
1023 <<
"\n Return empty logical expression." << std::endl;
1030 convertedLogicalExpression.append(
getRuleFromType(actualOperation)->opString);
1033 typedef std::map<int, std::string>::const_iterator CIter;
1037 std::istringstream iss(rpnToken.
operand);
1040 CIter it = intToNameMap.find(indexInt);
1041 if (it != intToNameMap.end()) {
1042 convertedLogicalExpression.append(it->second);
1047 <<
"\n Could not convert " << rpnToken.
operand <<
" to string!"
1048 <<
"\n Return empty logical expression." << std::endl;
1055 convertedLogicalExpression.append(
" ");
1056 lastOperation = actualOperation;
1088 std::vector<OperandToken> opVector;
1092 std::stack<OperandToken> tmpStack;
1093 std::vector<OperandToken> tmpVector;
1098 bool newOperandBlock =
true;
1099 bool oneBlockOnly =
true;
1100 bool operandOnly =
true;
1115 switch (it->operation) {
1121 if ((!newOperandBlock)) {
1122 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend();
1124 opVector.push_back(*itOp);
1134 newOperandBlock =
true;
1135 oneBlockOnly =
false;
1150 newOperandBlock =
false;
1151 operandOnly =
false;
1153 b1 = tmpStack.top();
1156 tmpStack.push(dummyToken);
1168 newOperandBlock =
false;
1169 operandOnly =
false;
1171 b1 = tmpStack.top();
1173 b2 = tmpStack.top();
1176 tmpStack.push(dummyToken);
1179 tmpVector.push_back(b1);
1188 tmpVector.push_back(b2);
1200 newOperandBlock =
false;
1201 operandOnly =
false;
1203 b1 = tmpStack.top();
1205 b2 = tmpStack.top();
1208 tmpStack.push(dummyToken);
1211 tmpVector.push_back(b1);
1220 tmpVector.push_back(b2);
1232 newOperandBlock =
false;
1233 operandOnly =
false;
1235 b1 = tmpStack.top();
1237 b2 = tmpStack.top();
1240 tmpStack.push(dummyToken);
1243 tmpVector.push_back(b1);
1252 tmpVector.push_back(b2);
1272 if (oneBlockOnly || operandOnly) {
1276 b1 = tmpStack.top();
1277 tmpVector.push_back(b1);
1281 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend(); itOp++) {
1282 opVector.push_back(*itOp);
1294 for (std::vector<OperandToken>::reverse_iterator itOp = tmpVector.rbegin(); itOp != tmpVector.rend(); itOp++) {
1295 opVector.push_back(*itOp);
1306 std::vector<OperandToken> opVectorU;
1307 opVectorU.reserve(opVector.size());
1309 for (std::vector<OperandToken>::const_iterator constIt = opVector.begin(); constIt != opVector.end(); constIt++) {
1310 bool tokenIncluded =
false;
1312 for (std::vector<OperandToken>::iterator itOpU = opVectorU.begin(); itOpU != opVectorU.end(); itOpU++) {
1313 if ((*itOpU).tokenName == (*constIt).tokenName) {
1314 tokenIncluded =
true;
1319 if (!tokenIncluded) {
1320 opVectorU.push_back(*constIt);
1362 rpnToken.
operand = tokenString;
1371 return actualOperation;
1402 dstExpression = srcExpression;
1405 while ((position = dstExpression.find_first_of(brackets, position)) != std::string::npos) {
1407 if (((position + 1) != std::string::npos) && (dstExpression[position + 1] !=
' ')) {
1408 dstExpression.insert(position + 1,
" ");
1412 if ((position != 0) && (dstExpression[position - 1] !=
' ')) {
1413 dstExpression.insert(position,
" ");
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
void buildOperandTokenVectorNumExp()
static void trim(std::string &s)
Log< level::Error, false > LogError
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
static struct OperationRule m_operationRules[]
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 std::atomic< unsigned int > counter
static int position[264][3]
GlobalLogicParser()
constructor(s)
virtual ~GlobalLogicParser()
destructor
void buildOperandTokenVector()
static constexpr float b2
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
virtual OperationType getOperation(const std::string &tokenString, OperationType lastOperation, TokenRPN &rpnToken) const
static constexpr float b1
bool setNumericalExpression(const std::string &)