#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct _token {
int type;
int value;
char *lexeme;
} token;
token* key_or_id(FILE *fin, int x) {
const char *keywords[12]={
"else", "if", "int", "return", "void", "while", "char", "for", "do", "switch", "continue", "break"
};
token *tok;
int i, j, n=12;
char buf[100];
i=0;
while(isalpha(x)) {
buf[i]=(char)x;
i+=1;
x=fgetc(fin);
}
buf[i]=0;
ungetc(x, fin);
for(i=0;i<n;++i) {
if(strcmp(buf, keywords[i])==0) { break; }
}
tok=(token*)calloc(sizeof(token), 1);
if(tok==NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
if(i<n) {
tok->type=1; // keyword;
tok->value=100+i; // 100: else 101: if ... 111: break 를 나타낸다.
} else {
tok->type=2; // identifier;
tok->lexeme=strdup(buf);
}
return tok;
}
token* number(FILE *fin, int x) {
token *tok;
int num=0;
while(isdigit(x)) {
num=10*num+x-'0';
x=fgetc(fin);
}
ungetc(x, fin);
tok=(token*)calloc(sizeof(token), 1);
if(tok==NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
tok->type=3; // number;
tok->value=num;
return tok;
}
token* special(FILE *fin, int x) {
token *tok;
tok=(token*)calloc(sizeof(token), 1);
if(tok==NULL) {
printf("Memory allocation failed.\n");
return NULL;
}
tok->type=-1; // not defined
tok->value=x; // 디버깅용
switch(x) {
case '/':
x=fgetc(fin);
if(x=='*') {
tok->type=4; // special symbol
tok->value=11; // 11: /* 코멘트의 시작
} else {
tok->type=4; // special symbol
tok->value=12; // 12: / 나눗셈 연산자
ungetc(x, fin);
}
break;
case '*':
x=fgetc(fin);
if(x=='/') {
tok->type=4; // special symbol
tok->value=13; // 13: */ 코멘트의 끝
} else {
tok->type=4; // special symbol
tok->value=14; // 14: * 곱셈 연산자
ungetc(x, fin);
}
break;
case '=':
x=fgetc(fin);
if(x=='=') {
tok->type=4; // special symbol
tok->value=15; // 15: == 비교 같다
} else {
tok->type=4; // special symbol
tok->value=16; // 16: = 대입 연산자
ungetc(x, fin);
}
break;
case '!':
x=fgetc(fin);
if(x=='=') {
tok->type=4; // special symbol
tok->value=17; // 17: != 비교 다르다
} else {
tok->type=4; // special symbol
tok->value=99; // 99: ! 에러
ungetc(x, fin);
}
break;
case '+':
tok->type=4; // special sysbol
tok->value=18; // 18: + 덧셈
break;
case '-':
tok->type=4; // special sysbol
tok->value=19; // 19: - 뺄셈
break;
case '<':
tok->type=4; // special sysbol
tok->value=20; // 20: < 작다
break;
case '>':
tok->type=4; // special sysbol
tok->value=21; // 21: > 크다
break;
case ';':
tok->type=4; // special sysbol
tok->value=22; // 22: ; 세미콜론
break;
case '(':
tok->type=4; // special sysbol
tok->value=23; // 23: ( 왼괄호
break;
case ')':
tok->type=4; // special sysbol
tok->value=24; // 24: ) 오른괄호
break;
case '{':
tok->type=4; // special sysbol
tok->value=25; // 25: { 왼중괄호
break;
case '}':
tok->type=4; // special sysbol
tok->value=26; // 26: } 오른중괄호
break;
case '[':
tok->type=4; // special sysbol
tok->value=27; // 27: [ 왼대괄호
break;
case ']':
tok->type=4; // special sysbol
tok->value=28; // 28: ] 오른대괄호
break;
}
return tok;
}
token* scanner(FILE *fin) {
int x;
while(!feof(fin)) {
x=fgetc(fin);
if(isalpha(x)) {
return key_or_id(fin, x);
} else if(isdigit(x)) {
return number(fin, x);
} else if(!isspace(x)) {
return special(fin, x);
} // white space needs to be skipped
}
}
int main() {
FILE *fin;
char fname[100];
token *ctok;
printf("파일이름: ");
gets(fname);
fin=fopen(fname, "r");
if(fin==NULL) {
printf("Cannot open file %s\n", fname);
return -1;
}
while(!feof(fin)) {
ctok=scanner(fin);
printf("token type = %d", ctok->type);
if(ctok->type==1) {
printf(" token value=%d\n", ctok->value);
} else if(ctok->type==2) {
printf(" token id = %s\n", ctok->lexeme);
} else if(ctok->type==3) {
printf(" token number=%d\n", ctok->value);
} else if(ctok->type==4) {
printf(" token kind=%d\n", ctok->value);
} else if(ctok->value!=-1) {
printf(" token kind=%c\n", ctok->value);
} else {
printf(" EOF\n");
}
}
fclose(fin);
return 0;
}
'c·c++ > c 프로그래밍' 카테고리의 다른 글
greedy knapsack (0) | 2013.05.04 |
---|---|
산길 내려가는 경로찾기 (0) | 2013.05.04 |
paper자르기 (0) | 2013.05.02 |
1부터 1000까지 3,6,9 의 숫자가 들어가는 소수들의 합을 구하는 문제 (0) | 2013.05.01 |
0과 1사이의 기약분수 (0) | 2013.04.28 |