코드가 길어서 죄송합니다 ㅜㅜ c언어 어휘분석기 입니다.

yooss0520의 이미지

/*
아직 c언어에 대해 잘 모르는 학생입니다. 우선 죄송스럽지만, 어디서 문제가 발생하였는지 찾을 수 없어 전체 코드를 올리게 되었습니다.
C로 작성된 Syntax Analyzer이며, 컴파일시에, 문법적인 오류는 없는지 컴파일은 되고, 생성된 exe 파일을 실행함으로써 outputfile이 생성은 되지만, outputfile이 아무것도 작성되지 않은 0byte 파일이 생성되는 문제가 발생되고 있습니다.

c파일을 입력받고, 정수, 실수, ID, KEYWORD, 사칙연산기호, 비트연산, 대소비교, 괄호, 세미콜론, 공백 등을 입력받았을 때, 아래의 결과와 같이 출력되는 프로그램으로 만들려고 하였습니다.

ex) int a = 10;
int
WHITESPACE
ID a
WHITESPACE
Assign =
WHITESPACE
INTEGER 10
SEMI ;
*/

#include
#include
#include
#include
#include
#include
#define URT 40

typedef struct tkt { // token sturcture
int kind; // kind of token
float rnum; //
int num;
char str[100]; // token String
int sub_data;

}tokentype;

typedef char oneword [50];

typedef struct {
oneword str;
} key_ent ;

key_ent keywordtable [15] = {"int","char", "bool", "float","true","false","if","else","while","for","return"} ;
int keyword_cnt = 10 ;
// To check its keyword.

typedef struct sym {
oneword idstr;
} sym_ent;

sym_ent symtbl [500] ;
int symtbl_idx = 0 ;

oneword tk_name [100] = {"INTEGER","FLOAT","WHITESPACE","STRING","ID","ARITHMETIC","BITWISE","ASSIGN",
"COMPARISON","SEMI","LBRACE","RBRACE","LPAREN","RPAREN","COMMA"};
// token_type name to named all tokens

FILE *fp, *ofp ;

tokentype lexem (void) ;
char myfgetc (FILE *fp) ;

int lookup_keywordtbl(char buf[]){
int i=0;
for(i=0;i<15;i++){
if(strcmp(buf,keywordtable[i].str)==0)
return i;
}
}

int lookup_symtbl(char buf[]){
int i=0;
for(i=0; i<100; i++){
if(strcmp(buf,symtbl[i].idstr)==0) {
return i;
}
}
return -1;
}

void print_token (tokentype a_tok, FILE *ofp) {

if (a_tok.kind == 0) {
fprintf(ofp, "%13s ", "INTEGER");
fprintf(ofp, "%13s ", a_tok.sub_data);
}

else if (a_tok.kind == 1) {
fprintf(ofp, "%13s ", "FLOAT");

if( a_tok.rnum - a_tok.num == 0.0){
fprintf(ofp, "%13.1f ", a_tok.rnum);
}

else{
fprintf(ofp, "%13g ", a_tok.rnum);
}
}

else if (a_tok.kind == 2) {
fprintf(ofp, "%13s ", "WHITESPACE");
}

else if (a_tok.kind == 3) {
fprintf(ofp, "%13s ", "STRING");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 4) {
fprintf(ofp, "%13s ", "ID");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 5) {
fprintf(ofp, "%13s ", "ARITHMETIC");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 6) {
fprintf(ofp, "%13s ", "BITWISE");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 7) {
fprintf(ofp, "%13d ", a_tok.kind);
fprintf(ofp, "%13s ", "ASSIGN");
}

else if (a_tok.kind == 8) {
fprintf(ofp, "%13s ", "COMPARISON");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 9) {
fprintf(ofp, "%13s ", "SEMI");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 10) {
fprintf(ofp, "%13s ", "LBRACE");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 11) {
fprintf(ofp, "%13s ", "RBRACE");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 12) {
fprintf(ofp, "%13s ", "LPAREN");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 13) {
fprintf(ofp, "%13s ", "RPAREN");
fprintf(ofp, "%13s ", a_tok.str);
}

else if (a_tok.kind == 14) {
fprintf(ofp, "%13s ", "COMMA");
fprintf(ofp, "%13s ", a_tok.str);
}

fprintf(ofp, " \n" );
printf(" \n" );

}

void main (void) {
tokentype a_tok;
char source_file [30] = "inputfile.c";
char output_file [30] = "outputfile.out";
int done = 0;
int index = 1;

fp = fopen (source_file, "r" );
if (!fp){
printf("ERROR: CHECK FILE NAMEED inputfile.c!");
return;
}
ofp = fopen (output_file, "w") ;
if (!ofp) {
printf("ERROR: CHECK FILE NAMED output.out!");
return;
}
fprintf(ofp,"TOKEN_NUM, TYPE, STRING(strbuf)\n",index);

while (!done ) {
a_tok = lexem ( ) ;
if (a_tok.kind == 43) // EOF TOKEN
done = 1 ;

else {
fprintf(ofp,"[%d] ",index);
print_token (a_tok, ofp) ;
}
index++;
}

fclose(fp);
fclose(ofp);
}

tokentype lexem () {
int state = 0;
char c;
char buf[50];
int bp = 0; // bp is buffer pointer(Next location).
int upper_n, FCNT=0;
int idx=0;
float fraction=0.0 ; // float type under '.'
tokentype token ;
token.kind=0;
token.rnum=0.0;
token.num=0;
token.sub_data=0;

while ( 1 ) {
switch (state) {
case 0: // CHECK FIRST CHAR OF TOKEN TO DECIDE TYPE
c = myfgetc (fp) ;

if (isalpha(c)) {
buf[bp] = c;
bp++;
state = 1;
}

else if(c =='_') {
buf[bp] = c;
bp++;
state = 1;
}

else if (c >=1 && c <= 9) {
upper_n = c;
state = 3;
}

else if (c == 0){
upper_n = c;
state = 6;
}

else if (c == '-')
state = 7;

else if(c == '"') {
buf[bp] = c;
bp++;
state = 12;
}

else if (c == ' ' || c == '\n' || c == '\t') {
state = 11;
} // WHITESPACE

else if( c == '+')
state = 14;

else if(c == '*')
state = 16;

else if( c== '/')
state = 17;

else if(c == '<')
state = 18;

else if(c == '>')
state = 22;

else if(c == '&')
state = 26;

else if(c == '|')
state = 27;

else if(c == '=')
state = 28;

else if(c == ';')
state = 32;

else if(c == '{')
state = 33;

else if(c == '}')
state = 34;

else if(c == '(')
state = 35;

else if(c == ')')
state = 36;

else if(c == ',')
state = 37;

else if(c == EOF) {
token.kind = 43;
return token;
}

else {
token.kind = URT ;
return token ;
}
break;

case 1:
c = myfgetc (fp) ;
if (isalpha(c) || isdigit(c)|c=='_') {
buf[bp] = c;
bp++;
state = 1;
} // Distinguish ID
else state = 2 ;
break ;

case 2:
ungetc (c, fp) ;
buf[bp] = '\0' ;
idx = lookup_keywordtbl (buf) ; // -1 if not exist.
if ( idx >= 0 ) {
strcpy(token.str,buf);
return token;
}

idx = lookup_symtbl (buf) ; // -1 if not exist.
if (idx >= 0) {
token.kind = 4 ;
token.sub_data = idx;
strcpy(token.str,buf);
return token;
}
// reaches here if it is not in symbol table.
strcpy (symtbl[symtbl_idx].idstr, buf);
symtbl_idx++;
token.kind = 4 ; // Identify it's ID token
token.sub_data = symtbl_idx - 1;
strcpy (token.str , buf) ;
return token;
//------------------------------------------------------------------------------------------
case 3: // After get 1 ~ 9
c = myfgetc(fp) ;
if (isdigit(c)) {
upper_n = 10*upper_n + c - '0';
state = 3;
}

else if (c == '.') {
state = 5 ;
fraction = 0 ;
FCNT = 0;
}
else state = 4 ;
break ;

case 4:
ungetc (c, fp) ;
token.kind = 0 ;
token.sub_data = upper_n ;
return token;
case 5:
c = myfgetc(fp);
FCNT++ ;
if (isdigit(c) ) {
fraction = fraction + ((float)(c - '0')/powf((float)10,FCNT));
state = 5 ;
break;
}
else {
ungetc (c, fp) ;
token.kind = 1 ;
token.num = upper_n;
token.rnum = upper_n + fraction ;
return token;
}

case 6:
c = myfgetc(fp);
if(c == '.') {
state = 5 ;
fraction = 0;
FCNT = 0;
}

else if (isalpha(c)){
ungetc (c, fp);
token.kind = 0;
token.sub_data = upper_n;
return token;
}

case 7:
c = myfgetc(fp);
if(c == 0){
upper_n = -c;
state = 8;
}

else if(c >=1 && c <= 9){
upper_n = -c;
state = 9;
}
else{
ungetc(c, fp);
state = 15; // only '-'
}
case 8:
c= myfgetc(fp);
if(c == '.'){
state = 10;
fraction = 0;
FCNT = 0;
}

case 9:
c = myfgetc(fp) ;
if (isdigit(c)) {
upper_n = 10*upper_n - c - '0';
state = 9;
}

else if (c == '.') {
state = 10 ;
fraction = 0 ;
FCNT = 0;
}

case 10:
c = myfgetc(fp);
FCNT++ ;
if (isdigit(c) ) {
fraction = fraction + ((float)(c - '0')/powf((float)10,FCNT));
state = 10 ;
break;
}

else {
ungetc (c, fp) ;
token.kind = 1 ;
token.num = upper_n;
token.rnum = upper_n - fraction ;
return token;
}

//------------------------------------------------------------------------------------------

case 11: // WHITE SPACE
token.kind = 2;
return token;

//------------------------------------------------------------------------------------------

case 12:
c = myfgetc (fp) ;
if (isalpha(c) | isdigit(c) | c=='_' || c == ' ' || c == '\n' || c == '\t') {
buf[bp] = c;
bp++;
state = 12;
} // Distinguish STRING
else if (c == '"')
state = 13 ;
break ;

case 13:
buf[bp] = '\0' ;
idx = lookup_keywordtbl (buf) ; // -1 if not exist.
if ( idx >= 0 ) {
strcpy(token.str,buf);
return token;
}

idx = lookup_symtbl (buf) ; // -1 if not exist.
if (idx >= 0) {
token.kind = 3 ;
token.sub_data = idx;
strcpy(token.str,buf);
return token;
}
// reaches here if it is not in symbol table.
strcpy (symtbl[symtbl_idx].idstr, buf);
symtbl_idx++;
token.kind = 3 ; // Identify it's String token
token.sub_data = symtbl_idx - 1;
strcpy (token.str , buf) ;
return token;

case 14:
token.kind = 5;
strcpy(token.str, "+");
return token;

case 15:
token.kind = 5;
strcpy(token.str, "-");
return token;

case 16:
token.kind = 5;
strcpy(token.str, "*");
return token;

// comment + Arithemetic
case 17:
c = myfgetc(fp) ;
if (c == '/') state =100;
else if(c=='*') state= 101;
else state =102 ;
break;
case 100:
c = myfgetc(fp) ;
while(1){

if(c=='\n'){
state = 0;
break;
}
c = myfgetc(fp) ;
}
break;
case 101:
c = myfgetc(fp) ;
while(1){
if(c=='*'){
c = myfgetc(fp) ;
if(c=='/'){
state=0;
break;
}
else{
ungetc (c, fp) ;
}
}
c = myfgetc(fp) ;
}
break;
case 102:
token.kind = 5;
strcpy (token.str, "/" ) ;
return token;

//------------------------------------------------------------------------------------------

case 18:
c = myfgetc(fp);
if (c == '=') state = 19 ;
else if(c == '<') state = 21;
else state = 20 ;
break;
case 19: //<=
token.kind = 8;
strcpy (token.str, "<=" ) ;
return token;
case 20: // <
ungetc (c, fp);
token.kind = 8;
strcpy (token.str, "<" ) ;
return token;
case 21:// 토큰 <<
token.kind = 6;
strcpy (token.str, "<<" ) ;
return token;

case 22:
c = myfgetc(fp);
if (c == '=') state = 23 ;
else if(c == '>') state = 25;
else state = 24 ;
break;
case 23: //<=
token.kind = 8;
strcpy (token.str, ">=" ) ;
return token;
case 24: // <
ungetc (c, fp);
token.kind = 8;
strcpy (token.str, ">" ) ;
return token;
case 25:// 토큰 <<
token.kind = 6;
strcpy (token.str, ">>" ) ;
return token;

case 26:
token.kind = 6;
strcpy (token.str, "&" ) ;
return token;
case 27:
token.kind = 6;
strcpy (token.str, "|" ) ;
return token;

case 28:
c = myfgetc(fp) ;
if (c == '=') state = 29;
else if(c=='!') state= 30;
else state =31;
break;

case 29:
token.kind = 8;
strcpy (token.str, "==" ) ;
return token;
case 30:
token.kind = 8;
strcpy (token.str, "=!" ) ;
return token;

case 31:
ungetc (c, fp);
token.kind = 7;
strcpy (token.str, "=" ) ;
return token;

case 32:
token.kind = 9;
strcpy (token.str, ";" ) ;
return token;

case 33:
token.kind = 10;
strcpy (token.str, "{" ) ;
return token;

case 34:
token.kind = 11;
strcpy (token.str, "}" ) ;
return token;

case 35:
token.kind = 12;
strcpy (token.str, "(" ) ;
return token;

case 36:
token.kind = 13;
strcpy (token.str, ")" ) ;
return token;

case 37:
token.kind = 14;
strcpy (token.str, "," ) ;
return token;

default: printf ("Error at . \n" ); return token;
} // switch
} //while
}

char myfgetc (FILE *fp) {
char c;
c = fgetc(fp);
return c ;
}

익명 사용자의 이미지

죄송할 것까지는 없습니다.

아무도 코드를 읽을 의무가 없으니까요.
그럼에도 불구하고 읽고 답변해 주는 사람들은 본인 선택 하에서 그러는 거죠.

그래도 이왕이면 <code> 블럭으로 감싸 주셔야 읽고 싶은 사람들이 좀 더 편하게 볼 수 있을 겁니다.
본인 코드가 들여쓰기 하나 없이, #include 다 깨져서 엉망으로 올라간 것 보고 아무 생각도 안 들던가요?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.