[编译原理课程设计] 程序示例一、词法分析器

#include<string.h>
#include<stdio.h>
#define   MAX 22             /*分析表的最大容量*/
#define   RES_MAX   10        /*关键字的最大长度*/
#define   MAXBUF 255         /*缓冲区的大小*/
char   ch =' ';              /*存放读入当前的输入字符*/
int Line_NO;                /*纪录行号*/

struct reserve    /*关键字*/
{
char lexptr[MAXBUF];
int token;
};

struct reserve symtable[MAX];
char str[MAX][10]={"program","begin","end","var","integer","real", "for","if","then","else","do","while","array","procedure", "function","of","boolean","const","div","mod","and","or"};


void init()      /*对关键字表进行初始化,div,mod,and,or也作为关键字处理*/
{                /*最小的token是program:3,最大的token是or:24*/
int j;
for(j=0; j<MAX; j++)
{
   strcpy(symtable[j].lexptr,str[j]);
   symtable[j].token=j+3;   
}
}

/***************对关键字进行搜索**************/
int se_res(char * is_res){
   int i;
   for(i=0;i<MAX;i++){
     if((strcmp(symtable[i].lexptr,is_res))==0) break;
   }
   if(i<MAX) return   symtable[i].token;
   else return 0;
}

/*****************判断是否为字母*****************/
int IsLetter(char c)
{
    if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;
    else return 0;
}
/*************判断是否为数字**************/
int IsDigit(char c){
   if(c>='0'&c<='9') return 1;
   else return 0;
}

/***************分析程序**************/
void analyse(FILE *fpin,FILE *fpout){
    char arr[MAXBUF];       /* 输入缓冲区,存放一个单词符号 */
    int j=0;

    while((ch=fgetc(fpin))!=EOF){
    if(ch==' '||ch=='/t'){}                    /*碰到空格、tab则跳过*/
    else if(ch=='/n'){Line_NO++;}
/*************************字符串的处理****************************/
   else if(IsLetter(ch)){
       while(IsLetter(ch)|IsDigit(ch)){
            if((ch<='Z')&&(ch>='A'))     ch=ch+32;   /*忽略大小写*/
                  arr[j]=ch;
                  j++;
                  ch=fgetc(fpin);
        }
        fseek(fpin,-1L,SEEK_CUR);   /*输入指针回退一个字符*/
        arr[j]='/0';
        j=0;
       if (se_res(arr)){   /*如果是关键字*/
                 fprintf(fpout,"%s/t/t%d/n",arr,se_res(arr));
        }else   fprintf(fpout,"%s/t/t%d/n",arr,1);    /*普通标识符*/
/*************************数字的处理****************************/      
   }else if(IsDigit(ch)){
      while(IsDigit(ch)){
                         arr[j]=ch;
                         j++;
                         ch=fgetc(fpin);
        }
        fseek(fpin,-1L,SEEK_CUR);
        arr[j]='/0';
        j=0;
        fprintf(fpout,"%s/t/t%d/n",arr,2) ;     /*无符号整数*/
      }else switch(ch){           
               case'+' :fprintf(fpout,"%s/t/t%d/n","+",41);break;
               case'-' :fprintf(fpout,"%s/t/t%d/n","-",42);break;
               case'*' :fprintf(fpout,"%s/t/t%d/n","*",43);break;
               case'(' :fprintf(fpout,"%s/t/t%d/n","(",25);break;
               case')' :fprintf(fpout,"%s/t/t%d/n",")",26);break;
               case'[' :fprintf(fpout,"%s/t/t%d/n","[",27);break;
               case']' :fprintf(fpout,"%s/t/t%d/n","]",28);break;                      
               case';' :fprintf(fpout,"%s/t/t%d/n",";",36);break;
               case'=' :fprintf(fpout,"%s/t/t%d/n","=",38);break;
               case'.' :fprintf(fpout,"%s/t/t%d/n",".",39);break;
               case',' :fprintf(fpout,"%s/t/t%d/n",",",40);break;
                 
               case':' :{ch=fgetc(fpin);
         if(ch=='=') fprintf(fpout,"%s/t/t%d/n",":=",29);
               else {fprintf(fpout,"%s/t/t%d/n",":",30);fseek(fpin,-1L,SEEK_CUR);}
                 }break;

               case'>' :{ch=fgetc(fpin);
         if(ch=='=') fprintf(fpout,"%s/t/t%d/n",">=",30);
                         else {fprintf(fpout,"%s/t/t%d/n",">",31);fseek(fpin,-1L,SEEK_CUR);}
                         }break;

               case'<' :{ch=fgetc(fpin);
         if(ch=='=') fprintf(fpout,"%s/t/t%d/n","<=",34);
         else if(ch=='>') fprintf(fpout,"%s/t/t%d/n","<>",35);
                         else{fprintf(fpout,"%s/t/t%d/n","<",33);fseek(fpin,-1L,SEEK_CUR);}
                        }break;

   /***************出现在{ }之间的全部作为注释部分处理*******************/  
               case'{' :{ch=fgetc(fpin);
       while(ch!='}'&&ch!=EOF)   {ch=fgetc(fpin);}
         if(ch==EOF) fprintf(fpout,"缺少一个'}'");
                        }break;
   /***************非法字符*******************/                         
               default :fprintf(fpout,"在第%d行无法识别的字符/t%c/n",Line_NO,ch);
        }
    }
}


/**********主程序中完成对输入输出文件的读写***********/
void main(){
   char in_fn[25],out_fn[25];
   FILE * fpin,* fpout;
   printf("//chi fa fen xi qi/n");
   printf("input the input file exmaple:fin.txt:/n");
   scanf("%s",in_fn);
   printf("input the output file exmaple:fout.txt:/n");
   scanf("%s",out_fn);
   fpin=fopen(in_fn,"r");
   fpout=fopen(out_fn,"w");
   init();
   analyse(fpin,fpout);
   fclose(fpin);
   fclose(fpout);
}

#

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验一:词法分析程序 一、实验目的     通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的类型码及单词符号的自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 二、实验要求 用C或C++写一个简单的词法分析程序程序可以满足下列要求: 1、能分析如下几种简单的语言词法 (1) 标识符: ID=letter(letter|digit)* (2) 关键字(全部小写) main int float double char if then else switch case break continue while do for (3)整型常量:NUM=digit digit* (4)运算符 = + - * / < <= == != > >= ; ( )? : (5)空格由空白、制表符和换行符组成,用以分隔ID、NUM、运算符等,字符分析时被忽略。 2、单词符号和相应的类别码 假定单词符号和相应的类别码如下: 单词符号 种别码 int 1 = 17 float 2 < 20 if 3 <= 21 switch 4 == 22 while 5 != 23 Do 6 > 24 标识符 10 >= 25 整型常量 11 ; 26 + 13 ( 27 - 14 ) 28 * 15 ? 29 / 16 : 30 3、词法分析程序实现的功能 输入:单词序列(以文件形式提供),输出识别的单词的二元组序列到文件和屏幕 输出:二元组构成: (syn,token或sum) 其中: syn 为单词的种别码 token 为存放的单词自身符号串 sum 为整型常数 例: 源程序: int ab; float ef=20; ab=10+ef; 输出: (保留字--1,int) (标识符--10,ab) (分号--26,;) (保留字--2,float) (标识符--10,ef) (等号--17,=) (整数--11,20) (分号--26,;) (标识符--10,ab) (等号--17,=) (整数--11,10) (加号--13,+) (标识符--10,ef) (分号--26,;) 4、自己准备测试数据存放于TestData.txt文件中,测试数据中应覆盖有以上5种数据,测试结果要求以原数据与结果对照的形式输出并保存在Result.txt中,同时要把结果输出到屏幕。 5、提前准备 ① 实验前,先编制好程序,上机时输入并调试程序。 准备好多组测试数据(存放于文件TestData.txt中)。 6、写出实验报告 报告格式:要求有实验名称、实验目的、实验要求、实验内容、实验小结。 其中实验内容包括算法分析、程序流程图及程序代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值