分享

【编译原理】一个词法分析器源码的剖析

 londonKu 2012-05-05

一,词法分析器

        作用:读取源程序的输入字符、将他们组成词素,生成并输出一个词法单元序列

二,设计原理

        1)C程序语言的符号分类:关键字、标识符、常数、运算符、界符

        2)词法分析器的二元输出:<单词种别,单词符号属性值>

        3)正规式和状态转换图

 

           4)程序说明:

                               1>main 中打开源码文件,从第一个字符流读取

                               2>如果第一个是字符,则交给letterprocess(str); 处理

                               3>如果第一个是数字,则交给numberprocess(str); 处理

                               4>如果第一个是数字,则交给otherprocess(str); 处理

                               5>注意上述过程中,File *fp每读取一个词素,fp都会移动到下一个词素。对于空格的处理:isspace(ch)检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符

  ('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页('\f')的情况

                 这个程序输出结果情况汇总:关键字、算术运算符、关系运算符、分割符号、特殊符号、注释符号、逻辑运算符、非法符号

三,程序源码

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <ctype.h>  
  5. #include <malloc.h>  
  6. #include <conio.h>  
  7. #define NULL 0  
  8. FILE *fp;  
  9. char ch;  
  10. char *keyword[34]={"auto","break","case","char","const","continue","default","do","double",   
  11. "else","enum","extern","float","for","goto","if","int","long","register",   
  12. "return","short","signed","sizeof","static","struct","switch","typedef", "printf",  
  13. "union","unsigned","void","volatile","while","main"};  
  14. char *operatornum[6]={"+","-","*","/","++","--"};  
  15. char *comparison[8]={"<","<=","=",">",">=","<>","==","!="};  
  16. char *interpunction[8]={",",";",":=",".","(",")","{","}"};  
  17. char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊标识符  
  18. char *zhushifu[3]={"//","/*","*/"};//注释符  
  19. char *luoji[3]={"&&","||","!"};//逻辑运算符  
  20.   
  21.   
  22. bool search(char searchstr[],int wordtype)//符号匹配   
  23. {  
  24.     int i;  
  25.     switch (wordtype)  
  26.     {  
  27.         case 1:  
  28.             for(i=0;i<=33;i++)  
  29.             {  
  30.                 if(strcmp(keyword[i],searchstr)==0)  
  31.                 return(true);  
  32.             }  
  33.             break;  
  34.         case 2:  
  35.             for(i=0;i<=5;i++)  
  36.             {  
  37.                 if(strcmp(operatornum[i],searchstr)==0)  
  38.                 return(true);  
  39.             }  
  40.          break;  
  41.               
  42.         case 3:   
  43.             for(i=0;i<=7;i++)  
  44.             {  
  45.              if(strcmp(comparison[i],searchstr)==0)  
  46.                 return(true);  
  47.             }  
  48.             break;  
  49.      
  50.         case 4:   
  51.             for(i=0;i<=7;i++)  
  52.             {  
  53.                 if(strcmp(interpunction[i],searchstr)==0)  
  54.                 return(true);  
  55.             }  
  56.     
  57.             break;  
  58.         case 5:   
  59.             for(i=0;i<=5;i++)  
  60.             {  
  61.                 if(strcmp(biaoshifu[i],searchstr)==0)  
  62.                     return(true);  
  63.             }  
  64.             break;  
  65.         case 6:  
  66.              for(i=0;i<=2;i++)  
  67.              {  
  68.                 if(strcmp(zhushifu[i],searchstr)==0)  
  69.                     return(true);  
  70.             }  
  71.             break;  
  72.         case 7:   
  73.             for(i=0;i<=2;i++)  
  74.             {  
  75.                 if(strcmp(luoji[i],searchstr)==0)  
  76.                     return(true);  
  77.             }  
  78.         break;  
  79.     }  
  80.   
  81.     return false;  
  82. }  
  83.   
  84. char letterprocess (char ch)//字母处理函数  
  85. {  
  86.     int i=-1;  
  87.     char letter[20];  
  88.     while (isalnum(ch)!=0)  
  89.     {  
  90.         letter[++i]=ch;  
  91.         ch=fgetc(fp);  
  92.     }  
  93.     letter[i+1]='\0';  
  94.     if (search(letter,1))  
  95.     {  
  96.         printf("<%s,关键字>\n",letter);  
  97.         //strcat(letter,"\n");  
  98.         //fputs('<' letter '>\n',outp);  
  99.     }  
  100.     else  
  101.     {  
  102.         printf("<%s,自定义变量>\n",letter);  
  103.         //strcat(letter,"\n");  
  104.         //fputs(letter,outp);  
  105.     }  
  106.   
  107.     return(ch);  
  108. }  
  109.   
  110. char numberprocess(char ch)//数字处理程序  
  111. {  
  112.     int i=-1;  
  113.     char num[20];  
  114.     while (isdigit(ch)!=0)  
  115.     {  
  116.         num[++i]=ch;  
  117.         ch=fgetc(fp);  
  118.     }  
  119.     if(isalpha(ch)!=0)//数字后面是字符   
  120.     {  
  121.         while(isspace(ch)==0)  
  122.         {  
  123.             num[++i]=ch;  
  124.             ch=fgetc(fp);  
  125.         }  
  126.         num[i+1]='\0';  
  127.         printf("错误!非法标识符:%s\n",num);  
  128.     goto u;  
  129.     }  
  130.     num[i+1]='\0';  
  131.     printf("<%s,数字>\n",num);  
  132.   
  133.     u: return(ch);  
  134. }  
  135.   
  136. char otherprocess(char ch)//其他处理程序   
  137. {  
  138.     int i=-1;  
  139.     char other[20];  
  140.     if (isspace(ch)!=0)  
  141.     {  
  142.         ch=fgetc(fp);  
  143.         goto u;  
  144.     }  
  145.     while ((isspace(ch)==0)&&(isalnum(ch)==0))  
  146.     {  
  147.         other[++i]=ch;  
  148.         ch=fgetc(fp);  
  149.     }  
  150.     other[i+1]='\0';  
  151.     if (search(other,2))  
  152.         printf("<%s,算数运算符>\n",other);  
  153.     else if (search(other,3))  
  154.         printf("<%s,关系运算符号>\n",other);  
  155.     else if (search(other,4))  
  156.         printf("<%s,分隔符号>\n",other);  
  157.     else if (search(other,5))  
  158.         printf("<%s,特殊标识符号>\n",other);  
  159.     else if (search(other,6))  
  160.         printf("<%s,注释符号>\n",other);  
  161.     else if (search(other,7))  
  162.         printf("<%s,逻辑运算符号>\n",other);  
  163.     else   
  164.         printf("错误!非法字符:%s\n",other);  
  165.     u: return (ch);  
  166. }  
  167.   
  168. int main ()  
  169. {  
  170.     char str;  
  171.     printf("**********************************词法分析器************************************\n");  
  172.     if ((fp=fopen("源程序.txt","r"))==NULL)  
  173.         printf("源程序无法打开!\n");  
  174.     else  
  175.     {  
  176.         str =fgetc(fp);//从流中读取字符   
  177.         while (str!=EOF)  
  178.         {  
  179.             if (isalpha(str)!=0)//如果是字符    isalpha包含在#include <cctype>  
  180.                 str=letterprocess(str);  
  181.             else  
  182.             {  
  183.                 if (isdigit(str)!=0)  
  184.                     str=numberprocess(str);  
  185.                 else  
  186.                     str=otherprocess(str);  
  187.             }  
  188.       
  189.         };  
  190.      printf("词法分析结束,谢谢使用!\n");  
  191.      //printf("点任意键退出!\n");  
  192.    }  
  193.    //c=getch();  
  194.      
  195.    return 0;  
  196. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多