void CConditionalFormulaParser::startParsing(std::string formula) { std::regex exp("^\\((([A-Z]|[0-9\\-]+)([<>=!]+)([A-Z]|[0-9\\-]+))\\)\\?([^:]+):(.+)$"); std::smatch result; if (!std::regex_match(formula, result, exp)) throw "Wrong Conditional Statement"; _preparedFormula.operandA = makeOperand(result[2].str()); _preparedFormula.operandB = makeOperand(result[4].str()); std::function<bool(double, double)> func; std::string actions[] = { ">","<","=","!=",">=","<=" }; std::function<bool(double, double)> functions[] = { isgreater<double,double>,isless<double,double>,std::equal_to<double>(),std::not_equal_to<double>(),isgreaterequal<double,double>,islessequal<double,double> }; for (int i = 0; i < 6; i++) { if (result[3].str()==(actions[i])) { func = functions[i]; break; } } if (func == NULL) { throw "Wrong Conditional Statement"; } _preparedFormula.function = func; _preparedFormula.trueFormula = makePolandNotation(result[5].str()); _preparedFormula.falseFormula = makePolandNotation(result[6].str()); }
std::string CFormulaParser::makePolandNotation(std::string formula) { std::stack<char> stack; std::string result,num; std::map<char, std::map<char, char>> priorities = makePriorityList(); char signs_raw[] = { '+','-','*','/','^','(',')' }; std::vector<char> signs(signs_raw, signs_raw + 7); bool stacked=false; for (std::string::iterator it = formula.begin(); it != formula.end(); it++) { if (*it >= '0' && *it <= '9' || *it == '.' || (*it=='-' && (it==formula.begin() || std::find(signs.begin(), signs.end(), *(it-1)) != signs.end()))) { num.push_back(*it); } else { if (num.length() > 0) { result.push_back(makeOperand(num)); num.erase(); } if (std::find(signs.begin(), signs.end(), *it) != signs.end()) { stacked = false; while (!stacked) { switch (priorities[!stack.empty() ? stack.top() : 0][*it]) { case 4: throw "Error in parsing formula"; break; case 1: stack.push(*it); stacked = true; break; case 2: result.push_back(stack.top()); stack.pop(); break; case 3: stack.pop(); stacked = true; break; default: throw "Error in parsing formula"; } } } else { result.push_back(*it); } } } if (num.length() > 0) { result.push_back(makeOperand(num)); num.erase(); } while (!stack.empty()) { result.push_back(stack.top()); stack.pop(); } return result; }
int main() { char char_response = 0; unsigned int first_operand = 0; unsigned int second_operand = 0; int end_of_operand_flag = 0; int operand_success = 0; int operation_success = 0; char operation = 0; printf("Let's test some simple expressions. Type \'N\' at any time to exit.\nPlease input an expression: "); while ((char_response = getchar()) != EOF) { putchar(char_response); if (char_response == 'N') { printf("\nThanks for playing. Goodbye.\n"); break; } if (isNumChecker(char_response)) { if (operand_success == 0) { first_operand = makeOperand(char_response, first_operand); // printf("\nfirst_operand = %d\n", first_operand); } if (operand_success == 1) { second_operand = makeOperand(char_response, second_operand); // printf("\nsecond_operand = %d\n", second_operand); } end_of_operand_flag = 1; } if (!isNumChecker(char_response) && end_of_operand_flag == 1) { operand_success++; end_of_operand_flag = 0; } if (isOperator(char_response)) { if (operation_success == 0 && operand_success == 1) operation = char_response; // printf ("\noperator = %c\n", operation); operation_success++; } if (char_response == '\n') { // printf("Successful operands = %d\nSuccessful operations = %d\n", operand_success, operation_success); if (operation == 0 || operation_success > 1) printf("Invalid expression.\n"); if (operand_success == 2 && operation_success == 1) { if (operation == '+') add(first_operand, second_operand); if (operation == '-') subtract(first_operand, second_operand); if (operation == '*') multiply(first_operand, second_operand); if (operation == '/') divide(first_operand, second_operand); if (operation == '%') modulo(first_operand, second_operand); } printf("Please input a valid expression: "); /* Reset all variables */ first_operand = 0; second_operand = 0; end_of_operand_flag = 0; operand_success = 0; operation_success = 0; operation = 0; } } return 0; }