www.pudn.com > express.rar > Expression.c


#include "stdio.h" 
#include "ctype.h" 
 
#define LEN sizeof(struct entry) 
 
char Buffer[256]; 
 
 
int state = 0; 
 
int lineno=1; 
 
char token[128]; 
int index=0; 
 
int flag=0;               /*0代表字符串,1代表数字,2代表运算符*/ 
 
char* keyword[]={"int","float","short","char","long","break","case","const", 
            "switch","continue","default","do","while","double","else","enum", 
            "extern","for","goto","if","register","return","signed","sizeof", 
            "static","struct","typedef","union","unsigned","void","volatile", 
            "auto"}; 
 
FILE *out; 
 
struct entry *headOfEntry; 
 
/*符号表用链表*/ 
struct entry 
{ 
    int attr;               /*记号*/ 
    char *value;            /*记号值*/ 
    struct entry *next;     /*指向下一结点指针*/ 
}; 
 
/*初始化符号链表*/ 
void entryinit() 
{ 
    headOfEntry=(struct entry *)malloc(LEN); 
    headOfEntry->next=NULL; 
} 
 
/*查询符号链表*/ 
int LookupEntry(char *c)                          /*字符串c是否存在于符号链表项中*/ 
{ 
                                                     /*若存在则返回1*/ 
    struct entry *e;                                /*若不存在则返回0*/ 
    int boolean=0; 
    e=headOfEntry->next; 
    while(e!=NULL) 
    { 
        if(strcmp(e->value,c)==0) 
        { 
            boolean=1; 
            printf("\nvalue is %s and c is %s\n",e->value,c); 
            return boolean; 
        } 
        e=e->next; 
    } 
    return boolean; 
} 
 
/*向符号链表中加入结点*/ 
void addToEntry(int f,char *symbol) 
{ 
    /*char *c;*/ 
    struct entry *p; 
    struct entry *new; 
 
    p = headOfEntry; 
    new = (struct entry *)malloc(LEN); 
    if(f==0) 
        new->attr=0; 
    else if(f==1) 
        new->attr=1; 
    new->value=strdup(symbol); 
    new->next=NULL; 
 
    while(p->next!=NULL) 
    { 
        p = p->next; 
    } 
 
    p->next = new; 
} 
 
/*初始化输出文件*/ 
void outFile(char *outfile) 
{ 
  if((out=fopen(outfile,"w"))==NULL) 
  { 
    printf("\nCan not open output file!\n"); 
    exit(0); 
  } 
} 
 
void output(int f) 
{ 
    int i; 
    char *rec; 
    rec=token; 
 
    if(f==0) 
    { 
        for(i=0;i<31;i++) 
        { 
            if(strcmp(keyword[i],rec)==0) 
            { 
                printf("Line %d : ",lineno); 
                fprintf(out,"Line %d : ",lineno); 
                printf("( IDN , %s )\n",rec); 
                fprintf(out,"( IDN , %s )\n",rec); 
                addToEntry(0,rec); 
                rec=""; 
                return; 
            } 
        } 
        printf("Line %d : ",lineno); 
        fprintf(out,"Line %d : ",lineno); 
        printf("( id , %s )\n",token); 
        fprintf(out,"( id , %s )\n",token); 
        addToEntry(1,rec); 
        return; 
    } 
    else if(f==1) 
    { 
        printf("Line %d : ",lineno); 
        fprintf(out,"Line %d : ",lineno); 
        printf("( num , %s )\n",token); 
        fprintf(out,"( num , %s )\n",token); 
    } 
    else if(f==2) 
    { 
        printf("Line %d : ",lineno); 
        fprintf(out,"Line %d : ",lineno); 
        printf("( op , %s )\n",token); 
        fprintf(out,"( op , %s )\n",token); 
    } 
} 
 
void analyse(char *infile) 
{ 
    FILE *fp; 
    char recieve; 
    char ch='#'; 
 
    int forward = -1; 
 
    int temp,temp1; 
 
    int pointer=0; 
 
    if((fp=fopen(infile,"r"))==NULL) 
    { 
        printf("\nCan not open output file!\n"); 
        exit(0); 
    } 
 
 
    do 
    { 
        recieve = fgetc(fp); 
        Buffer[pointer] = recieve; 
        pointer++; 
        if(pointer==127) 
        { 
            Buffer[pointer] = EOF; 
            break; 
        } 
    }while(recieve!=EOF);              /*初始装入第一部分*/ 
 
    while(1) 
    { 
        forward = forward + 1; 
 
        if(Buffer[forward] == EOF) 
        { 
            if(forward==127) 
            { 
                /*重装第二部分*/ 
                pointer = 128; 
                do 
                { 
                    recieve = fgetc(fp); 
                    Buffer[pointer] = recieve; 
                    pointer++; 
                    if(pointer==255) 
                    { 
                        Buffer[pointer] = EOF; 
                        break; 
                    } 
                }while(recieve!=EOF); 
 
                forward = forward + 1; 
            } 
            else if(forward==255) 
            { 
                /*重装第一部分*/ 
                pointer = 0; 
                do 
                { 
                    recieve = fgetc(fp); 
                    Buffer[pointer] = recieve; 
                    pointer++; 
                    if(pointer==255) 
                    { 
                        Buffer[pointer] = EOF; 
                        break; 
                    } 
                }while(recieve!=EOF); 
 
                forward = 0; 
            } 
            else 
            { 
                /*终止词法分析*/ 
                break; 
            } 
        } 
 
        switch(state) 
        { 
            case 0: ch = Buffer[forward]; 
                    if(ch==' '||ch=='\t') 
                        state = 0; 
                    else if(ch=='\n') 
                    { 
                        lineno++; 
                        state = 0; 
                    } 
                    else if(isalpha(ch)) 
                    { 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                        state=1; 
                    } 
                    else if(isdigit(ch)) 
                    { 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                        state=2; 
                    } 
                    else if(ch=='#'||ch=='('||ch==')'||ch=='['||ch==']'||ch=='{'||ch=='}'||ch=='.'||ch=='\\' 
                        ||ch==';'||ch=='\''||ch=='?'||ch=='"'||ch=='%'||ch==','||ch==':') 
                    { 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                        flag=2; 
                        token[index]='\0'; 
                        index++; 
                        output(flag); 
                        state=0; 
                    } 
                    else if(ch=='/') 
                    { 
                        state=3; 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                    } 
                    else if(ch=='+'||ch=='-'||ch=='*'||ch=='>'||ch=='<'||ch=='='||ch=='!') 
                    { 
                        state=5; 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                    } 
                    else if(ch=='|') 
                    { 
                        state=11; 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                    } 
                    else if(ch=='&') 
                    { 
                        state=12; 
                        index=0; 
                        token[index]=ch; 
                        index++; 
                    } 
                    else 
                    { 
                        printf("Unprocessed char is %c\n",ch); 
                        fprintf(out,"Unmatched char is %c\n",ch); 
                        state = 0; 
                    } 
             break; 
 
             case 1: ch = Buffer[forward]; 
                     if(isalnum(ch)) 
                     { 
                         token[index]=ch; 
                         index++; 
                         state = 1; 
                     } 
                     else 
                     { 
                         state = 0; 
                         token[index]='\0'; 
                         index++; 
                         flag=0; 
                         output(0); 
                         forward = forward - 1; 
                     } 
             break; 
             case 2: ch = Buffer[forward];                               /*寻找常数*/ 
                     if(isdigit(ch)) 
                     { 
                        token[index]=ch; 
                        index++; 
                        state=2; 
                     } 
                     else if(ch=='.') 
                     { 
                        state=6; 
                     } 
                     else{ 
                        state=0; 
                        forward = forward - 1; 
                        token[index]='\0'; 
                        index++; 
                        flag=1; 
                        output(flag); 
                     } 
             break; 
             case 3: ch = Buffer[forward];                            /*寻找注释符的前半部分*/ 
                     if(ch=='*') 
                     { 
                        state=4; 
                     } 
                     else if(ch=='=') 
                     { 
                        state=0; 
                        token[index]=ch; 
                        index++; 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                     } 
                     else{ 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                        state=0; 
                        forward = forward - 1; 
                     } 
             break; 
             case 4: ch = Buffer[forward]; 
                     temp = forward - 1; 
                     if(ch!='/')                                       /*寻找注释符后半部分*/ 
                        state=4; 
                     else{ 
                        if(Buffer[temp]=='*') 
                            state=0; 
                        else{ 
                            printf("Remark symbol error!\n"); 
                            state=0; 
                        } 
                     } 
             break; 
             case 5: ch = Buffer[forward]; 
                     if(ch=='=') 
                     { 
                        state=0; 
                        token[index]=ch; 
                        index++; 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                     } 
                     else if(ch=='+') 
                     { 
                        state=0; 
                        token[index]=ch; 
                        index++; 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                     } 
                     else if(ch=='-') 
                     { 
                        state=0; 
                        token[index]=ch; 
                        index++; 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                     } 
                     else{ 
                        token[index]='\0'; 
                        index++; 
                        flag=2; 
                        output(flag); 
                        state=0; 
                        forward = forward - 1; 
                     } 
             break; 
             case 6: ch = Buffer[forward]; 
                     temp = forward - 1; 
                     if(isdigit(ch)) 
                     { 
                         token[index]=Buffer[temp];                   /*将'.'放入token*/ 
                         index++; 
                         token[index]=ch;                         /*将该数字放入token*/ 
                         index++; 
                         state=7; 
                     } 
                     else{ 
                         token[index]='\0';                       /*输出前面的数字*/ 
                         index++; 
                         flag=1; 
                         output(flag); 
             
                         index=0;                                 /*输出'.'*/ 
                         token[index]=Buffer[temp]; 
                         token[index]='\0'; 
                         index++; 
                         flag=2; 
                         output(flag); 
 
                         forward = forward - 1; 
                         state=0; 
                     } 
             break; 
             case 7: ch = Buffer[forward]; 
                     if(isdigit(ch)) 
                     { 
                         state=7; 
                         token[index]=ch; 
                         index++; 
                      } 
                      else if(ch=='E'||ch=='e'){                  /*找到表示指数的E或e*/ 
                         state=8; 
                         temp=forward;                        /*temp用于保存指向E或e的指针*/ 
                      } 
                      else{ 
                         token[index]='\0'; 
                         index++; 
                         flag=1; 
                         output(flag); 
                         state=0; 
                         forward = forward - 1; 
                      } 
             break; 
             case 8: ch = Buffer[forward]; 
          /*temp1=q;*/ 
                     if(ch=='+'||ch=='-')                        /*如果E或e后面跟着+或-*/ 
                     { 
                         temp1=forward;                      /*用temp1保存指向+或-的指针*/ 
                         state=9; 
                     } 
                     else if(isdigit(ch)){                       /*如果E或e后面跟着一个数字*/ 
                         state=10; 
                         token[index]=Buffer[temp];              /*将E或e放入token*/ 
                         index++; 
                         token[index]=ch;                      /*将该数字放入token*/ 
                         index++; 
                     } 
                     else{                                       /*如果E或e后面跟着其他字符*/ 
                         token[index]='\0';                    /*输出前面的数*/ 
                         index++; 
                         flag=1; 
                         output(flag); 
             
                         index=0;                              /*将E或e放入token,回退字符,转入状态1*/ 
                         token[index]=Buffer[temp]; 
                         index++; 
                         forward = forward - 1; 
                         state=1;                              /*转入状态1,判断字符串*/ 
                     } 
             break; 
             case 9: ch = Buffer[forward]; 
                     if(isdigit(ch))                            /*若E或e后面的+或-的后面跟一个数字*/ 
                     { 
                         token[index]=Buffer[temp];             /*将E或e和+或-放入token*/ 
                         index++; 
            /*printf("\ntemp is %c\n",temp->ch);*/ 
                         token[index]=Buffer[temp1]; 
                         index++; 
            /*printf("\ntemp1 is %c\n",temp1->ch);*/ 
                         token[index]=ch;                     /*将该数字放入token*/ 
                         index++; 
                         state=10;                            /*转入状态10*/ 
                     } 
                     else{ 
                         token[index]='\0';                    /*输出前面的数*/ 
                         index++; 
                         flag=1; 
                         output(flag); 
             
                         index=0;                              /*输出E或e*/ 
                         token[index]=Buffer[temp]; 
                         index++; 
                         token[index]='\0'; 
                         index++; 
                         flag=0; 
                         output(flag); 
 
                         index=0; 
                         token[index]=Buffer[temp1];           /*将+或-放入token*/ 
                         index++; 
                         if(ch=='=')                           /*判断+=或-=*/ 
                         { 
                             token[index]=ch; 
                             index++; 
                             token[index]='\0'; 
                             index++; 
                             flag=2; 
                             output(flag); 
                             state=0; 
                         } 
                         else{ 
                             token[index]='\0'; 
                             index++; 
                             flag=2; 
                             output(flag); 
                             forward = forward - 1; 
                             state=0; 
                         } 
                     } 
             break; 
             case 10: ch = Buffer[forward]; 
                      if(isdigit(ch)) 
                      { 
                         token[index]=ch; 
                         index++; 
                         state=10; 
                      } 
                      else{ 
                         token[index]='\0'; 
                         index++; 
                         flag=1; 
                         output(flag); 
                         forward = forward - 1; 
                         state=0; 
                     } 
             break; 
             case 11: ch = Buffer[forward]; 
                      if(ch=='|') 
                      { 
                         token[index]=ch; 
                         index++; 
                         token[index]='\0'; 
                         index++; 
                         flag=2; 
                         output(flag); 
                         state = 0; 
                      } 
                      else 
                      { 
                         token[index]='\0'; 
                         index++; 
                         flag=1; 
                         output(flag); 
                         forward = forward - 1; 
                         state=0; 
                      } 
              break; 
              case 12: ch = Buffer[forward]; 
                       if(ch=='&') 
                       { 
                         token[index]=ch; 
                         index++; 
                         token[index]='\0'; 
                         index++; 
                         flag=2; 
                         output(flag); 
                         state = 0; 
                       } 
                       else 
                      { 
                         token[index]='\0'; 
                         index++; 
                         flag=1; 
                         output(flag); 
                         forward = forward - 1; 
                         state=0; 
                      } 
              break; 
        } 
    } 
 
    printf("\nThe end!\nThe number of lines in this source file is %d.\n",lineno-1); 
    fprintf(out,"\nThe end!\nThe number of lines in this source file is %d.\n",lineno-1); 
 
    fclose(fp); 
} 
 
void print() 
{ 
    struct entry *q; 
    q=headOfEntry; 
    printf("The followed is symbol list:\n"); 
    fprintf(out,"The followed is symbol list:\n"); 
    while(q->next!=NULL) 
    { 
        printf("(%d,%s)\n",q->next->attr,q->next->value); 
        fprintf(out,"(%d,%s)\n",q->next->attr,q->next->value); 
        q=q->next; 
    } 
} 
 
 
main() 
{ 
    char *in; 
    char *outf; 
 
    printf("Enter the name of Source file:\n"); 
    scanf("%s",in); 
    printf("Enter the name of output file:\n"); 
    scanf("%s",outf); 
 
    entryinit(); 
 
    outFile(outf); 
    analyse(in); 
    print(); 
    fclose(out); 
    getch(); 
}