#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)
로그인 후 작성할 수 있습니다.