SymbolListPtr CodeBlock::convert_postfix(SymbolListPtr p) {
	// data structs
	unique_ptr<stack<SymbolPtr>> op_stack = unique_ptr<stack<SymbolPtr>>(new stack<SymbolPtr>);
	SymbolListPtr unpostfix_symbols = SymbolListPtr(new SymbolList());
	
	// shunting yard (modified for unary operators!)
	for (auto i = p->begin(); i !=
		 p->end(); i++) {
		if (is_operand(*i)) {
			unpostfix_symbols->push_back(*i);
			if (!op_stack->empty()) {
				if (is_unary(op_stack->top())) {
					unpostfix_symbols->push_back(op_stack->top());
					op_stack->pop();
				}
			}
		} else if (is_operator(*i)) {
			if (is_unary((*i))) {
				op_stack->push(*i);
			} else {
				while (!op_stack->empty()
					   && !is_lparen(op_stack->top())
					   && compare_ops(*i, op_stack->top()) <= 0) {
					unpostfix_symbols->push_back(op_stack->top());
					op_stack->pop();
				}
				op_stack->push(*i);
			}
		} else if (is_lparen(*i)) {
			op_stack->push(*i);
		} else if (is_rparen(*i)) {
			while (!op_stack->empty()) {
				if (is_lparen(op_stack->top())) {
					op_stack->pop();
					if (!op_stack->empty()) {
						if (is_unary(op_stack->top())) {
							unpostfix_symbols->push_back(op_stack->top());
							op_stack->pop();
						}
					}
					break;
				}
				unpostfix_symbols->push_back(op_stack->top());
				op_stack->pop();
			}
		}
	}
	while(!op_stack->empty()) {
		unpostfix_symbols->push_back(op_stack->top());
		op_stack->pop();
	}
	
	// set the temp symbols as the postfix stuff
	return unpostfix_symbols;
}
Ejemplo n.º 2
0
void infix2rpn(char *expr, RPNEntry ***rpne, int *nrpne) {
    Array *rpn = array_new(32, 16);
    Stack *stack_ops = stack_new(16);
    //static char token[64];
    char *token;
    int tokenlen;
    int i;

    int uminus = 1;
    int inoperand = 0;
    //printf("%s:-> ", expr);

    char lookahead;

    for(token = gettoken(expr, &tokenlen, &lookahead);token != NULL; token = gettoken(NULL, &tokenlen, &lookahead)) {
        if (uminus) {
            if (*token == T_MINUS) {
                *token = T_UMINUS;
            }
            uminus = 0;
        }

        if (is_function(token, tokenlen)) {
            stack_push(stack_ops, token);
        } else if (is_operand(token)) {
            array_add(rpn, token);
        } else if (is_arg_separator(token)) {
            while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) {
                array_add(rpn, stack_pop(stack_ops));
            }
        } else if (is_operator(token)) {
            uminus = 1;
            if (stack_empty(stack_ops)) {
                stack_push(stack_ops, token);
            } else {
                if (compare_ops(token, stack_peek(stack_ops))) {
                    array_add(rpn, stack_pop(stack_ops));
                }
                stack_push(stack_ops, token);
            }
        } else if (is_lparen(token)) {
            uminus = 1;
            stack_push(stack_ops, token);
        } else if (is_rparen(token)) {
            while(!stack_empty(stack_ops) && !is_lparen(stack_peek(stack_ops))) {
                array_add(rpn, stack_pop(stack_ops));
            }
            stack_pop(stack_ops);
        } else {
            // errorski
        }
    }
    while (!stack_empty(stack_ops)) {
        array_add(rpn, stack_pop(stack_ops));
    }

    stack_free(&stack_ops);
    *rpne = (RPNEntry **)malloc(rpn->count * sizeof(RPNEntry*));
    for (i = 0; i < rpn->count; i++) {
        token = array_get(rpn, i);
        (*rpne)[i] = new_rpnentry(token, strlen(token));
    }
    *nrpne = rpn->count;
    array_free(&rpn);
}