読者です 読者をやめる 読者になる 読者になる

シンプルな逆ポーランド式計算機

c

数字は一桁しか対応してません。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define STACK_MAX 1024

typedef int (*OP_TYPE)(int, int);
static OP_TYPE get_operator(char c);
static int is_operator(char c);

static int add(int a, int b);
static int sub(int a, int b);
static int mul(int a, int b);
static int divide(int a, int b);
static int mod(int a, int b);

static int is(int val, int expected);

static int reverse_porland_simple(const char *input);

int main (int argc, char *argv[])
{
    is(reverse_porland_simple("1 2 +"), 3);
    is(reverse_porland_simple("3 2 -"), 1);
    is(reverse_porland_simple("9 9 *"), 81);
    is(reverse_porland_simple("9 1 /"), 9);
    is(reverse_porland_simple("4 3 %"), 1);

    is(reverse_porland_simple("4 3 2 1 + + +"), 10);
    is(reverse_porland_simple("4 3 2 1 + - *"), 0);

    return 0;
}

static int reverse_porland_simple(const char *input)
{
    int stack[STACK_MAX];
    int sp, ret_value;
    int i;
    char c;

    sp = 0;

    for (i = 0; input[i] != '\0'; i++) {
        c = input[i];

        if (isspace(c)) {
            continue;
        }

        if (isdigit(c)) {
            stack[sp++] = c - '0';
        } else if(is_operator(c)) {
            int op1, op2, val;
            OP_TYPE operator;

            op2 = stack[--sp];
            if (sp < 0) {
                fprintf(stderr, "Invalid operation\n");
                exit(EXIT_FAILURE);
            }
            op1 = stack[--sp];
            if (sp < 0) {
                fprintf(stderr, "Invalid operation\n");
                exit(EXIT_FAILURE);
            }

            operator = get_operator(c);
            if (operator == NULL) {
                fprintf(stderr, "Error: no operation %c\n", c);
                exit(EXIT_FAILURE);
            }

            val = operator(op1, op2);
            stack[sp++] = val;
        } else {
            fprintf(stderr, "Error : invalid input character %c(code %d)\n", c, c);
            exit(EXIT_FAILURE);
        }
    }

    ret_value = stack[--sp];

    if (sp != 0) {
        fprintf(stderr, "Error : data is left in stack sp = %d\n", sp);
        exit(EXIT_FAILURE);
    }

    return stack[0];
}

static int is_operator(char c)
{
    switch (c) {
    case '+':
    case '-':
    case '*':
    case '/':
    case '%':
        return 1;
    default:
        return 0;
    }
}

static OP_TYPE get_operator(char c)
{
    switch (c) {
    case '+':
        return &add;
    case '-':
        return &sub;
    case '*':
        return &mul;
    case '/':
        return &divide;
    case '%':
        return &mod;
    default:
        return NULL;
    }
}

static int add(int a, int b)
{
    return a + b;
}

static int sub(int a, int b)
{
    return a - b;
}

static int mul(int a, int b)
{
    return a * b;
}

static int divide(int a, int b)
{
    if (b == 0) {
        fprintf(stderr, "Error: Zero divided\n");
    }

    return a / b;
}

static int mod(int a, int b)
{
    if (b == 0) {
        fprintf(stderr, "Error: Zero divided\n");
    }
    return a % b;
}

static int is(int val, int expected)
{
    static int test_num = 1;

    if (val == expected) {
        printf("%2d ok\n", test_num);
    } else {
        printf("%2d not ok\n", test_num);
        printf("get %d, expected %d\n", val, expected);
    }

    test_num++;
    return 0;
}

整数を返す関数で負の値を返す可能性がある場合エラーコードは
どうやるんだろう?errno的な考え方がいいのかな。


今回は面倒なのでエラー発生、即終了にしてみました。