阴漾吧 关注:2贴子:30
  • 5回复贴,共1

【编译】词法分析器

只看楼主收藏回复

主程序 yang95.c 如下:


#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<ctype.h>
#define null 0

int i,j,flag,status,count,id,row=1;
char ch,*tmpStr='\0';
char words[10] = {" "}; 
char program[1000];
FILE *input,*output,*fpReserver,*fpCal,*fpSep;

int Scan(char program[]){
  flag=-1;
  j=0;
  ch=program[i++];

  if((ch==' ')||(ch=='\n'||(ch=='\t'))&&ch!=EOF) {
    if(ch=='\n')
        row++;
    Scan(program);
  }
  else{
    /*判断是否保留字*/
    if((ch>='a')&&(ch<='z')){
        while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9'))){
            words[j++]=ch;
            ch=program[i++];
        }
        i--;
        words[j++]='\0';

        /*打开关键字文件*/
        if((fpReserver=fopen("keywords.txt","r"))==NULL){
            printf("file open in readonly mode,but an error generate!\n");
            exit(0);
        }
        while(fscanf(fpReserver,"%s",tmpStr)!=EOF)
          if(strcmp(words,tmpStr)==0){
            fclose(fpReserver);
            id++;
            flag=1;
            break;
          }
        fclose(fpReserver);
        if(flag==-1){
            id++;
            flag=2;
        }
    }/*end:判断是否保留字*/

    /*识别数字*/
    else if(isdigit(ch)){
        while(isdigit(ch)){/*都为数字时*/
            words[j++]=ch;
            ch=program[i++];
        }
        if(ch=='.'){ /*第一个小数点时  加入  且读取下一个字符*/
            words[j++]=ch;
            ch=program[i++];
            if(isdigit(ch)){
                while(isdigit(ch)){/*小数点后是数字 则加入,读取下一个*/
                    words[j++]=ch;
                    ch=program[i++];
                }
                if(isalpha(ch)||(ch=='.')){/*如:22.2后面又出现小数点或字母*/
                    words[j++]=ch;
                    ch=program[i++];
                    while(isalpha(ch)||isdigit(ch)||ch=='.'){
                        words[j++]=ch;
                        ch=program[i++];
                    }
                    words[j]='\0';
                    id++;
                    flag=0;
                }
                else{/*数字、其他字符或结束符时,则为数据*/
                    words[j]='\0';
                    id++;
                    flag=3;
                }
            }
            else{/*小数点后不是数字*/
                while((ch!=' '&&ch!='\t'&&ch!='\n')&&ch!=EOF){
                    words[j++]=ch;
                    ch=program[i++];
                }
                words[j]='\0';
                id++;
                flag=0;
            }
        }
        else if(isalpha(ch)){ /*数字后是字母*/
            while(isdigit(ch)||isalpha(ch)||ch=='.'){
                words[j++]=ch;
                ch=program[i++];
            }
            words[j]='\0';
            id++;
            flag=0;
        }
        else if(!isalpha(ch)||ch!='.'){/*都为数字*/
            words[j]='\0';
            id++;
            flag=3;
        }
        i--;
    }/*end判断是否数字*/

    /*判断是否运算符*/



1楼2008-05-21 18:37回复
        else switch(ch){
            case '=':{
                if (ch == '=')
                    words[j++] = ch;
                words[j] = '\0';
                ch = program[i++];
                if (ch == '='){
                    words[j++] = ch;
                    words[j] = '\0';
                }
                else {
                    i--;
                }
                id++;
                flag=4;
                break;
            }
            case'+':{
                if (ch == '+')
                    words[j++] = ch;
                words[j] = '\0';
                ch = program[i++];
                if (ch == '='){
                    words[j++] = ch;
                    words[j] = '\0';
                }
                else if (ch == '+'){
                    words[j++] = ch;
                    words[j] = '\0';
                }
                else{
                    i--;
                }
                id++;
                flag=4;
                break;
            }
            case'-':{
                if (ch == '-')
                    words[j++] = ch;
                words[j] = '\0';
                ch = program[i++];
                if (ch == '='){
                    words[j++] = ch;
                    words[j] = '\0';
                }
                else if( ch == '-'){
                    words[j++] = ch;
                    words[j] = '\0';
                }
                else{
                    i--;
                }
                id++;
                flag=4;
                break;
            }
            case'*':{
                if (ch == '*')
                    words[j++] = ch;
                words[j] = '\0';
                ch = program[i++];
                if (ch == '='){
                    words[j++] = ch;
                    words[j] = '\0';
                    flag=4;
                }
                else if (ch == '/'){
                    words[j++] = ch;
                    words[j] = '\0';
                    flag=5 ;
                }
                else{
                    i--;
                    flag=4;
                }
                id++;
                break;
            }
            case'/':{
                /*if (ch == '/')*/
                    words[j++] = ch;
                words[j] = '\0';
                ch = program[i++];
                if (ch == '='){
                    words[j++] = ch;
                    words[j] = '\0';
                    flag=4;
                }
                else if (ch == '*'){
                    words[j++] = ch;
                    words[j] = '\0';
                    ch=program[i++];
                    flag=5;
                    while(ch!='*')
                        ch=program[i++];
                    i--;
                }
                else if(ch=='/'){
                    words[j++] = ch;
                    words[j] = '\0';
                    flag=0;
                }
                else{
                    i--;
                    flag=4;
                }
                id++;
                break;
            }
            case '>': case '<':{
                if((ch=='<')||(ch=='>')){
                    words[j++]=ch;
                }
                words[j]='\0';
                ch=program[i++];
                if(ch=='='){
                    words[j++]=ch;
                    words[j]='\0';
                }
                else
                    i--;
                id++;
                flag=4;
                break;
            } /*end:运算符 < > <= >=*/
            case '!':{
                if(ch=='!'){
                    words[j++]=ch;
                }
                words[j]='\0';
                ch=program[i++];
                if(ch=='='){
                    words[j++]=ch;
                    words[j]='\0';
                    id++;
                    flag=4;
                }/*!=*/
                else{
                    i--;/*没有这句,'!='不会出现*/
                    id++;
                    flag=0;
                }
                break;
            } /*end:运算符 != */
            case ',':case ';':case '{':case '}':case '(':case ')':{
                words[j++]=ch;
                words[j]='\0';
                ch=program[i];
                id++;
                flag=5;
                break;
            }/*end:分隔符 */
            case -1:{
                flag=-1;
                break;
            }/*一定要加这句 否则死循环*/
            default:{
                words[j++]=ch;
                words[j]='\0';
                id++;
                flag=0;
                break;
            }/* 其他符号*/
        }/*end:switch*/
      }/*end:else*/
      return flag;/*注意要放对位子*/
    }


    main() 
    {
        i=0;
        if((input=fopen("myInput.txt","r"))==null){
            printf("不能读取文件!");
            exit(0);
        }
        if((output=fopen("myOutput.txt","w+"))==null){
            printf("输出文件建立错误!");
            exit(0);
        }
        ch=fgetc(input);

        if((ch==' '||ch=='\n'||ch=='\t')&&ch!=EOF){
            if(ch=='\n')
                row++;
            ch=fgetc(input);
        }
        program[i++]=ch;

        do{
            ch=fgetc(input);
            program[i++]=ch;
        }while(ch!=EOF);
        program[i--]='\0';
        i=0;
        do{
            flag=Scan(program);
            if(flag==0)
                fprintf(output," %d  \t%d \t( error,\t' %s '\t)\n",row,id,words);
            else if(flag!=-1)
                fprintf(output," \t %d \t( %d,\t' %s '\t)\n",id,flag,words);
        }while (flag != -1) ;
        fclose(input);
        fclose(output);
    }


    2楼2008-05-21 18:37
    回复
      存放保留字的文件 keywords.txt的内容如下:


      auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if while static


      3楼2008-05-21 18:38
      回复
        假设输入文件 myInput.txt 内容如下:



        void main()/*yang*/
        {

        int a1,a2;
        a1+=22.2;@
        }


        4楼2008-05-21 18:39
        回复
          则 输出文件 MYOUTPUT.txt内容如下:


             1  ( 1, ' void ' )
             2  ( 2, ' main ' )
             3  ( 5, ' ( ' )
             4  ( 5, ' ) ' )
             5  ( 5, ' /* ' )
             6  ( 5, ' */ ' )
             7  ( 5, ' { ' )
             8  ( 1, ' int ' )
             9  ( 2, ' a1 ' )
             10  ( 5, ' , ' )
             11  ( 2, ' a2 ' )
             12  ( 5, ' ; ' )
             13  ( 2, ' a1 ' )
             14  ( 4, ' += ' )
             15  ( 3, ' 22.2 ' )
             16  ( 5, ' ; ' )
           6  17  ( error, ' @ ' )
             18  ( 5, ' } ' )


          5楼2008-05-21 18:40
          回复
            提示:yang95.c、keywords.txt、myInput.txt三个文件必须在同一个文件夹中,且最好不要置于桌面上


            6楼2008-05-21 18:41
            回复