Обратная польская запись в Си

Мне нужна помощь в реализации моего кода. Вот код на C. Моё задание - создать программу для обратной польской записи. Вот что у меня так далеко. Одна ошибка, которую я имею сразу, - "контроль может достигнуть конца не пустой функции". После ошибки я не уверен, куда идти дальше. Любая помощь будет очень полезна.

#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;
    }
}

2 ответа

Ваш if, else имеет return следующий else, но никто не следует if то, что компилятор может гарантировать, будет выполнено. Поэтому, если ваша функция выполняет if ветвь, функция не имеет return, Легко исправить - добавить один как default дело. Таким образом, у вас есть гарантированное исполнение return по тому пути, который может распознать компилятор. Что-то по линии return -1; /* operator not recognized */

Если у вас уже есть входные данные в RPN, то все, что вам нужно, это стек операндов и конструкция большого переключателя (или if-elseif), где вы оцениваете операторы.

Я вижу, что вы конвертируете нотацию постфикса (RPN) в инфикс (в частности, в дерево выражений), однако оценка RPN намного проще, чем обход дерева.

Я не буду изобретать велосипед, посмотрите реализацию здесь: http://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm

Переменная s содержит вход. rpn Функция начинается с токенизатора (в вашем коде его нет). Если ввод неправильный (недопустимое выражение RPN), die() Функция будет вызвана с кратким объяснением.

Другие вопросы по тегам