void deal_tmp(sqstack *operator, sqstack *operand, char ch) { int op1, op2; while ( convert_operator(ch) <= convert_operator((char)top_stack(operator)) ) { op2 = pop_stack(operand); op1 = pop_stack(operand); switch ( (char)pop_stack(operator) ) { case '+' : printf("push data: %d + %d\n", op1, op2); push_stack(operand, op1 + op2); break; case '-' : printf("push data: %d - %d\n", op1, op2); push_stack(operand, op1 - op2); break; case '*' : printf("push data: %d * %d\n", op1, op2); push_stack(operand, op1 * op2); break; case '/' : printf("push data: %d / %d\n", op1, op2); push_stack(operand, op1 / op2); break; } if ( empty_stack(operator) || ((char)pop_stack(operator) == '(') ) { break; } } push_stack(operator, (int)ch); }
std::vector<Element> parse_expression(std::stringstream &stream) { std::vector<Element> out_buffer; std::stack<Element> st; while(stream.good()) { char c = stream.peek(); assert(!stream.fail()); if(c == ')' || c == ']') { stream.get(); while (1) { assert(!st.empty()); Element element = st.top(); st.pop(); if(element.type == Element::Type::BRACKET) { break; } else { out_buffer.push_back(convert_operator(element)); } } if(!st.empty() && st.top().type == Element::Type::FUNCTION) { out_buffer.push_back(st.top()); st.pop(); } } else if(c == '(' || c == '[') { stream.get(); Element element { Element::Type::BRACKET }; #ifdef DEBUG_MATH_PARSER element.identifier = "("; #endif st.push(element); } else if(isalpha(c)) { Element element; std::string id = parse_identifier(stream); #ifdef DEBUG_MATH_PARSER element.identifier = id; #endif if(function_info.find(id) != function_info.end()) { element.type = Element::Type::FUNCTION; element.function = function_info[id]; st.push(element); } else { assert(id.length() == 1); element.type = Element::Type::VARIABLE; element.variable = id[0]; out_buffer.push_back(element); } } else if(isnumber(c)) { Element element { Element::Type::SCALAR }; stream >> element.scalar; out_buffer.push_back(element); } else if(operator_info.find(c) != operator_info.end()) { Element current { Element::Type::OPERATOR }; #ifdef DEBUG_MATH_PARSER current.identifier = std::string(1, c); #endif current.op = operator_info[stream.get()]; while(!st.empty() && st.top().type == Element::Type::OPERATOR && st.top().op.precedence + st.top().op.rtl_associativity <= current.op.precedence) { out_buffer.push_back(convert_operator(st.top())); st.pop(); } st.push(current); } else if(isspace(c)) { stream.get(); } }
int main() { char expression[30],*p; sqstack *operator, *operand; int sum, flag = 0; int op1, op2; operator = (sqstack *)malloc(sizeof(sqstack)); setnull(operator); operand = (sqstack *)malloc(sizeof(sqstack)); setnull(operand); gets(expression); p = expression; while ( *p ) { if ( (*p >= '0') && (*p <= '9') ) { p++; continue; } switch ( *p ) { case '+' : case '-' : case '*' : case '/' : case ' ' : case '(' : case ')' : break; default : printf("Wrong Character %c in expression!\n", *p); return -1; } p++; } p = expression; while ( *p ) { if ( (*p >= '0') && (*p <= '9') ) { if ( flag ) { sum = 10*sum + (*p - '0'); } else { sum = *p - '0'; flag = 1; } p++; continue; } if ( flag ) { printf("push data %d\n", sum); push_stack(operand, sum); flag = 0; } if ( *p == ' ' ) { p++; continue; } if ( empty_stack( operator ) ) { printf("push %c\n", *p); push_stack(operator, (int)*p); p++; continue; } if ( *p == ')' ) { printf("*** Wow, we meet ) ***\n"); deal_bracket(operator, operand); p++; continue; } if ( (convert_operator(*p) > convert_operator((char)top_stack(operator))) || ((char)top_stack(operator) == '(') ) { printf("push %c\n", *p); push_stack(operator, (int)*p); } else { deal_tmp(operator, operand, *p); } p++; } if ( flag ) push_stack(operand, sum); while ( !empty_stack(operator) ) { op2 = pop_stack(operand); op1 = pop_stack(operand); switch ( (char)pop_stack(operator) ) { case '+' : printf("push data: %d + %d\n", op1, op2); push_stack(operand, op1 + op2); break; case '-' : printf("push data: %d - %d\n", op1, op2); push_stack(operand, op1 - op2); case '*' : printf("push data: %d * %d\n", op1, op2); push_stack(operand, op1 * op2); break; case '/' : printf("push data: %d / %d\n", op1, op2); push_stack(operand, op1 / op2); break; } } printf("%d\n", pop_stack(operand)); return 0; }