词法分析器实验报告
一、实验目的
·掌握词法分析器的生成工具LEX的用法
·实现PL/0编译器的词法分析部分
二、实验内容和要求
·实验内容:
用flex工具生成一个PL/0语言的词法分析程序,对PL/0语言的源程序进行扫描,识别出单词符号的类别,输出各种符号的信息。
·实验要求:
·输入:PL0源程序
·输出:把单词符号分为下面六类,然后按单词符号出现顺序依次输出各单词符号的种类和出现在源程序中的位置(行数和列数)。
– K类(关键字)
– I类(标识符)
– C类(常量)
– O类(算符)
– D类(界符)
– T类(其他)
·实验环境:
·词法分析器生成工具:flex
·编程语言:C
三、实验过程
LEX源程序
%{ #include<math.h> #include<string.h> #include<stdlib.h> #include<stdio.h> void position(); void main(int argc,char *argv[]); int row=1;//行 int col=1;//列 int value; FILE *fpout;//结果文件指针 %} Keyword const|var|procedure|begin|end|if|then|while|do|read|call|write|odd|for /*关键字*/ Identfier [A-Za-z][A-Za-z0-9]* /*标识符*/ Constant ([0-9])+ /*常数*/ Operator \+|-|\*|\/|:=|#|<|<=|>|>=|=|!= /*算符*/ Delimiter [,\.;()] /*界符*/ whitespace [\\s+] /*分隔符:空格,回车,制表符*/ wrongid (([0-9])+)[A-Za-z][A-Za-z0-9]* /*错误标识符(数字开头的字母数字串)*/ wrongnum (([0-9])+)([\.]+)(([0-9]+)) /*错误常数(浮点数)*/ newline [\n\r] /*记录新的一行*/ %% {Keyword} {value=1;position();} {Identfier} {value=2;position();} {Constant} {value=3;position();} {Operator} {value=4;position();} {Delimiter} {value=5;position();} {whitespace} {value=7;position();} {wrongid} {value=6;position();} {wrongnum} {value=6;position();} " " {value=7;position();} ":" {value=6;position();} . {value=6;position();} {newline} {row+=1;col=1;} %% void position(){ switch(value){ case 1: fprintf(fpout,"%s : K , (%d , %d)\n",yytext,row,col); break; case 2: /*标识符的有效长度是10*/ if(strlen(yytext)<=10){ fprintf(fpout,"%s : I , (%d , %d)\n",yytext,row,col); break; } else{ fprintf(fpout,"%s : T , (%d , %d)\n",yytext,row,col); break; } case 3: /*数最多为14位*/ if(strlen(yytext)<=14){ fprintf(fpout,"%s : C , (%d , %d)\n",yytext,row,col); break; } else{ fprintf(fpout,"%s : T , (%d , %d)\n",yytext,row,col); break; } case 4: fprintf(fpout,"%s : O , (%d , %d)\n",yytext,row,col); break; case 5: fprintf(fpout,"%s : D , (%d , %d)\n",yytext,row,col); break; case 6: fprintf(fpout,"%s : T , (%d , %d)\n",yytext,row,col); break; case 7: break; } col+=strlen(yytext); } void main(int argc,char *argv[]) { yyin=fopen("number.pl0","r"); fpout=fopen("result.txt","w+"); yylex(); fclose(yyin); } int yywrap() { return 1; }
四、实验总结
实验难点在于考虑到尽可能多的错误情况,尤其是PL/0语言本身的词法要求。