编译原理(实验二)词法分析程序实验

一、实验目的: 加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。   二、实验内容: 1.要识别的词素: (1)保留字或关键字:如:BEGIN、 END、VAR、INTEGER、REAL、 IF、 THEN、READ、WRITE、WHILE。 (2)运算符: 如:+、-、*、/、:=、=、>、<、>=、<= (3)标识符: 用户定义的变量名、常数名、过程名 (4)常数:   如:10、25、100、2.3等整数或实数 (5)界符:   如:‘,’、‘.’ 、‘;’ 、‘(’ 、‘)’、‘{’、‘}’,‘:’ 2.词法分析过程所要完成的任务: (1)从源程序读字符(getch) (2)滤空格 (3)识别保留字 (4)识别标识符 (5)拼数 (6)拼复合词(如:=) (7)输出源程序的token(词法单元)序列。     三、实验要求:
  1. 对单词的构词规则有明确的定义;
  2. 编写的分析程序能够正确识别源程序中的单词符号;
  3. 识别出的单词以<类别码,值>的形式保存并输出;
  4. 实验报告要求用自动机对词法定义做出详细说明,并给出词法分析程序的工作流程图。
  四、实验步骤: 1.先画出识别不同词素的自动机,再将其组合成一个大的自动机; 2.画出词法分析程序的工作流程图,编写程序。
  1. 依次读入源程序符号,对源程序进行词素识别,直到源程序结束;
  2. 对正确的单词,按照它的种别以<类别码,值>的形式输出;
  五、我的代码
  1. #include <stdio.h>
  2. #include <string.h>
  3. char str[80],token[8];
  4. char ch;
  5. int syn,p,m=0,n,sum=0;
  6. double small = 0;
  7. char *tab[10] = {"begin","end","var","integer","real","if","then","read","write","while"};
  8. /**
  9.   *整数 1
  10.   *小数 2
  11.   *字符串 3
  12.   * begin 10    end 11     var 12     integer 13        real 14
  13.   * if    15    then 16    read 17    write   18     while 19
  14.   * + 20     -  21      *  22      /  23      :=  24       =   25
  15.   * > 26     <  27      >=  28       <=   29
  16.   * ,   30      .   31        ;  32       (  33      ) 34
  17.   * {    35     }  36     :  37
  18.   */
  19. void scaner() {
  20.     for(n=0; n<8; n++) token[n]=NULL;
  21.     ch=str[p++];
  22.     while(ch==' ') {
  23.         ch=str[p];
  24.         p++;
  25.     }
  26.     //关键字和变量名识别
  27.     if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) {
  28.         m=0;
  29.         while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) {
  30.             token[m++]=ch;
  31.             ch=str[p++];
  32.         }
  33.         token[m++]='\0';
  34.         p--;
  35.         syn=3;
  36.         for(n=0; n<10; n++)
  37.             if(strcmp(token,tab[n])==0) {
  38.                 syn=10+n;
  39.                 break;
  40.             }
  41.     } else if((ch>='0'&&ch<='9')) { //整数和小数识别
  42.         sum=0;
  43.         while((ch>='0'&&ch<='9') || ch=='.') {
  44.             if(ch=='.') {
  45.                 ch=str[p++];
  46.                 double rate = 0.1;
  47.                 small = sum;
  48.                 while((ch>='0'&&ch<='9')) {
  49.                     small = small + (ch-'0')*rate;
  50.                     rate = rate*0.1;
  51.                     ch=str[p++];
  52.                 }
  53.                 p--;
  54.                 syn=2;
  55.                 break;
  56.             }
  57.             sum=sum*10+ch-'0';
  58.             ch=str[p++];
  59.         }
  60.         if(syn!=2) {
  61.             p--;
  62.             syn=1;
  63.         }
  64.     } else switch(ch) { //运算符等其它符号识别
  65.             case'<':
  66.                 m=0;
  67.                 token[m++]=ch;
  68.                 ch=str[p++];
  69.                 if(ch=='=') {
  70.                     syn=29;
  71.                     token[m++]=ch;
  72.                 } else {
  73.                     syn=27;
  74.                     p--;
  75.                 }
  76.                 break;
  77.             case'>':
  78.                 m=0;
  79.                 token[m++]=ch;
  80.                 ch=str[p++];
  81.                 if(ch=='=') {
  82.                     syn=28;
  83.                     token[m++]=ch;
  84.                 } else {
  85.                     syn=26;
  86.                     p--;
  87.                 }
  88.                 break;
  89.             case':':
  90.                 m=0;
  91.                 token[m++]=ch;
  92.                 ch=str[p++];
  93.                 if(ch=='=') {
  94.                     syn=24;
  95.                     token[m++]=ch;
  96.                 } else {
  97.                     syn=37;
  98.                     p--;
  99.                 }
  100.                 break;
  101.             case'+':
  102.                 syn=20;
  103.                 token[0]=ch;
  104.                 break;
  105.             case'-':
  106.                 syn=21;
  107.                 token[0]=ch;
  108.                 break;
  109.             case'*':
  110.                 syn=22;
  111.                 token[0]=ch;
  112.                 break;
  113.             case'/':
  114.                 syn=23;
  115.                 token[0]=ch;
  116.                 break;
  117.             case'=':
  118.                 syn=25;
  119.                 token[0]=ch;
  120.                 break;
  121.             case'(':
  122.                 syn=33;
  123.                 token[0]=ch;
  124.                 break;
  125.             case')':
  126.                 syn=34;
  127.                 token[0]=ch;
  128.                 break;
  129.             case'{':
  130.                 syn=35;
  131.                 token[0]=ch;
  132.                 break;
  133.             case'}':
  134.                 syn=36;
  135.                 token[0]=ch;
  136.                 break;
  137.             case',':
  138.                 syn=30;
  139.                 token[0]=ch;
  140.                 break;
  141.             case'.':
  142.                 syn=31;
  143.                 token[0]=ch;
  144.                 break;
  145.             case';':
  146.                 syn=32;
  147.                 token[0]=ch;
  148.                 break;
  149.             case'\n': //去掉换行
  150.                 syn=-2;
  151.                 break;
  152.             case'#':
  153.                 syn=0;
  154.                 token[0]=ch;
  155.                 break;
  156.             default:
  157.                 if(ch != '#')
  158.                     syn=-1;
  159.                 break;
  160.         }
  161. }
  162. int main() {
  163.     printf("请输入字符串:\n");
  164.     while(1) {
  165.         p=0;
  166.         do {
  167.             scanf("%c", &ch);
  168.             str[p++]=ch;
  169.         } while(ch!='#');
  170.         p=0;
  171.         do {
  172.             scaner();
  173.             switch(syn) {
  174.                 case 1:
  175.                     printf("(%d,%d)\n",syn,sum);
  176.                     break;
  177.                 case 2:
  178.                     printf("(%d,%f)\n",syn,small);
  179.                     break;
  180.                 case -1:
  181.                     printf("Error %c\n", ch);
  182.                     break;
  183.                 case -2:
  184.                     break;
  185.                 default:
  186.                     if(token[0] != '#')
  187.                         printf("(%d,%s)\n",syn,token);
  188.                     break;
  189.             }
  190.         } while (syn!=0);
  191.         printf("请再次输入:\n");
  192.     }
  193. }
运行结果如下  

发表评论

目前评论:1