1、1词法分析识别五类单词符计算机 09207 邹芬芬 实验目的设计完成正则文法所描述的 Pascal 语言子集单词符号的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即关键字、其他标识符、整型常数、运算符、界符五大类。并在文本文件中依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)。 实验要求1) 给出各单词符号的类别编码;2) 词法分析程序应能发现输入串中的错误;3) 词法分析作为单独一遍编写,词法分析结
2、果为二元式序列组成的中间文件;4) 设计两个测试用例(尽可能完备),并给出测试结果。 实验设计1)待分析的简单语言的词法(1) 关键字:“begin“,“end“,“if“,“then“,“else“,“for“,“do“,“while“,“and“,“or“,“not“所有的关键字都是小写。(2) 运算符和界符:, =, , =, :, :=, /, /*, +, -, *, ;, (, ), /* */(3) 其他单词是标识符(ID)和整型常数(NUM) ,通过以下正规式定义:ID=letter(letter|digit)*NUM=digit digit*(4) 空格由空白、制表符和换行符
3、组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽2略。2) 各种单词符号对应的种别码表 1 各种单词符号对应的种别码单词符号 种别码 单词符号 种别码begin 1 18then 4 = 19else 5 : 20for 6 := 21do 7 / 22while 8 /* 23and 9 + 24or 10 - 25not 11 * 26letter (letter | digit)* 12 ; 27digit digit* 13 ( 280 then x:=2*x+1/3;/*此行为测试程序!*/end#测试结果(#字符用于标示字符串结束) :4输出文本:(
4、1,begin) ( 12,x) ( 21,:=) ( 13,9) ( 27,;) ( 3,if) ( 12,x) ( 18,) ( 13,0) ( 4,then) ( 12,x)( 21,:=) ( 13,2) ( 26,*) ( 12,x) ( 24,+) ( 13,1) ( 22,/) ( 27,;) ( 2,end) ( 0,# )测试样例 2begina := 2;b := 1;elsethen b :=2;end#测试结果:输出文本:( 1,begin) ( 12,a) ( 21,:=) ( 13,2) ( 27,;) ( 12,b) ( 21,:=) ( 13,1) ( 27,;
5、) error error error( 3,if) ( 28,() ( 12,a) ( 19,=) ( 12,b) ( 29,) ( 4,then) ( 12,a) ( 21,:=) ( 13,3) ( 27,;)( 5,else) ( 4,then) ( 12,b) ( 21,:=) ( 13,2) ( 27,;) ( 2,end) ( 0,# )5. 心得体会通过这次用 C 语言对词法分析程序的编制,回顾了 C 语言的编程方法,加深了对词法分析原理的理解和词法分析的实现过程,掌握了编译程序的实现方法和技术。6附录源代码#include #include #include #include
6、 char TOKEN20; /*用来存放单词词文中的各个字符*/5char *rwtab11=“begin“,“end“,“if“,“then“,“else“,“for“,“do“,“while“,“and“,“or“,“not“; /*定义保留字*/int syn;int n;FILE*fp, *fpout;void scanner()int count=0;int i;char ch;ch=fgetc(fp);while(ch= |ch=t|ch=n) ch=fgetc(fp); /*当是空格、空白和换行的时候指向下一个字符*/if(isalpha(ch) /*ch是字母字符时*/TOK
7、EN0=ch;ch=fgetc(fp);i=1;while(isalnum(ch)TOKENi=ch;i+;ch=fgetc(fp);TOKENi=0;fseek(fp,-1,1);syn=12; /*首先是将全部字母字符归为一类,syn=12*/for(n=0;n*/if(ch=) /*当字符是) /*当字符是 时再分为几种情况:,=*/if(ch=) TOKEN1=ch;ch=fgetc(fp);TOKEN2=0;fseek(fp,-1,1);syn=19; /*当字符是=时*/else7fseek(fp,-1,1);syn=18;break;case:TOKEN0=ch;ch=fgetc
8、(fp); /*当开始字符是: 时再分为几种情况::,:=*/if(ch=) /*当字符是:=时*/TOKEN1=ch;ch=fgetc(fp);TOKEN2=0;fseek(fp,-1,1);syn=21; elsesyn=20;fseek(fp,-1,1);break;case/:TOKEN0=ch;ch=fgetc(fp); /*当开始字符是/ 时再分为几种情况:/,/* */if(ch=*) /*当字符是/*时*/TOKEN1=ch;ch=fgetc(fp);i=2;while(ch != #)if(ch = *)TOKENi=ch;i+;ch=fgetc(fp);if(ch = /)
9、TOKEN0=0;break; elsesyn=23;ch=fgetc(fp);TOKEN2=0;fseek(fp,-1,1);8ch=fgetc(fp);TOKENi=0;fseek(fp,-1,1); elsesyn=22;ch=fgetc(fp);TOKEN1=0;fseek(fp,-1,1);break;case+:TOKEN0=ch; /*当字符是+时*/TOKEN1=0;syn=26;break; case-:TOKEN0=ch; /*当字符是-时*/TOKEN1=0;syn=27;break; case*:TOKEN0=ch; /*当字符是*时*/TOKEN1=0;syn=28;
10、break; case;:TOKEN0=ch; /*字符是;时*/TOKEN1=0;syn=29;break; case(:TOKEN0=ch; /*当字符是(时*/TOKEN1=0;syn=30;break; case):TOKEN0=ch; /*当字符是)时*/TOKEN1=0;syn=31;break; case#:TOKEN0=ch; /*当字符是#时*/TOKEN1=0;fseek(fp,-1,1); syn=0;break; default:syn=-1;return;int main()fp=fopen(“fp.txt“,“r“);9if(!fp)printf(“file cannot be opened!“);elsedoFILE *fpout;scanner();switch(syn)case -1: fpout= fopen( “output.txt“, “w“ );fprintf( fpout, “n errorn“);fclose(fpout);break;default: fpout= fopen( “output.txt“, “w“ );fprintf( fpout, “( %d,%s ) n“,syn,TOKEN );fclose(fpout);while(syn!=0);system(“pause“);return 0;