PHOENIX
참새 계급 아이콘계급:참새 (27기 최영재) 02.11(+)
루키 훈장(비행10회)파일럿 훈장(비행5회)처녀비행 훈장10회 이착륙 훈장5회 이착륙 훈장1회 이착륙 훈장

일반게시판

sr_parser 컴파일러2006-06-27 · 조회 4

#include 'stdio.h'
#include 'stdlib.h'
#include 'ctype.h'
#include 'string.h'

#define COL 5  //table의 col정의
#define ROW 10  //table의 row 정의
#define MAX 30 //stack의 최고값 정의
#define char_to_int(c) (int) c-'0'

typedef struct rule{
 char lhs;
 char rhs[10];
}rule; //rule 구조체 정의
rule R[4]; //rule을 4개 지정

FILE *output; //파일포인터
char stack[MAX]; //stack 값 지정
char *table[ROW][COL]; //table포인터 정의
int top=-1; //top의 값을 -1로 지정

void SRparser(char input[]); //파싱하는 함수
int get_col(char t); //알파벳 심볼의 인덱스를 구하는 함수
char *init_stack(char String[]); //input string을 생성하고, 스택을 초기화한다
char gettop(); //stack의 top부분을 가져옴
void GOTO(); //goto함수가 적용
void shift(char num, char pu); //shift함수
int reduce(char num);  //reduce함수
void push(char c); //스택을 push
char pop(); //스택을 pop
void filewrite(int step, char string[]); //결과값들을 파일에 출력해주는 함수

void main(int argc, char* argv[]){
 int i, j;

 for(i=0;i<ROW;i++){
  for(j=0;j<COL;j++){
   table[i][j]='\0';
  }
 }
 table[0][0]='s3'; table[0][1]='s4'; table[0][3]='1'; 
 table[0][4]='2';    table[1][2]='acc'; table[2][0]='s6'; 
 table[2][1]='s7'; table[2][4]='5';    table[3][0]='s3'; 
 table[3][1]='s4'; table[3][4]='8'; table[4][0]='r3';
 table[4][1]='r3'; table[5][2]='r1'; table[6][0]='s6'; 
 table[6][1]='s7';   table[6][4]='9'; table[7][2]='r3'; 
 table[8][0]='r2'; table[8][1]='r2';   table[9][2]='r2';
 R[0].lhs='A'; strcpy(R[0].rhs, 'S');  R[1].lhs='S'; strcpy(R[1].rhs, 'CC');
 R[2].lhs='C'; strcpy(R[2].rhs, 'cC'); R[3].lhs='C'; strcpy(R[3].rhs, 'd');

 SRparser(init_stack(argv[1])); 
}

void SRparser(char input[]){
 char stacktop, *st;
 int select, row, col, flag=1, check=0, step=0;
 
 output = fopen('bt-parsing-result.txt', 'w');
 fprintf(output,'Step\tStack\t\t\tinput\t\taction\n');
 printf('Right parse : ');
 while(flag){
  filewrite(step++, input);
  st=NULL;
  if(check) select= 4;
  else{
   stacktop=gettop();
   if(isalpha(stacktop)) select = 5;
    
   else if(isdigit(stacktop)){
    row=char_to_int(stacktop);
    col=get_col(*input);
    if(col == -1){select = 4; st = NULL;}
    else st=table[row][col];
   }
   if(st && *st == 's') select=1; //shift: 1
   else if(st && *st == 'r') select=2; // reduce :2
   else if(st && *st == 'a') select=3; // accept :3
   else if(st) select=4; //error : 4
   switch(select){
   case 1: shift(*(++st), *input); input++; break;
   case 2: check=reduce(*(++st)); printf('%c', *st); break;
   case 3: printf('\nreselt : accept\n'); fprintf(output,'accept\n'); flag=0; break;
   case 4: printf('error\n'); fprintf(output,'error\n'); flag=0; break;
   case 5: GOTO(); break;
   }
  } 
 }
 fclose(output);
}

void filewrite(int step, char string[]){
 fprintf(output,'%d\t',step);
 if(top>15) fprintf(output,'%s\t', stack);
 else if(top>=7) fprintf(output,'%s\t\t', stack);
 else fprintf(output,'%s\t\t\t', stack);
 if(strlen(string) >7) fprintf(output,'%s\t', string);
 else fprintf(output,'%s\t\t', string);
 
}

char* init_stack(char String[]){
 int i;
 char *cp;
 push('0');
 i=strlen(String); //Srting의 길이 측정
 cp=(char *) malloc(sizeof(char) * i+2);
 strcpy(cp, String);
 cp[i]='$'; cp[i+1]='\0';
 return cp;

}

int reduce(char num){
 int number = char_to_int(num);
 int i, avail, temp_num=0;
 char temp[10], temp2, temp3[10];
 fprintf(output,'reduce\t%d\n', number);
 avail=strlen(R[number].rhs)*2;
 for(i=0;i<avail;i++){
  temp2=pop();
  if(isalpha(temp2)){
   temp[temp_num++]=temp2;
   temp[temp_num]='\0';
  }
 }
 avail=0;
 for(i=temp_num-1;i>=0;i--){
  temp3[avail++]=temp[i];
  temp3[avail]='\0';
 }
 if(strcmp(R[number].rhs, temp3)) return 1;
 else push(R[number].lhs);
 return 0; 
}

void shift(char num, char pu){
 int number=char_to_int(num);
 fprintf(output,'shitf\t%d\n', number);
 push(pu);
 push(num);
}

void GOTO(){
 int row, col, avail=top-1;
 char *temp;
 if(top<1){
  printf('err'); exit(1);
 }
 else{
  col=get_col(gettop());
  row=char_to_int(stack[avail]);
  temp=table[row][col];
  push(*temp);
 }
 fprintf(output,'GOTO\t%c\n', *temp);

}

char gettop(){
 if(top<=-1){
  printf('stack is empty\n');
  exit(1);
 }
 else return stack[top];
}

int get_col(char t){
 int x;
 switch(t){
 case 'c' : x=0; break;
 case 'd' : x=1; break;
 case '$' : x=2; break;
 case 'S' : x=3; break;
 case 'C' : x=4; break;
 default : x= -1; break;
 }
 return x;

}

void push(char c){
 if(top>=MAX){
  printf('stack is full\n');
  exit(1);
 }
 stack[++top]=c;
 stack[top+1]='\0';
}

char pop(){
 char temp;
 if(top<=-1){
  printf('stack is empty\n');
  exit(1);
 }
 temp=stack[top];
 stack[top]='\0';
 top--;
 return temp;
}

 

 

목록

덧글쓰기 (0)