⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 词法分析2.txt

📁 编译原理的词法分析实验
💻 TXT
字号:
编译原理——词法分析代码2007-05-27 17:59#include<stdio.h>
#include<malloc.h>
struct struCH
{        char               ch;
   struct             struCH *next;
}struCH,*temp,*head,*shift,*top,*base;
FILE              *fp;
char               curchar;         /*存放当前待比较的字符*/
char               curtocmp;      /*存放当前栈顶的字符*/
char               ch;
int                  right, i,j;
int table[5][9]={                 /*存储预测分析表,1为有产生式,0为无*/
                     {1,0,0,0,0,1,0,0,0},
                      {0,1,1,0,0,0,1,1,1},
                      {1,0,0,0,0,1,0,0,0},
                      {0,1,1,1,1,0,1,1,1},
                      {1,0,0,0,0,1,0,0,0}};
void main(int argc,char *argv[]){
        void puch(char ch);
        void pop();
        void doforpush(int t);
        void identify();
        int errnum=0, k=0, countchar=0, rownum;
        int m=0;
        int charerr=0;   /*有非法字符时的开关控制量*/
        /*******************以只读方式打开文件*********************/
        argv[1]="exp.txt";
        if((fp=fopen(argv[1],"r"))==NULL){
               printf("\n\tCan not open file %s,or not exist it!\n",argv[1]);
               exit(0);      /*文件不存在or打不开时,正常退出程序*/
        }
        else printf("\n\tSuccess open file: %s\n",argv[1]);        /*成功打开文件*/
        /******************遍历整个文件检测是否有非法字符********************/
        /*如果用while(!feof(fp))语言,将会多出一个字符而难以控制,
         *所以这里采用先计算字符数量再遍历整个文件来检测其否有非法字符*/
        /*[1]计算文件中字符数量*/
        while(!feof(fp)){
               ch=getc(fp);           /*这里只是让指针往前移*/
               countchar++;         /*统计文件中的字符数(包括换行符及文件结束符)*/
        }
        rewind(fp);                    /*将fp文件指针重新指向文件头处,以备后面对文件的操作*/
        if(countchar==0){         /*空文件*/
               printf("\t%s is a blank file!\n",argv[1]);
               exit(0);                   /*正常退出本程序*/
        }
        /*[2]开始遍历文件*/
        while(k<(countchar-1)){/*加换行符后countchar仍多一个,故减1*/
               ch=getc(fp);
        if(!(ch=='('||ch==')'||ch=='i'||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#'||ch=='\n')){
                      charerr=1;errnum++;/*charerror出错标记,errnum统计出错个数*/
               }
               k++;
        }
        rewind(fp);             /*将fp文件指针重新指向文件头处,以备后面的建链表操作*/
        if(charerr==1){      /*文件中有非法字符*/
               printf("\n\t%d Unindentify characters in file %s \n",errnum,argv[1]);
              exit(0);            /*正常退出本程序*/
        }
        /*******************非空且无非法字符,则进行识别操作*****************/
        for(rownum=1;m<(countchar-1);rownum++){     /*识别所有行,rownum记录行号*/
               /* 初始变量及堆栈和 */
              right=1;
               /* '#''E'进栈 */
               base=malloc(sizeof(struCH));    /*初始化堆栈*/
               base->next=NULL;
               base->ch='#';
               temp=malloc(sizeof(struCH));
               temp->next=base;
               temp->ch='E';
               top=temp;                                /*栈顶指针top指向栈顶*/
              /*初始存放待识别的表达式的线性链表头*/
               shift=malloc(sizeof(struCH));
               shift->next=NULL;
               head=shift;
               /*读取一行形成线性链表*/
               ch=getc(fp);putchar(ch);m++;
               while(ch!='\n'&&m<(countchar)){ /*行末or到文件尾。最后会读取文件结束符*/
                      /*读取ch,读取存入链*/
                      temp=malloc(sizeof(struCH));
                      temp->ch=ch;
                      temp->next=NULL;
                      shift->next=temp;
                      shift=shift->next;
                      ch=getc(fp);
                      if(m!=(countchar-1)) putchar(ch);   /*不输出最后一次读取的文件结束符*/
                      m++;
               }
               head=head->next;         /*消去第一个空头结点,并使head指向非空线性链表头*/
               shift=head;                    /*shift指向头结点,以便后面识别操作*/
               putchar('\n');
               identify();                      /*开始识别一行*/
               if(!right)                        /*错误提示:[文件名] Line [行号]:error                    expression!*/
                      printf("%s   Line %d:\t   error expression!\n",argv[1],rownum);
               else                               /*正确提示:[文件名] Line [行号]:right                  expression!*/
                      printf("%s   Line %d:\t   right expression!\n",argv[1],rownum);
               putchar('\n');
        }/*end for*/
        printf("Completed!\n");
        fclose(fp);       /*关闭文件*/
        exit(0);            /*正常退出程序*/
}
/*入栈函数*/
void push(char ch){
        temp=malloc(sizeof(struCH));
        temp->ch=ch;
        temp->next=top;
        top=temp;
}
/*出栈函数*/
void pop(void){
        curtocmp=top->ch;
        if(top->ch!='#')
               top=top->next;
}
/*根据数组下标计算的值找对应的产生式,并入栈*/
void doforpush(int t){
        switch(t){
               case 0:push('A');push('T');break;
               case 5:push('A');push('T');break;
               case 11:push('A');push('T');push('+');break;
               case 12:push('A');push('T');push('-');break;
               case 20:push('B');push('F');break;
               case 25:push('B');push('F');break;
               case 33:push('B');push('F');push('*');break;
               case 34:push('B');push('F');push('/');break;
               case 40:push('i');break;
               case 45:push(')');push('E');push('(');
        }
}
/*根据curchar,curtocmp转为数字以判断是否有产生式*/
void changchartoint()
{
        switch(curtocmp)           /*非终结符:栈顶*/
        {
               case 'A':i=1;break;
               case 'B':i=3;break;
               case 'E':i=0;break;
               case 'T':i=2;break;
               case 'F':i=4;
        }
        switch(curchar)              /*终结符:待识别的表达式中*/
        {
               case 'i':j=0;break;
               case '+':j=1;break;
               case '-':j=2;break;
               case '*':j=3;break;
               case '/':j=4;break;
               case '(':j=5;break;
               case ')':j=6;break;
               case '#':j=7;
        }
}
/*识别算法函数*/
void identify()
{
        int t;
        for(;;)
        {
               pop();                                   /*读取栈顶的字符存curtocmp中*/
               curchar=shift->ch;                 /*读取链中的一个字符存curchar*/
               printf("\t%c-->%c\n",curchar,curtocmp);
               if(curtocmp=='#' && curchar=='#')                      break;
               if(curtocmp=='A'||curtocmp=='B'||curtocmp=='E'||curtocmp=='T'||curtocmp=='F'){
                      if(curtocmp!='#'){          /*[1]未到栈底时,匹配字符*/
                             changchartoint();
                             if(table[i][j]){                 /*[1.1]有产生式*/
                                    t=10*i+j;                /*计算产生式在数组中的位置*/
                                    doforpush(t);          /*找对应t的产生式,并入栈*/
                                    continue;
                             }
                             else{                              /*[1.2]没有产生式*/
                                    right=0;                   /*出错*/
                                    break;
                             }
                      }
                      else{                                /*[2]到栈底,当前比较字符为'#'*/
                             if(curtocmp!=curchar){ /*输入行中最后一字符非'#'*/
                                    right=0;                  /*出错*/
                                    break;
                             }
                             else
                                    break;                    /*正确*/
                      }
               }
               else{        /*若当前字符为终结符*/
                      if(curtocmp!=curchar){
                             right=0;                       /*出错*/
                             break;
                      }
                      else{
                             shift=shift->next;         /*读取下一个字符*/
                             continue;
                      }
               }
        }/*end for*/
 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -