Вот этот код:
#include <ctype.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { STACK_INITIAL_CAPACITY = 8, POLIZ_INITIAL_COMPILER_CAPACITY = 16 };

enum {
    PE_OK,
    PE_STACK_UNDERFLOW,
    PE_INVALID_INDEX,
    PE_DIVISION_BY_ZERO,
    PE_INT_OVERFLOW,
    PE_READ_FAILED,
    PE_OUT_OF_MEMORY,
};

struct PolizState;

typedef int (*PolizFuncT)(struct PolizState *state, int iextra);

struct PolizItem {
    PolizFuncT handler;
    int iextra;
};

struct PolizState {
    int32_t *stack;
    size_t size;
    size_t capacity;
    int err;
};

struct PolizItem *poliz_compile(const char *str);
struct PolizState *poliz_new_state(void);
void poliz_free_state(struct PolizState *state);
int poliz_last_error(struct PolizState *state);

static int32_t floor_divide(int32_t a, int32_t b) {
    if (b == 0) {
        return 0;
    }

    int32_t q = a / b;
    int32_t r = a % b;

    if (a < 0) {
        if (b > 0 && r != 0) {
            q--;
        } else if (b < 0 && r != 0) {
            q++;
        }
    }

    return q;
}

static int push_stack(struct PolizState *state, int32_t value) {
    if (state->err) {
        return -state->err;
    }

    if (state->size == state->capacity) {
        size_t new_capacity =
            state->capacity == 0 ? STACK_INITIAL_CAPACITY : state->capacity * 2;
        int32_t *new_stack =
            realloc(state->stack, new_capacity * sizeof(int32_t));
        if (!new_stack) {
            state->err = PE_OUT_OF_MEMORY;
            return -state->err;
        }
        state->stack = new_stack;
        state->capacity = new_capacity;
    }
    state->stack[state->size++] = value;
    return PE_OK;
}

static int pop_stack(struct PolizState *state, int32_t *value) {
    if (state->size == 0) {
        state->err = PE_STACK_UNDERFLOW;
        return PE_STACK_UNDERFLOW;
    }
    *value = state->stack[--state->size];
    return PE_OK;
}

static int handler_push_number(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    return push_stack(state, (int32_t)iextra);
}

static int handler_add(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t a, b;
    if (pop_stack(state, &b) != PE_OK) {
        return -state->err;
    }
    if (pop_stack(state, &a) != PE_OK) {
        return -state->err;
    }

    int64_t result = (int64_t)a + (int64_t)b;
    if (result > INT32_MAX || result < INT32_MIN) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    return push_stack(state, (int32_t)result);
}

static int handler_sub(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t a, b;
    if (pop_stack(state, &b) != PE_OK) {
        return -state->err;
    }
    if (pop_stack(state, &a) != PE_OK) {
        return -state->err;
    }

    int64_t result = (int64_t)a - (int64_t)b;
    if (result > INT32_MAX || result < INT32_MIN) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    return push_stack(state, (int32_t)result);
}

static int handler_mul(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t a, b;
    if (pop_stack(state, &b) != PE_OK) {
        return -state->err;
    }
    if (pop_stack(state, &a) != PE_OK) {
        return -state->err;
    }

    int64_t result = (int64_t)a * (int64_t)b;
    if (result > INT32_MAX || result < INT32_MIN) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    return push_stack(state, (int32_t)result);
}

static int handler_div(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t divisor, dividend;
    if (pop_stack(state, &divisor) != PE_OK) {
        return -state->err;
    }
    if (pop_stack(state, &dividend) != PE_OK) {
        return -state->err;
    }

    if (divisor == 0) {
        state->err = PE_DIVISION_BY_ZERO;
        return -state->err;
    }

    if (dividend == INT32_MIN && divisor == -1) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    int32_t result = floor_divide(dividend, divisor);
    return push_stack(state, result);
}

static int handler_mod(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t divisor, dividend;
    if (pop_stack(state, &divisor) != PE_OK) {
        return -state->err;
    }
    if (pop_stack(state, &dividend) != PE_OK) {
        return -state->err;
    }

    if (divisor == 0) {
        state->err = PE_DIVISION_BY_ZERO;
        return -state->err;
    }

    if (dividend == INT32_MIN && divisor == -1) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    int32_t q = floor_divide(dividend, divisor);
    int32_t r = dividend - divisor * q;

    if (r > INT32_MAX || r < INT32_MIN) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    return push_stack(state, r);
}

static int handler_negate(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t a;
    if (pop_stack(state, &a) != PE_OK) {
        return -state->err;
    }

    int64_t result = -(int64_t)a;
    if (result > INT32_MAX || result < INT32_MIN) {
        state->err = PE_INT_OVERFLOW;
        return -state->err;
    }

    return push_stack(state, (int32_t)result);
}

static int handler_read(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t value;
    int res = scanf("%d", &value);
    if (res != 1) {
        state->err = PE_READ_FAILED;
        return -state->err;
    }

    return push_stack(state, value);
}

static int handler_write(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    int32_t value;
    if (pop_stack(state, &value) != PE_OK) {
        return -state->err;
    }

    printf("%d", value);
    return PE_OK;
}

static int handler_newline(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    printf("\n");
    return PE_OK;
}

static int handler_remove_top(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    if (state->size == 0) {
        state->err = PE_STACK_UNDERFLOW;
        return -state->err;
    }

    state->size--;
    return PE_OK;
}

static int handler_copy(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    size_t num = (size_t)iextra;
    if (num >= state->size) {
        state->err = PE_INVALID_INDEX;
        return -state->err;
    }

    int32_t value = state->stack[state->size - 1 - num];
    return push_stack(state, value);
}

static int handler_swap(struct PolizState *state, int iextra) {
    if (state->err) {
        return -state->err;
    }

    size_t num = (size_t)iextra;
    if (num >= state->size) {
        state->err = PE_INVALID_INDEX;
        return -state->err;
    }

    if (num == 0) {
        return PE_OK;
    }

    size_t index1 = state->size - 1 - num;
    size_t index2 = state->size - 1;
    int32_t temp = state->stack[index1];
    state->stack[index1] = state->stack[index2];
    state->stack[index2] = temp;

    return PE_OK;
}

struct PolizState *poliz_new_state(void) {
    struct PolizState *state = malloc(sizeof(struct PolizState));
    if (!state) {
        return NULL;
    }

    state->stack = NULL;
    state->size = 0;
    state->capacity = 0;
    state->err = PE_OK;
    return state;
}

void poliz_free_state(struct PolizState *state) {
    if (state) {
        free(state->stack);
        free(state);
    }
}

int poliz_last_error(struct PolizState *state) {
    if (!state) {
        return PE_OK;
    }
    return state->err;
}

static struct PolizItem compile_token(const char *token, int *extra) {
    struct PolizItem item;
    item.handler = NULL;
    item.iextra = 0;

    char *endptr;
    long num = strtol(token, &endptr, 10);
    if (*endptr == '\0') {
        item.handler = handler_push_number;
        item.iextra = (int)num;
        return item;
    }

    if (strcmp(token, "+") == 0) {
        item.handler = handler_add;
    } else if (strcmp(token, "-") == 0) {
        item.handler = handler_sub;
    } else if (strcmp(token, "*") == 0) {
        item.handler = handler_mul;
    } else if (strcmp(token, "/") == 0) {
        item.handler = handler_div;
    } else if (strcmp(token, "%") == 0) {
        item.handler = handler_mod;
    } else if (strcmp(token, "#") == 0) {
        item.handler = handler_negate;
    } else if (strcmp(token, "r") == 0) {
        item.handler = handler_read;
    } else if (strcmp(token, "w") == 0) {
        item.handler = handler_write;
    } else if (strcmp(token, "n") == 0) {
        item.handler = handler_newline;
    } else if (strcmp(token, ";") == 0) {
        item.handler = handler_remove_top;
    } else if (token[0] == 'd') {
        if (token[1] == '\0') {
            *extra = 0;
        } else {
            long dn = strtol(token + 1, &endptr, 10);
            if (*endptr != '\0' || dn < 0) {
                dn = 0;
            }
            *extra = (int)dn;
        }
        item.handler = handler_copy;
    } else if (token[0] == 's') {
        if (token[1] == '\0') {
            *extra = 1;
        } else {
            long sn = strtol(token + 1, &endptr, 10);
            if (*endptr != '\0' || sn < 0) {
                sn = 1;
            }
            *extra = (int)sn;
        }
        item.handler = handler_swap;
    } else {
        item.handler = NULL;
    }

    return item;
}

static int is_variable_command(PolizFuncT handler) {
    return (handler == handler_copy) || (handler == handler_swap);
}

struct PolizItem *poliz_compile(const char *str) {
    if (!str) {
        return NULL;
    }

    char *input = strdup(str);
    if (!input) {
        return NULL;
    }

    size_t capacity = POLIZ_INITIAL_COMPILER_CAPACITY;
    size_t count = 0;
    struct PolizItem *items = malloc(capacity * sizeof(struct PolizItem));
    if (!items) {
        free(input);
        return NULL;
    }

    char *token = strtok(input, " \t\r\n");
    while (token) {
        if (count == capacity - 1) {
            size_t new_capacity = capacity * 2;
            struct PolizItem *new_items =
                realloc(items, new_capacity * sizeof(struct PolizItem));
            if (!new_items) {
                free(items);
                free(input);
                return NULL;
            }
            items = new_items;
            capacity = new_capacity;
        }

        int extra = 0;
        struct PolizItem item = compile_token(token, &extra);
        items[count].handler = item.handler;

        if (is_variable_command(item.handler)) {
            items[count].iextra = extra;
        } else {
            items[count].iextra = item.iextra;
        }

        count++;

        token = strtok(NULL, " \t\r\n");
    }

    if (count == capacity - 1) {
        size_t new_capacity = capacity * 2;
        struct PolizItem *new_items =
            realloc(items, new_capacity * sizeof(struct PolizItem));
        if (!new_items) {
            free(items);
            free(input);
            return NULL;
        }
        items = new_items;
        capacity = new_capacity;
    }
    items[count].handler = NULL;
    items[count].iextra = 0;
    count++;

    struct PolizItem *final_items =
        realloc(items, count * sizeof(struct PolizItem));
    if (!final_items) {
        final_items = items;
    }

    free(input);
    return final_items;
}

Должен решать задачу:
Submit a solution for sm06-5-c/function-pointers/func-poliz-1

Full score:	100
Time limit:	1 s
Real time limit:	5 s
Memory limit:	64M
Open date:	2024-10-19 00:00:00
Deadline:	2024-12-17 23:59:59
Date penalty formula:	2024-11-19 23:59:59 0
Problem sm06-5: c/function-pointers/func-poliz-1

Напишите компилятор выражений в польской записи в "шитый" код, то есть в специальное внутреннее представление, удобное для исполнения, как описано далее.

Польская запись передается на вход в виде строки, в которой элементы польской записи отделяются друг от друга пробельными символами. Обозначим стек вычислений польской записи через S. На стеке вычислений хранятся 32-битные знаковые целые числа. Элемент S[0] — это верхушка стека, S[1] — это следующий после верхушки элемент на стеке. В польской записи поддерживаются следующие элементы:

NUM	NUM — это 32-битное целое число, перед которым допускается необязательные знаки "плюс" или "минус". значение числа помещается в стек.
+	Вычислить S[1] + S[0]. Оба значения удаляются из стека, результат операции помещается в стек.
-	Вычислить S[1] - S[0]. Оба значения удаляются из стека, результат операции помещается в стек.
*	Вычислить S[1] * S[0]. Оба значения удаляются из стека, результат операции помещается в стек.
/	Вычислить S[1] / S[0] (по математическим правилам нацело). Оба значения удаляются из стека, результат операции помещается в стек.
%	Вычислить S[1] % S[0] (по математическим правилам). Оба значения удаляются из стека, результат операции помещается в стек.
#	Вычислить -S[0]. Аргумент операции удаляется из стека, результат операции помещается в стек.
r	Считать со стандартного потока ввода 32-битное знаковое целое значение в десятичной записи, результат операции помещается в стек.
w	Вывести на стандартный поток вывода S[0]. Аргумент удаляется из стека.
n	Вывести на стандартный поток вывода символ \n.
;	Удалить элемент из верхушки стека.
dNUM	Поместить копию элемента S[NUM] на верхушку стека. Если NUM не указан, подразумевается значение индекса 0. Таким образом команда d копирует элемент на верхушке стека, как и команда d0. Команда d1 заносит на верхушку стека значение S[1], где индекс берется до выполнения операции занесения в стек. Индекс NUM всегда неотрицательный. Команда должна выполняться за амортизированное O(1).
sNUM	Обменять местами S[NUM] и S[0]. Если NUM не указан, подразумевается значение индекса 1. Таким образом команда s меняет местами S[1] и S[0], как и команда s1. Команда s0 не делает ничего (даже если стек пуст). Индекс NUM всегда неотрицательный. Команда должна выполняться за O(1).
Предопределены следующие типы данных:

// opaque structure for poliz calculation state
struct PolizState;

// poliz operation handler
typedef int (*poliz_func_t)(struct PolizState *state, int iextra);

struct PolizItem
{
    poliz_func_t handler;
    int iextra;
};

// runtime errors
enum
{
    PE_OK,  // no error
    PE_STACK_UNDERFLOW, // not enough elements on stack
    PE_INVALID_INDEX, // s or d operations refer to invalid index
    PE_DIVISION_BY_ZERO,
    PE_INT_OVERFLOW,
    PE_READ_FAILED, // read from stdin failed to convert integer for any reason
    PE_OUT_OF_MEMORY,
};

struct PolizItem *poliz_compile(const char *str);

struct PolizState *poliz_new_state(void);
void poliz_free_state(struct PolizState *state);
int poliz_last_error(struct PolizState *state);
Функция компиляции должна иметь следующий прототип:

struct PolizItem *poliz_compile(const char *str);
Функция компиляции возвращает массив элементов польской записи. Последний элемент массива содержит указатель handler равный NULL. Массив должен выделяться в динамической памяти.

Если дана строка str, то вычисление значения выполняется следующим образом:

    struct PolizItem *items = poliz_compile(str);
    struct PolizState *state = poliz_new_state();
    for (int i = 0; items[i].handler != NULL; ++i) {
        int err = items[i].handler(state, items[i].iextra);
        if (err < 0) {
            fprintf(stderr, "error: %d\n", -err);
            break;
        } else if (err > 0) {
            abort();  // хендлеры должны возвращать код ошибки со знаком '-'
        }
    }
    poliz_free_state(state);
    free(items);
Ваша задача: написать функции poliz_compile, poliz_new_state, poliz_free_state, poliz_last_error и функции-обработчики команд польской записи. Не сдавайте код функции main. Вам будет доступен заголовочный файл poliz.h, который вы можете включать директивой #include.

Функция poliz_last_error возвращает **неотрицательный** код последней ошибки при выполнении польской записи. Если в процессе выполнения произошла ошибка, но выполнение не было прервано (например, если из примера выше убрать break), то все последующие после ошибки команды не должны ничего делать, то есть в начале каждого обработчика команды должна находиться проверка:

    // проверяем была ли ошибка ранее
    if (state->err) return -state->err;
Используйте ключевое слово static там, где это полезно.

Можете предполагать, что польская запись корректна, за исключением возможных ошибок времени выполнения. То есть, польская запись может содержать ошибку деления на константу 0, но выявлять ее при компиляции, как и выявлять антипереполнение и другие ошибки времени выполнения не нужно.

Например, если дана строка r r + w n, при чтении со стандартного потока ввода

  100 128
на стандартный поток вывода должно быть напечатано

228
Обратите внимание, что длина вывода должна быть в точности 4 символа (3 цифры и \n).

 

Submit a solution

Language:	gcc - GNU C 11.3.0
Но у него возникают runtime error на 3 тестах
мне сказали, что это связано с операцией %, с переполнением, реши проблему