Programming Language/C2010. 10. 14. 19:42

 Postfix.c

 stack을 익히기 위하여 미니 프로젝트로 계산기를 구현해 보았습니다.
중위 표기식의 입력을 후위 표기로 변환, 계산 합니다.
삼각함수 연산도 가능합니다.

fds.c

/*=====================================================================*/

/*                              ☆★ 미니 프로젝트 : calculator. ☆★                   */



/*                 목적 : 중위 표기식을 후위 표기식으로 변환해서 계산.              */

/*                 기능 :-삼각함수 연산 가능.                                                                                     
                                        ex)-10*-cos(--sin(--45--45)/2-sin(40))                                                          
                                           -10 -1 45 45 + sin 2 / 40 sin - cos * *      =10.0
                                           radian = (PI*first)/180;
/*                           -에러처리 가능.
                                        ex)-10*-(-9.1(--0.8--0.1))
                                           =error       
/*=====================================================================*/

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<math.h>

#define MAX_STACK_SIZE 100                      //스택 최대 크기.
#define MAX_EXPR_SIZE 100                       //수식의 최대 크기.
#define PI 3.14159                                      //파이 3.14159

typedef enum {lparen, rparen, plus, minus, times, divide, mod,  s,  c,  t, eos, operand} precedence;
                        //       (              )               +         -              *              /          %    s   c   t       0       default         
                        //       0              1               2         3              4              5          6    7       8       9   10    11            

int stack[MAX_STACK_SIZE];                      //전역 배열.
char expr[MAX_EXPR_SIZE];                       //입력 문자열.
char bexpr[MAX_EXPR_SIZE];                      //후위 표기법으로 저장되는 배열.
double result[MAX_STACK_SIZE];          //연산해주는 스택.
int cnt=0;

precedence stack[MAX_STACK_SIZE];       //연산자가 푸쉬&팝 되는 스택.

static int isp[] = {0, 19, 12, 12, 13, 13, 13, 14, 14, 14, 0};          //in-stack precredence.
                                 // 0   1       2       3       4       5       6       7       8       9  10
static int icp[] = {20, 19, 12, 12, 13, 13, 13, 14, 14, 14, 0};                 //incoming precedence.

/*********** 함수 ************/

void postfix(void);                                                             // 중위 표기법을 후위 표기법으로 바꿔주는 함수.

void push(int* top,precedence token);                   // 스택에 입력하는 함수.

int pop(int* top);                                                              // 스택에서 출력 함수.
        
precedence get_token(char* symbol , int* n);    // precedence type으로 바꿔주는 함수. 

void print_token(int opt);                                              // precedence를 기호로 바꾸어 출력.

double Opop(int* top);                                                  // 연산해줄 탑 출력하는 함수.      (main에서 계산시 사용.)

void Opush(int* top,double i);                                  // 탑에 연산해줄 값을 입력하는 함수.  (main에서 계산시 사용.)

double operation(int* top,char i);                              // 두수를 팝하여 연산해주는 계산기.           (main에서 계산시 사용.)


/*****************************************************************/
/*                      메인 함수.                                                                                   */
/*****************************************************************/
int main(void){
        char bag[MAX_STACK_SIZE];       // bexpr에서 더블형으로 바꿔 result[]에 옮겨주는 배열. 
        char* bp=bexpr;                         // bag에 넣을 입력 문자열의 포인터.
        int top = -1;                           // top 다음에 수가 저장.
        int n = 0;                                      // for문의 카운터. 인덱스.
        int i = 0;                                      // bag의 카운터.
        double sol;                                     // 팝된 값들의 연산후 저장될 변수. 푸쉬됨.
        printf("중위 표기법으로 입력하시오.\n중위표기법 =>\t");
        scanf("%s",expr);
        printf("후위표기법 => \t");
        postfix();
        
        for(; n<(int)strlen(bexpr); n++,*bp++)
        {
                if((bexpr[n]=='-' && isdigit(bexpr[n+1])!=0)||(isdigit(bexpr[n]) != 0))
                {
                        i=0;
                        while(bexpr[n] !=' '){                          // *bp 즉 bexpr[n]의 값이 띄어쓰기가 나오기 전까지 bag에 입력.
                                bag[i++]=*(bp++);
                                n++;
                        }
                        bag[i]='\0';
                        Opush(&top,atof(bag));                              //result스택의 top에 bag숫자열을 float형으로 변환하여 넣어줌.
                }
                else if(isdigit(bexpr[n])==0 && bexpr[n]!=' ')          // 연산자가 나오면!
                {         
                        sol = operation(&top,bexpr[n]);                                     // 두 수를 팝하여 연산하고 그 리턴형을 sol에 저장. 
                        Opush(&top, sol);                                                           // sol을 푸쉬!.
                }
        //      printf("\nbag= %s\n",bag);
        //      printf("result= %f\n",result[top]); 
        }
        
        printf("\n결과는     => \t%lf \n",Opop(&top));                              //마지막 탑. 즉, 결과를 출력. 
        return 0;
}



/****************************************************************/
/*      (계산기)두수를 팝하여 연산해주는 계산기 함수.                              */
/*      operation                                                                                                       */
/****************************************************************/

double operation(int* top,char i)
{
        double first,second,radian;
        
        if(i=='s')                                                                      //sin 
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return sin(radian);
        }
        else if(i=='c')                                                         //cos
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return cos(radian);
        }
        else if(i=='t')                                                         //tan
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return tan(radian);
        }
        else                                                                            //연산자
        {
                second=Opop(top);
                first=Opop(top);
                switch(i) {
                case '+' : return (first+second);
                case '-' : return (first-second);
                case '/' : return (first/second);
                case '*' : return (first*second);
                case '%' : return (first*second);
                default : return 0 ;
                }
        }
}


                        
/****************************************************************/
/*      (계산기) 탑에 연산해줄 값을 입력하는 함수.                                       */
/*      Opush                                                                                                           */
/****************************************************************/


void Opush(int* top,double i)
{
        result[++(*top)] = i;
}

/****************************************************************/
/*      (계산기) 연산해줄 탑을 출력해주는 Operation_pop함수.            */
/*       Opop                                                                                                           */
/****************************************************************/
double Opop(int* top)
{
        double temp = result[*top];
        (*top)--;
        return temp;
}

/****************************************************************/
/*      중위표기법을 후위표기법으로 바꿔주는  함수.                                        */
/*      - 수식 문자열, 스택, top은 전역적                                                  */
/*      postfix                                                                                                         */
/****************************************************************/

void postfix(void)
{
        char symbol;
        precedence token;               // 인덱스다. 결국은 정수.
        int n = 0;                              //스택 인덱스.
        int top = 0;                    //top의 초기값. (최초의 연산자와 비교해줄 eos의 인덱스)
        int mcnt = 1;                   // '-'의 갯수를 측정하는 카운트.
        int on = 0;                             // n의 상수값.
        char tri ;                              // 삼각 함수 한글자를 저장할 값.
        stack[0] = eos;                 //최초의 연산자와 비교해줄 최초의 top.(eos)
        

        for(token = get_token(&symbol, &n); token != eos; token = get_token(&symbol, &n))       //token이 eos를 가리킬때까지 get_token. 
        {       
        /* 1. token이 마이너스 일때. */
                if(token == minus)
                {       
                        on = n;                                         //n의 최초 값.
                        
                        for(; expr[n] == '-'; n++)                                                      //mcnt 카운트로 '-'갯수 측정. n의 값이 증가하는것에 유의.
                                mcnt++;
                                
                        
                                /* "-(" 가 나온 경우① "-1*("로 바꿔주는 문. "-(" 앞이 숫자가 아닐경우.  */
            if(expr[n] == '('&& expr[n-2] != '-' && isdigit(expr[n-2]) ==0){    
                                //expr[n-4] = '(';
                                expr[n-3] = '-';
                expr[n-2] = '1';
                expr[n-1] = '*';

                n-=3;
            }
                                /* "-(" 가 나온 경우②   "-(" 앞이 숫자일 경우. '+'연산자가 필요하게 됨.  */
                        else if(expr[n] == '('&& expr[n-2] != '-' && isdigit(expr[n-2]) !=0){   
                                expr[n-4] = '+';
                                expr[n-3] = '-';
                expr[n-2] = '1';
                expr[n-1] = '*';
                n-=4;
            }

                                /* 삼각함수가 나온 경우①. 위의 괄호의 경우처럼 둘로 나누어 연산.*/
                        else if((expr[n] == 's'||expr[n] == 'c'||expr[n] == 't')&&  expr[n-2] != '-' && isdigit(expr[n-2]) ==0){        
                                tri=expr[n];
                        //      expr[n-2] = '(';
                                expr[n-1] = '-';
                                expr[n]   = '1';
                                expr[n+1] = '*';
                                expr[n+2] = tri;
                                n--;
                        }
                                /* 삼각함수가 나온 경우②.*/
                        else if((expr[n] == 's'||expr[n] == 'c'||expr[n] == 't')&&  expr[n-2] != '-' && isdigit(expr[n-2]) !=0){                                
                                tri=expr[n];
                                expr[n-2] = '+';
                                expr[n-1] = '-';
                                expr[n]   = '1';
                                expr[n+1] = '*';
                                expr[n+2] = tri;
                                n-=2;
                        }

                                /* '-'의 앞이 괄호나 숫자가 아니고  뒤에 숫자가 나왔을때 음수기호로 만들어주는 경우.*/                   
            else if((isdigit(expr[on-2]) ==0) && (mcnt%2==1) && expr[on-2] !=')' ){                     
                printf("-");
                                bexpr[cnt++]='-';
                        }

            else if(mcnt%2==0){                                                                 // '-'가 짝수개.
                                if(isdigit(expr[on-2])==0)                                              // --앞에 숫자 아니면..없어져라..
                                        ;
                                
                                else{
                                        token = plus;
                                        while(isp[stack[top]] >= icp[token])
                                                print_token(pop(&top));
                                        push(&top, token);
                                }
            }
            else if(mcnt%2==1){                                                         // '-'가 홀수개. mcnt != 1
                token = minus;
                while(isp[stack[top]] >= icp[token])
                    print_token(pop(&top));
                push(&top, token);
            }
            mcnt=1;
                        //printf("%s\n",expr);
        }
        
                else if(token == s || token == c || token == t){
                        //tri=token;
                
                        while(isp[stack[top]] >= icp[token])
                                print_token(pop(&top));
                        push(&top, token);
                        while(expr[n]!='(')
                                n++;
                }
                
        /* 2. token이 숫자 일때. */  

        
        else if(token == operand)               
        {
            printf("%c",symbol);
                        bexpr[cnt++]=symbol;
            while(get_token (&symbol, &n) == operand){
                                
                                if(expr[n] == '('){
                                        printf("????? -_-\n\nERROR : 연산자를 미입력 하셨습니다.\n\n");
                                        return;
                                }
                printf("%c",symbol);
                                bexpr[cnt++]=symbol;
                        }
            printf(" ");
                        bexpr[cnt++]=' ';
            n--;
            
        }
        /* 3. token에 괄호(')')가 들어간다면... */
        
        else if(token == rparen)                        
                {
            while(stack[top] != lparen)
                print_token(pop(&top));
            pop(&top);                                                      //좌 괄호를 버린다.
        }


        /* 4. token이 연산자 일때. */
                
                else                                                    //symbol의 isp가 token의 icp보다 크거나 같으면 symbol을 제거하고 출력 시킴.
                {
                        while(isp[stack[top]] >= icp[token])
                                print_token(pop(&top));
                        push(&top, token);
                }
        }
        
        
        /* 결과물 출력. */   
        while((token = pop(&top)) != eos)
                print_token (token);
}



/****************************************************************/
/*                      push함수                                                                                  */
/*      - 스택에 push 해주는 함수.                                                                      */
/****************************************************************/

void push(int* top,precedence token){
        stack[++(*top)] = token;
}       




/****************************************************************/
/*                      pop함수                                                                                           */
/****************************************************************/

int pop(int* top){
        int temp =stack[*top];
        (*top)--;
        return temp;
}



/****************************************************************/
/*                              get_token                                                                               */
/*      입력 문자열로부터 토큰을 얻기위한 함수.                                          */
/*      - 토큰이 연산자이면 명칭으로 반환.(return)                                    */
/*      - symbol은 expr의 n++번째 요소 를 보고 인식.                               */
/*      - call by reference.                                                                            */
/****************************************************************/
precedence get_token(char* symbol , int* n)
{
        *symbol = expr[(*n)++];                 //symbol은 문자표현.
        switch (*symbol){
                case '(' : return lparen;
                case ')' : return rparen;
                case '+' : return plus;
                case '-' : return minus;
                case '/' : return divide;
                case '*' : return times;
                case '%' : return mod;
                case 's' : return s;
                case 'c' : return c;
                case 't' : return t;
                case '\0' : return eos;
                default : return operand;               //오류 검사는 하지 않고 기본값은 피연산자.
        }
}

/****************************************************************/
/*      precedence상태인 토큰을 연산자로 바꾸어 출력해주는 함수.    */
/*      print_token                                                                                                     */
/****************************************************************/


void print_token(int opt)
{
//      char* copt = opt;
//      switch (*copt){
        char copt;
        switch (opt){
                case plus       : copt = '+' ;
                        break;
                case minus      : copt = '-' ;
                        break;
                case divide : copt = '/' ;
                        break;
                case times      : copt = '*' ;
                        break;
                case mod        : copt = '%' ;
                        break;
                case s          : copt = 's' ;
                        break;
                case c          : copt = 'c' ;
                        break;
                case t          : copt = 't' ;
                        break;
                default : return ;
        
        }
        bexpr[cnt++]=copt;
        bexpr[cnt++]=' ';

        printf("%c ",copt);
}
/*=====================================================================*/

/*                              ☆★ 미니 프로젝트 : calculator. ☆★                   */



/*                 목적 : 중위 표기식을 후위 표기식으로 변환해서 계산.              */

/*                 기능 :-삼각함수 연산 가능.                                                                                     
                                        ex)-10*-cos(--sin(--45--45)/2-sin(40))                                                          
                                           -10 -1 45 45 + sin 2 / 40 sin - cos * *      =10.0
                                           radian = (PI*first)/180;
/*                           -에러처리 가능.
                                        ex)-10*-(-9.1(--0.8--0.1))
                                           =error       
/*=====================================================================*/

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<math.h>

#define MAX_STACK_SIZE 100                      //스택 최대 크기.
#define MAX_EXPR_SIZE 100                       //수식의 최대 크기.
#define PI 3.14159                                      //파이 3.14159

typedef enum {lparen, rparen, plus, minus, times, divide, mod,  s,  c,  t, eos, operand} precedence;
                        //       (              )               +         -              *              /          %    s   c   t       0       default         
                        //       0              1               2         3              4              5          6    7       8       9   10    11            

int stack[MAX_STACK_SIZE];                      //전역 배열.
char expr[MAX_EXPR_SIZE];                       //입력 문자열.
char bexpr[MAX_EXPR_SIZE];                      //후위 표기법으로 저장되는 배열.
double result[MAX_STACK_SIZE];          //연산해주는 스택.
int cnt=0;

precedence stack[MAX_STACK_SIZE];       //연산자가 푸쉬&팝 되는 스택.

static int isp[] = {0, 19, 12, 12, 13, 13, 13, 14, 14, 14, 0};          //in-stack precredence.
                                 // 0   1       2       3       4       5       6       7       8       9  10
static int icp[] = {20, 19, 12, 12, 13, 13, 13, 14, 14, 14, 0};                 //incoming precedence.

/*********** 함수 ************/

void postfix(void);                                                             // 중위 표기법을 후위 표기법으로 바꿔주는 함수.

void push(int* top,precedence token);                   // 스택에 입력하는 함수.

int pop(int* top);                                                              // 스택에서 출력 함수.
        
precedence get_token(char* symbol , int* n);    // precedence type으로 바꿔주는 함수. 

void print_token(int opt);                                              // precedence를 기호로 바꾸어 출력.

double Opop(int* top);                                                  // 연산해줄 탑 출력하는 함수.      (main에서 계산시 사용.)

void Opush(int* top,double i);                                  // 탑에 연산해줄 값을 입력하는 함수.  (main에서 계산시 사용.)

double operation(int* top,char i);                              // 두수를 팝하여 연산해주는 계산기.           (main에서 계산시 사용.)


/*****************************************************************/
/*                      메인 함수.                                                                                   */
/*****************************************************************/
int main(void){
        char bag[MAX_STACK_SIZE];       // bexpr에서 더블형으로 바꿔 result[]에 옮겨주는 배열. 
        char* bp=bexpr;                         // bag에 넣을 입력 문자열의 포인터.
        int top = -1;                           // top 다음에 수가 저장.
        int n = 0;                                      // for문의 카운터. 인덱스.
        int i = 0;                                      // bag의 카운터.
        double sol;                                     // 팝된 값들의 연산후 저장될 변수. 푸쉬됨.
        printf("중위 표기법으로 입력하시오.\n중위표기법 =>\t");
        scanf("%s",expr);
        printf("후위표기법 => \t");
        postfix();
        
        for(; n<(int)strlen(bexpr); n++,*bp++)
        {
                if((bexpr[n]=='-' && isdigit(bexpr[n+1])!=0)||(isdigit(bexpr[n]) != 0))
                {
                        i=0;
                        while(bexpr[n] !=' '){                          // *bp 즉 bexpr[n]의 값이 띄어쓰기가 나오기 전까지 bag에 입력.
                                bag[i++]=*(bp++);
                                n++;
                        }
                        bag[i]='\0';
                        Opush(&top,atof(bag));                              //result스택의 top에 bag숫자열을 float형으로 변환하여 넣어줌.
                }
                else if(isdigit(bexpr[n])==0 && bexpr[n]!=' ')          // 연산자가 나오면!
                {         
                        sol = operation(&top,bexpr[n]);                                     // 두 수를 팝하여 연산하고 그 리턴형을 sol에 저장. 
                        Opush(&top, sol);                                                           // sol을 푸쉬!.
                }
        //      printf("\nbag= %s\n",bag);
        //      printf("result= %f\n",result[top]); 
        }
        
        printf("\n결과는     => \t%lf \n",Opop(&top));                              //마지막 탑. 즉, 결과를 출력. 
        return 0;
}



/****************************************************************/
/*      (계산기)두수를 팝하여 연산해주는 계산기 함수.                              */
/*      operation                                                                                                       */
/****************************************************************/

double operation(int* top,char i)
{
        double first,second,radian;
        
        if(i=='s')                                                                      //sin 
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return sin(radian);
        }
        else if(i=='c')                                                         //cos
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return cos(radian);
        }
        else if(i=='t')                                                         //tan
        {
                first=Opop(top);
                radian=(PI*first)/180;
                return tan(radian);
        }
        else                                                                            //연산자
        {
                second=Opop(top);
                first=Opop(top);
                switch(i) {
                case '+' : return (first+second);
                case '-' : return (first-second);
                case '/' : return (first/second);
                case '*' : return (first*second);
                case '%' : return (first*second);
                default : return 0 ;
                }
        }
}


                        
/****************************************************************/
/*      (계산기) 탑에 연산해줄 값을 입력하는 함수.                                       */
/*      Opush                                                                                                           */
/****************************************************************/


void Opush(int* top,double i)
{
        result[++(*top)] = i;
}

/****************************************************************/
/*      (계산기) 연산해줄 탑을 출력해주는 Operation_pop함수.            */
/*       Opop                                                                                                           */
/****************************************************************/
double Opop(int* top)
{
        double temp = result[*top];
        (*top)--;
        return temp;
}

/****************************************************************/
/*      중위표기법을 후위표기법으로 바꿔주는  함수.                                        */
/*      - 수식 문자열, 스택, top은 전역적                                                  */
/*      postfix                                                                                                         */
/****************************************************************/

void postfix(void)
{
        char symbol;
        precedence token;               // 인덱스다. 결국은 정수.
        int n = 0;                              //스택 인덱스.
        int top = 0;                    //top의 초기값. (최초의 연산자와 비교해줄 eos의 인덱스)
        int mcnt = 1;                   // '-'의 갯수를 측정하는 카운트.
        int on = 0;                             // n의 상수값.
        char tri ;                              // 삼각 함수 한글자를 저장할 값.
        stack[0] = eos;                 //최초의 연산자와 비교해줄 최초의 top.(eos)
        

        for(token = get_token(&symbol, &n); token != eos; token = get_token(&symbol, &n))       //token이 eos를 가리킬때까지 get_token. 
        {       
        /* 1. token이 마이너스 일때. */
                if(token == minus)
                {       
                        on = n;                                         //n의 최초 값.
                        
                        for(; expr[n] == '-'; n++)                                                      //mcnt 카운트로 '-'갯수 측정. n의 값이 증가하는것에 유의.
                                mcnt++;
                                
                        
                                /* "-(" 가 나온 경우① "-1*("로 바꿔주는 문. "-(" 앞이 숫자가 아닐경우.  */
            if(expr[n] == '('&& expr[n-2] != '-' && isdigit(expr[n-2]) ==0){    
                                //expr[n-4] = '(';
                                expr[n-3] = '-';
                expr[n-2] = '1';
                expr[n-1] = '*';

                n-=3;
            }
                                /* "-(" 가 나온 경우②   "-(" 앞이 숫자일 경우. '+'연산자가 필요하게 됨.  */
                        else if(expr[n] == '('&& expr[n-2] != '-' && isdigit(expr[n-2]) !=0){   
                                expr[n-4] = '+';
                                expr[n-3] = '-';
                expr[n-2] = '1';
                expr[n-1] = '*';
                n-=4;
            }

                                /* 삼각함수가 나온 경우①. 위의 괄호의 경우처럼 둘로 나누어 연산.*/
                        else if((expr[n] == 's'||expr[n] == 'c'||expr[n] == 't')&&  expr[n-2] != '-' && isdigit(expr[n-2]) ==0){        
                                tri=expr[n];
                        //      expr[n-2] = '(';
                                expr[n-1] = '-';
                                expr[n]   = '1';
                                expr[n+1] = '*';
                                expr[n+2] = tri;
                                n--;
                        }
                                /* 삼각함수가 나온 경우②.*/
                        else if((expr[n] == 's'||expr[n] == 'c'||expr[n] == 't')&&  expr[n-2] != '-' && isdigit(expr[n-2]) !=0){                                
                                tri=expr[n];
                                expr[n-2] = '+';
                                expr[n-1] = '-';
                                expr[n]   = '1';
                                expr[n+1] = '*';
                                expr[n+2] = tri;
                                n-=2;
                        }

                                /* '-'의 앞이 괄호나 숫자가 아니고  뒤에 숫자가 나왔을때 음수기호로 만들어주는 경우.*/                   
            else if((isdigit(expr[on-2]) ==0) && (mcnt%2==1) && expr[on-2] !=')' ){                     
                printf("-");
                                bexpr[cnt++]='-';
                        }

            else if(mcnt%2==0){                                                                 // '-'가 짝수개.
                                if(isdigit(expr[on-2])==0)                                              // --앞에 숫자 아니면..없어져라..
                                        ;
                                
                                else{
                                        token = plus;
                                        while(isp[stack[top]] >= icp[token])
                                                print_token(pop(&top));
                                        push(&top, token);
                                }
            }
            else if(mcnt%2==1){                                                         // '-'가 홀수개. mcnt != 1
                token = minus;
                while(isp[stack[top]] >= icp[token])
                    print_token(pop(&top));
                push(&top, token);
            }
            mcnt=1;
                        //printf("%s\n",expr);
        }
        
                else if(token == s || token == c || token == t){
                        //tri=token;
                
                        while(isp[stack[top]] >= icp[token])
                                print_token(pop(&top));
                        push(&top, token);
                        while(expr[n]!='(')
                                n++;
                }
                
        /* 2. token이 숫자 일때. */  

        
        else if(token == operand)               
        {
            printf("%c",symbol);
                        bexpr[cnt++]=symbol;
            while(get_token (&symbol, &n) == operand){
                                
                                if(expr[n] == '('){
                                        printf("????? -_-\n\nERROR : 연산자를 미입력 하셨습니다.\n\n");
                                        return;
                                }
                printf("%c",symbol);
                                bexpr[cnt++]=symbol;
                        }
            printf(" ");
                        bexpr[cnt++]=' ';
            n--;
            
        }
        /* 3. token에 괄호(')')가 들어간다면... */
        
        else if(token == rparen)                        
                {
            while(stack[top] != lparen)
                print_token(pop(&top));
            pop(&top);                                                      //좌 괄호를 버린다.
        }


        /* 4. token이 연산자 일때. */
                
                else                                                    //symbol의 isp가 token의 icp보다 크거나 같으면 symbol을 제거하고 출력 시킴.
                {
                        while(isp[stack[top]] >= icp[token])
                                print_token(pop(&top));
                        push(&top, token);
                }
        }
        
        
        /* 결과물 출력. */   
        while((token = pop(&top)) != eos)
                print_token (token);
}



/****************************************************************/
/*                      push함수                                                                                  */
/*      - 스택에 push 해주는 함수.                                                                      */
/****************************************************************/

void push(int* top,precedence token){
        stack[++(*top)] = token;
}       




/****************************************************************/
/*                      pop함수                                                                                           */
/****************************************************************/

int pop(int* top){
        int temp =stack[*top];
        (*top)--;
        return temp;
}



/****************************************************************/
/*                              get_token                                                                               */
/*      입력 문자열로부터 토큰을 얻기위한 함수.                                          */
/*      - 토큰이 연산자이면 명칭으로 반환.(return)                                    */
/*      - symbol은 expr의 n++번째 요소 를 보고 인식.                               */
/*      - call by reference.                                                                            */
/****************************************************************/
precedence get_token(char* symbol , int* n)
{
        *symbol = expr[(*n)++];                 //symbol은 문자표현.
        switch (*symbol){
                case '(' : return lparen;
                case ')' : return rparen;
                case '+' : return plus;
                case '-' : return minus;
                case '/' : return divide;
                case '*' : return times;
                case '%' : return mod;
                case 's' : return s;
                case 'c' : return c;
                case 't' : return t;
                case '\0' : return eos;
                default : return operand;               //오류 검사는 하지 않고 기본값은 피연산자.
        }
}

/****************************************************************/
/*      precedence상태인 토큰을 연산자로 바꾸어 출력해주는 함수.    */
/*      print_token                                                                                                     */
/****************************************************************/


void print_token(int opt)
{
//      char* copt = opt;
//      switch (*copt){
        char copt;
        switch (opt){
                case plus       : copt = '+' ;
                        break;
                case minus      : copt = '-' ;
                        break;
                case divide : copt = '/' ;
                        break;
                case times      : copt = '*' ;
                        break;
                case mod        : copt = '%' ;
                        break;
                case s          : copt = 's' ;
                        break;
                case c          : copt = 'c' ;
                        break;
                case t          : copt = 't' ;
                        break;
                default : return ;
        
        }
        bexpr[cnt++]=copt;
        bexpr[cnt++]=' ';

        printf("%c ",copt);
}
        

이 글은 스프링노트에서 작성되었습니다.

'Programming Language > C' 카테고리의 다른 글

C Tutorial (L_list 역순출력)  (0) 2010.10.14
C Tutorial (트리 문자 읽기)  (0) 2010.10.14
C Tutorial (strcmp+numcmp)  (0) 2010.10.14
C Tutorial ([C.L.A]. 문자열중간읽기)  (0) 2010.10.14
C Tutorial (역순화 문자열)  (0) 2010.10.14
Posted by BLUE-NOTE