-1

I need help implementing my code. Here is the code in C. My assignment is to create a program for reverse polish notation. Here is what I have so far. One error i have right off is "control may reach end of non void function". After the error I'm not sure where to go from there. Any help would be of great use.

#include <stdlib.h>
#include <stdio.h>
#include <math.h> 
#include <string.h>

typedef struct node
{
    int datum;
    int isOperator;
    struct node* left;
    struct node* right;
}*Node;

Node BuildTree(char** argv, int* index);
int isOperator(char ch);
int isadd(int);
int evaluate(Node);
void infix(Node, int);

int main(int argc, char* argv[])
{
    int i = 9; //argc - 1;
    Node tree = NULL;

    char* debugList[] = {NULL,"2","9","+","5","-", "6", "D", "3", "X"};

    tree = BuildTree(debugList, & i);
    infix(tree, 43);

    printf("\n%d", evaluate(tree));
    return 0;
}

Node BuildTree(char** argv, int* index)
{
    Node node;
    if (*index < 1)
        return NULL;

    if(isOperator(argv[*index][0]))
    {
        //insert to the right
        node = (Node) malloc(sizeof(Node));
        node -> datum = (int) argv[*index][0];
        (*index)--;
        node -> right = BuildTree(argv, index);
        node -> left = BuildTree(argv, index);
        node -> isOperator = 1;
        return node;
    }
    else
    {
        node = (Node) malloc(sizeof(Node));
        node -> right = NULL;
        node -> left = NULL;
        node -> datum = (int) argv[*index][0];
        node -> isOperator = 0;
        (*index)--;
        return node;
    }
}
// Return true if ch is a operator, otherwise false
int isOperator(char ch)
{
    if (ch == '+' || ch == '-' || ch == 'D' || ch == 'X')
        return 1;

    else
        return 0;
}

void infix(Node node, int c){
    if(node == NULL)
        return;
    else if (isadd(node -> datum) && !isadd(c)){
        printf("(");
        infix(node -> left, node -> datum);
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);
        printf(")");
    }
    else {
        infix(node -> left, node -> datum);
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);
    }
}

int isadd(int c)
{
    if(c == 43 || c == 45)
        return 1;
    else
        return 0;
}

int evaluate(Node node)
{
    if(node -> isOperator)
    {
        switch(node -> datum)
        {
            case 43:
                return evaluate(node -> left) + evaluate(node -> right);
            case 45:
                return evaluate(node -> left) - evaluate(node -> right);
            case 68:
                return evaluate(node -> left) / evaluate(node -> right);
            case 88:
                return evaluate(node -> left) * evaluate(node -> right);
        }
    }else{
        return node -> datum - 48;
    }
}
nchen24
  • 502
  • 2
  • 9
justjoe
  • 11
  • 1
  • 2
  • 2
    In `evaluate`, if `node->isOperator` evaluates to true, but `node->datum` is something other than 43, 45, 68, or 88, then you will have reached the end of `evaluate` without returning anything. Consider adding a default case to your switch statement. – nchen24 Dec 08 '14 at 06:33
  • I have made changes you have suggested and now i'm receiving "bad access code" error – justjoe Dec 08 '14 at 09:46
  • What do you mean a bad access code error? EXC_BAD_ACCCESS? I personally would try to debug with valgrind: (from the command line) `valgrind ./a.out`. If you compile with `-g` (e.g.: `gcc -g -Wall -Wextra rpn.c`), you will get exact line numbers that are causing your program to fail, but there may be easier ways (such as run and debug, if you are using xcode), depending on what you're writing/compiling with. – nchen24 Dec 08 '14 at 10:13

2 Answers2

1

Your if, else has a return following else, but none following if that the compiler can guarantee will be executed. Therefore, if your function executes the if branch, the function has no return. Easy fix - add one as the default case. That way you have a guaranteed execution of a return down that path that the compiler can recognize. Something along the line of return -1; /* operator not recognized */

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

If you have an input already in RPN, then all you need is an operand stack, and a big switch (or if-elseif) construct where you evaluate the operators.

I see that you convert the postfix (RPN) notation to infix (specifically to an expression tree), hovewer evaluating the RPN is much-much easier than traversing the tree.

I won't reinvent the wheel, see an implemenation here: http://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm#C

The variable s contains the input. The rpn function starts with a tokenizer (you don't have that in your code). If the input is bad (not valid RPN expression), the die() function will be called with a brief explanation.

Koshinae
  • 2,240
  • 2
  • 30
  • 40