编译原理 实验1 PL/0语言词法分析

PL/0语言词法分析

一、 实验目的

通过完成词法分析程序,了解词法分析的过程。编制一个读单词程序,对PL/0语言进行词法分析,把输入的字符串形式的源程序分割成一个个单词符号,即基本保留字、标识符、常数、运算符、界符五大类。

二、 实验环境

操作系统:window xp

编写环境:visual c++ c-freeturbo c

编写语言:c语言

分析语言:PL/0

三、 实验内容

PL/0语言进行词法分析,把输入的字符串形式的源程序分割成一个个单词符号,其词法描述如下:

(1) 关键字:begincallconstdoendifoddprocedurereadthenvarwhilewrite

(2) 标识符:用来表示各种名字,必须以字母开头小于10位字符组成

(3) 数字:以0-9组成小于14位的数字

(4) 运算符:+-*/:=<<=>>=

(5) 界符:,.;#

 

各种单词符号对应类型表

单词符号

类型

+

plus

-

minus

*

times

/

slash

(

lparen

)

rparen

=

eql

,

comma

.

perio

#

neq

;

semicolon

begin

beginsym

call

callsym

const

constsym

do

dosym

end

endsym

if

ifsym

odd

oddsym

procedure

proceduresym

read

readsym

then

thensym

var

varsym

while

whilesym

write

writesym

GETSYM函数功能:

(1) 滤空格  空格在词法分析时是一种不可缺少的界符,而在语法分析时则是无用的,所以必须过滤

(2) 识别保留字  主程序定义了一个以字符为元素的一维数组WORD,称保留字表。对字母开头的字母、数字字符串要查此表。若查着则识别为保留字,将对应的类别放在SYM中。如IF的对应值IFSYMTHEN的对应值为THENSYM。若查不着,则认为是用户定义的标识符

(3) 识别保留字  对用户定义的标识符将IDENT放在SYM中,标识符本身的值放在ID

(4) 拼数  当扫描到数字串时,将字符串形式的十进制数转换为二进制数,然后把数的类别NUMBER放在SYM中,数值本身的值放在NUM

(5) 拼合复合词  对两个字符组成的算符,如:>=:=<=等单词,识别后将类别送SYM

(6) 输出源程序  为边读入字符边输出(可输出在文件中)

四、 

实验结果

要分析的内容如下:

  1. const a=36;  
  2. var c,d;  
  3. procedure p;  
  4. begin  
  5. var g;  
  6. g:=1234567890000000;  
  7. write(g);  
  8. end;  
  9. begin  
  10. read(c,d);  
  11. if c<=d then c:=a;  
  12. write(c,d);  
  13. call p;  
  14.     end.  

pl0.h 头文件
  1. #define norw 13         /*关键字个数*/   
  2. #define nmax 14         //number的最大位数   
  3. #define al 10           //符号的最的长度 符号就是+ - 神马的  
  4. #define cxmax 200       //最多的虚拟机代码数  
  5.   
  6. enum symbol {  
  7.     nul, ident, number, plus, minus, times, slash, oddsym, eql, neq,  
  8.     lss, leq, gtr, geq, lparen, rparen, comma, semicolon, period, becomes,  
  9.     beginsym, endsym, ifsym, thensym, whilesym, writesym, readsym, dosym,   
  10.     callsym, constsym, varsym, procsym,  
  11. };  
  12.   
  13. FILE* fa1;              //输出分析的文件和首地址 首地址是虚拟机指针   
  14. char ch;                //getch读取的字符   
  15. enum symbol sym;  
  16. char id[al+1];          //当前的ident  
  17. int num;   
  18. int cc, ll;             //getch计数器  
  19. int cx;                 //虚拟机代码指针,取值范围0-cxmax-1   
  20. char line[81];  
  21. char a[al+1];           //读取一个符号 暂时存在这里   
  22.   
  23. char word[norw][al];    //保留字13个 就是begin end if 什么的   
  24. enum symbol wsym[norw]; //保留字对应的符号 begin对应beginsym   
  25. enum symbol ssym[256];  //单字符的符号值   
  26.   
  27. FILE* fin;   
  28. FILE* fout;  
  29. char fname[al];         //输入的文件名  
  30. int err;  
  31.   
  32. #define getchdo         if(-1==getch()) return -1;  
  33.   
  34. void error(int n);  

主函数
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include "pl0.h"  
  4.   
  5. void error(int n)  
  6. {  
  7.     char space[81];  
  8.     memset(space, 32, 81);  
  9.     space[cc-1] = 0;  
  10.     printf("****出现错误\n");  
  11.     fprintf(fa1, "****出现错误\n");  
  12.     err++;  
  13. }  
  14. int getch()  
  15. {  
  16.     if(cc == ll)  
  17.     {  
  18.         if(feof(fin))  
  19.         {  
  20.             printf("读完了");  
  21.             return -1;  
  22.         }  
  23.         ll = 0;  
  24.         cc = 0;  
  25.         //printf("%d ", cx);  
  26.         //fprintf(fa1, "%d", cx);  
  27.         ch = ' ';  
  28.         while(ch != 10)  
  29.         {  
  30.             if(fscanf(fin, "%c", &ch) == EOF)  
  31.             {  
  32.                 line[ll] = 0;  
  33.                 break;  
  34.             }  
  35.             printf("%c", ch);  
  36.             fprintf(fa1, "%c", ch);  
  37.             line[ll] = ch;  
  38.             ll++;  
  39.         }  
  40.         printf("\n");  
  41.         //fprintf(fa1, "\n");  
  42.     }  
  43.     ch = line[cc];  
  44.     cc++;  
  45.     return 0;  
  46. }  
  47.   
  48. int getsym()  
  49. {  
  50.     int i, j, k;  
  51.     while(ch == ' ' || ch == 10 || ch == 9)  
  52.     {  
  53.         getchdo;  
  54.     }  
  55.     if(ch >= 'a' && ch <= 'z')  
  56.     {  
  57.         k = 0;  
  58.         do  
  59.         {  
  60.             if(k < al)  
  61.             {  
  62.                 a[k] = ch;  
  63.                 k++;  
  64.             }  
  65.             getchdo;  
  66.         }while(ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9');  
  67.       
  68.         a[k] = 0;  
  69.         strcpy(id, a);  
  70.         i = 0;  
  71.         j = norw-1;  
  72.         do  
  73.         {  
  74.             k = (i+j)/2;  
  75.             if(strcmp(id, word[k]) <= 0)  
  76.                 j = k-1;  
  77.             if(strcmp(id, word[k]) >= 0)  
  78.                 i = k+1;  
  79.         }while(i <= j);  
  80.           
  81.         if(i-1 > j)  
  82.         {  
  83.             sym = wsym[k];  
  84.         }  
  85.         else  
  86.         {  
  87.             sym = ident;  
  88.         }  
  89.     }  
  90.     else  
  91.     {  
  92.         if(ch >= '0' && ch <= '9')  
  93.         {  
  94.             k = 0;  
  95.             num = 0;  
  96.             sym = number;  
  97.             do  
  98.             {  
  99.                 num = num * 10 + ch - '0';  
  100.                 k++;  
  101.                 getchdo;  
  102.             }while(ch >= '0' && ch <= '9');  
  103.             k--;  
  104.             if(k > nmax)  
  105.             {  
  106.                 error(30);  
  107.             }  
  108.         }  
  109.         else  
  110.         {  
  111.             if(ch == ':')  
  112.             {  
  113.                 getchdo;  
  114.                 if(ch == '=')  
  115.                 {  
  116.                     sym = becomes;  
  117.                     getchdo;  
  118.                 }  
  119.                 else  
  120.                 {  
  121.                     sym = nul;  
  122.                 }  
  123.             }  
  124.             else  
  125.             {  
  126.                 if(ch == '<')  
  127.                 {  
  128.                     getchdo;  
  129.                     if(ch == '=')  
  130.                     {  
  131.                         sym = leq;  
  132.                         getchdo;  
  133.                     }  
  134.                     else  
  135.                     {  
  136.                         sym = lss;  
  137.                     }  
  138.                 }  
  139.                 else  
  140.                 {  
  141.                     if(ch == '>')  
  142.                     {  
  143.                         getchdo;  
  144.                         if(ch == '=')  
  145.                         {  
  146.                             sym = geq;  
  147.                             getchdo;  
  148.                         }  
  149.                         else  
  150.                         {  
  151.                             sym = gtr;  
  152.                         }  
  153.                     }  
  154.                     else   
  155.                     {  
  156.                           
  157.                         sym = ssym[ch];  
  158.                         if(sym != period)  
  159.                         {  
  160.                             getchdo;  
  161.                         }  
  162.                         else  
  163.                             return -1;  
  164.                     }  
  165.                 }  
  166.             }  
  167.         }  
  168.     }  
  169.     return 0;  
  170. }  
  171. void init()  
  172. {  
  173.     int i;  
  174.     for(int i = 0; i < 256; i++)  
  175.         ssym[i] =  nul;  
  176.     ssym['+'] = plus;  
  177.     ssym['-'] = minus;  
  178.     ssym['*'] = times;  
  179.     ssym['/'] = slash;  
  180.     ssym['('] = lparen;  
  181.     ssym[')'] = rparen;  
  182.     ssym['='] = eql;  
  183.     ssym[','] = comma;  
  184.     ssym['.'] = period;  
  185.     ssym['#'] = neq;  
  186.     ssym[';'] = semicolon;  
  187.       
  188.     strcpy(&(word[0][0]), "begin");  
  189.     strcpy(&(word[1][0]), "call");  
  190.     strcpy(&(word[2][0]), "const");  
  191.     strcpy(&(word[3][0]), "do");  
  192.     strcpy(&(word[4][0]), "end");  
  193.     strcpy(&(word[5][0]), "if");  
  194.     strcpy(&(word[6][0]), "odd");  
  195.     strcpy(&(word[7][0]), "procedure");  
  196.     strcpy(&(word[8][0]), "read");  
  197.     strcpy(&(word[9][0]), "then");  
  198.     strcpy(&(word[10][0]), "var");  
  199.     strcpy(&(word[11][0]), "while");  
  200.     strcpy(&(word[12][0]), "write");  
  201.       
  202.     wsym[0] = beginsym;  
  203.     wsym[1] = callsym;  
  204.     wsym[2] = constsym;  
  205.     wsym[3] = dosym;  
  206.     wsym[4] = endsym;  
  207.     wsym[5] = ifsym;  
  208.     wsym[6] = oddsym;  
  209.     wsym[7] = procsym;  
  210.     wsym[8] = readsym;  
  211.     wsym[9] = thensym;  
  212.     wsym[10] = varsym;  
  213.     wsym[11] = whilesym;  
  214.     wsym[12] = writesym;  
  215.       
  216.       
  217.       
  218.       
  219. }   
  220. int main()  
  221. {  
  222.     printf("请输入要分析的文件名\n");  
  223.     scanf("%s", fname);  
  224.     fin = fopen(fname, "r");  
  225.     if(fin)   
  226.     {  
  227.         printf("请输入要保存的文件名\n");  
  228.         scanf("%s", fname);  
  229.         fa1 = fopen(fname, "w");  
  230.         init();  
  231.         err = 0;  
  232.         cc = cx = ll = 0;  
  233.         ch = ' ';  
  234.         while(getsym() != -1)  
  235.         {  
  236.               
  237.         }  
  238.         printf("分析完毕");  
  239.            
  240.     }  
  241.     else  
  242.     {  
  243.         printf("找不到文件\n");  
  244.     }  
  245.     printf("\n");  
  246.     return 0;  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值