[ 소 스 ]#include "stdio.h"#include "stdlib.h"#define MAX_STACK_SIZE 100 // stack의 최대 크기#define MAX_EXPR_SIZE 100 // 입력받는 수열의 최대 길이typedef enum {lparen, rparen, plus, minus, times, divide, eos, operand} precedence; // token 나열int stack[MAX_STACK_SIZE]; // 전역 배열 ( 오직 top를 통해서만 접근 )static int isp[]={0,19,12,12,13,13,0}; // stack 안에서의 우선순위static int icp[]={20,19,12,12,13,13,0}; // 입력받는 수열에서의 우선순위 ( stack 에 저장되기 전 )char expr[MAX_EXPR_SIZE]; // 입력 받는 문자열 ( 수열, infix )char post[MAX_EXPR_SIZE];int top=-1; // 초기 top 은 01값을 갖고 공백 스택을 나타낸다int i=0;void push(int *top, precedence item);precedence pop(int *top);int eval();precedence get_token(char *symbol, int *n);void postfix();void print_token(precedence print);void push(int *top, precedence item){if(*top>=MAX_STACK_SIZE-1) {printf("stack is full.. n"); // stack이 꽉 찼을 경우 경고 출력exit(1);}stack[++*top]=item; // (++*top; stack[*top];) stack에 item을 채움}precedence pop (int *top){if(*top==-1) {printf("stack is empty.. n"); // stack에 item이 없을 경우 (stack이 비어있을 경우) 오류 key 반환exit(1);}else return (precedence)stack[(*top)--]; // (stack[*top]; (*top)--;) stack에서 최상위에 있는 item을 반환}void postfix(void){char symbol;precedence token;int n=0;top = 0;stack[0]=eos;for(token=get_token(&symbol, &n); token != eos; token=get_token(&symbol,&n)){if(token == operand){post[i++]=symbol;}else if (token == rparen){while(stack[top] != lparen) // 왼쪽 괄호가 나올때 까지 토큰들을 제거해서 출력print_token(pop(&top));pop(&top); // 왼쪽 괄호 버림}else{while(isp[stack[top]] >= icp[token]) // symbol의 isp가 token의 icp보다 크거나 같으면 symbol 을 제거하고 출력print_token(pop(&top));push(&top,token);}}while((token = pop(&top)) != eos )print_token(token);}int eval(){precedence token;char symbol;int op1, op2; // postfix 에서 연산 기호를 만났을 경우 pop하게 될 두개의 operand 가 저장될 변수int n=0; // 수식 문자열을 위한 카운터int top=-1;token = get_token(&symbol, &n);while (token!=eos) { // token 값이 0이 아닌 동안if (token==operand) // 만약 token이 operand 라면push(&top, (precedence)( symbol-'0' )); // stack 에 삽입 ( 삽입 시 symbol의 아스키 값에서 '0'의 아스키값인 48을 빼준다 )else { // token 이 연산 기호 라면, 두 피연산자를 pop하여 연산을 수행한 후, 그 결과를 stack에 삽입op2=pop(&top); // stack에서 삭제 (pop)op1=pop(&top);switch (token) { // token 값이case plus : push(&top, (precedence) (op1+op2)); // plus 이면 pop한 두 operand를 더한다break;case minus : push(&top,eos); // -를 만나면 우선 eos 를 넣어주고if(op2==eos) // 두번째 pop 값이 eos 이면printf("%d",-op1); // -op2 출력else push(&top, (precedence) (op1-op2)); // 아니면 pop 한 두 operand 를 뺀다 ( 나중에 pop한 op1 에서 먼저 pop한 op2를 빼주어야 한다 )break;case times : push(&top, (precedence) (op1*op2)); // times 이면 pop 한 두 operand 를 곱한다break;case divide : push(&top, (precedence) (op1/op2)); // divide 이면 pop 한 두 operand 를 서로 나눈다}}token=get_token(&symbol, &n); // 다음 token 검사}return pop(&top); // 결과 반환}precedence get_token(char *symbol, int *n){*symbol=expr[(*n)++]; // symbol 은 문자표현 ( token 은 symbol 이 열거된 값으로 표현, 명칭으로 반환 )switch (*symbol) {case '(' : return lparen; // 왼쪽 괄호case ')' : return rparen; // 오른쪽 괄호case '+' : return plus; // 합case '-' : return minus; // 차case '*' : return times; // 곱case '/' : return divide; // 나누기case '