Skip to content

Instantly share code, notes, and snippets.

@b166er-droid
Forked from cameronp98/postfix_calc.c
Created April 28, 2020 23:14
Show Gist options
  • Save b166er-droid/57ba55abc3192e813b2e45cc2affa6c2 to your computer and use it in GitHub Desktop.
Save b166er-droid/57ba55abc3192e813b2e45cc2affa6c2 to your computer and use it in GitHub Desktop.
Simple postfix expression parser in C. Uses Reverse Polish Notation (RPN), i.e. 2 2 + 3 * => 12.0
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef float st_type;
typedef struct {
st_type value;
struct node_t *next;
} node_t;
typedef struct {
node_t *head;
size_t size;
} *stack_t;
void error(char *msg) {
printf("Error: '%s'", msg);
exit(EXIT_FAILURE);
}
/* ------------------------------------------------------------------------- */
node_t *get_new_node(st_type value) {
node_t *node = malloc(sizeof(node_t));
node->value = value;
node->next = NULL;
return node;
}
stack_t get_new_stack() {
stack_t stack = malloc(sizeof(stack_t));
if (stack == NULL)
error("Failed to allocate memory.");
stack->head = NULL;
stack->size = 0;
return stack;
}
/* ------------------------------------------------------------------------- */
inline int isempty(stack_t st) {
return (st->size == 0);
}
void push(stack_t st, st_type value) {
node_t *new_node = get_new_node(value);
if (isempty(st))
st->head = new_node;
else {
node_t *head = st->head;
st->head = new_node;
new_node->next = head;
}
st->size++;
}
st_type pop(stack_t st) {
if (isempty(st))
error("Stack underflow");
node_t *head = st->head;
st_type value = head->value;
st->head = head->next;
free(head);
st->size--;
return value;
}
/* ------------------------------------------------------------------------- */
st_type operation(char c, st_type a, st_type b) {
switch(c) {
case '-':
return a + b;
case '*':
return a * b;
case '/':
return a / b;
default:
return a + b;
}
}
st_type parse_postfix_expr(stack_t stack) {
st_type a, b;
char c;
while ((c = getchar()) != '\n') {
if (isdigit(c))
push(stack, (st_type)(c - '0'));
else if (c=='+'||c=='-'||c=='*'||c=='/') {
if (stack->size < 2)
error("Expected 2 operands");
b = pop(stack), a = pop(stack);
push(stack, operation(c, a, b));
}
}
}
/* ------------------------------------------------------------------------- */
main() {
/* create a linked list for use as a stack */
stack_t stack = get_new_stack();
/* capture console input to evaluate */
printf("Enter an RPN expression: ");
parse_postfix_expr(stack);
/* display the results */
while (!isempty(stack))
printf("%.3f ", pop(stack));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment