您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 江苏科技大学编译原理实验报告
实验一词法分析设计一、实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。二、实验内容用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。(2)统计行数和列数用于错误单词的定位。(3)删除空格类字符,包括回车、制表符空格。(4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token的机内表示)(5)如果发现错误则报告出错(6)根据需要是否填写标识符表供以后各阶段使用。单词的基本分类:关键字:由程序语言定义的具有固定意义的标识符。也称为保留字例如if、for、while、printf;单词种别码为1。1标识符:用以表示各种名字,如变量名、数组名、函数名;常数:任何数值常数。如125,1,0.5,3.1416;运算符:+、-、*、/;关系运算符:、=、=、、=、;分界符:;、,、(、)、[、];三、词法分析实验设计思想及算法1、主程序设计考虑:程序的说明部分为各种表格和变量安排空间。在具体实现时,将各类单词设计成结构和长度均相同的形式,较短的关键字后面补空。k数组------关键字表,每个数组元素存放一个关键字(事先构造好关键字表)。s数组------存放分界符表(可事先构造好分界符表)。为了简单起见,分界符、算术运算符和关系运算符都放在s表中(编程时,应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。id和ci数组分别存放标识符和常数。instring数组为输入源程序的单词缓存。outtoken记录为输出内部表示缓存。还有一些为造表填表设置的变量。主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。例如,把每一单词设计成如下形式:(type,pointer)其中type指明单词的种类,例如:Pointer指向本单词存放处的开始位置。还有一些为造表填表设置的变量。主程序开始后,先以人工方式输入关键字,造k表;再输入分界符等造p表。主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。2例如,把每一单词设计成如下形式:(type,pointer)其中type指明单词的种类,例如:Pointer指向本单词存放处的开始位置。3词法分析设计流程图2、词法分析过程考虑根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符k表示关键字;id表示标识符;ci表示常数;s表示分界符。对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数变为二进制形式存入数组中ci中,并记录其在表中的位置。lexical过程中嵌有两个小过程:一个名为getchar,其功能为从instring中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程,输出错误编号。要求:所有识别出的单词都用两个字节的等长表示,称为内部码。第一个字节为t,第二个字节为i。t为单词的种类。关键字的t=1;分界符的t=2;算术运算符的t=3;关系运算符的t=4;无符号数的t=5;标识符的t=6。i为该单词在各自表中的指针或内部码值。表1为关键字表;表2为4分界符表;表3为算术运算符的i值;表4为关系运算符的i值。5取字符和统计字符行列位置子程序四、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。3、根据测试数据进行测试。测试实例应包括以下三个部分:全部合法的输入。各种组合的非法输入。由记号组成的句子。4、词法分析程序设计要求输出形式:例:输入VC++语言的实例程序:Ifi=0thenn++;a﹤=3b%);输出形式为:单词二元序列类型位置(行,列)(单词种别,单词属性)for(1,for)关键字(1,1)i(6,i)标识符(1,2)=(4,=)关系运算符(1,3)60(5,0)常数(1,4)then(1,then)关键字(1,5)n(6,n)标识符(1,6)++ErrorError(1,7);(2,;)分界符(1,8)a(6,a)标识符(2,1)﹤=(4,=)关系运算符(2,2)3bErrorError(2,4)%ErrorError(2,4))(2,))分界符(2,5);(2,;)分界符(2,6)五、实验步骤1、根据流程图编写出各个模块的源程序代码上机调试。2、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的词法分析程序;直至能够得到完全满意的结果。六、程序源代码1、词法分析器操作类package词法分析器;publicclasscompiler{publicStringcomputerComp(Stringstr){Stringoutput=;intindex=0;while(indexstr.length()){//判断界符if(isJieFu(str.charAt(index))){7output+=((界符,+str.charAt(index)+));index++;}//判断运算符elseif(isCompu(str.charAt(index))){if(!isCompu(str.charAt(index+1))){output+=((运算符,);}elseif((!isCompu(str.charAt(index+2)))&&isCompu(str.charAt(index+1))){if(str.charAt(index)=='!'){if(str.charAt(index+1)=='='){output+=((运算符,);}else{output+=((非法字符,);}}elseif((str.charAt(index)==''||str.charAt(index)=='')||((str.charAt(index)=='*'||str.charAt(index)=='/')||(str.charAt(index)=='%'||str.charAt(index)=='='))){if(str.charAt(index+1)=='='){output+=((运算符,);}else{output+=((非法字符,);}}else8if(str.charAt(index)=='+'||str.charAt(index)=='-'){if(str.charAt(index)==str.charAt(index+1)||str.charAt(index+1)=='='){output+=((运算符,);}else{output+=((非法字符,);}}else{output+=((非法字符,);}}else{output+=((非法字符,);}while(isCompu(str.charAt(index))){output+=(str.charAt(index));index++;if(index=str.length())returnoutput;}output+=());}//数字elseif(isMath(str.charAt(index))){intindex1=index;output+=(();9while(isMath(str.charAt(index))){output+=(str.charAt(index));index++;if(index=str.length())returnoutput;}if(isLetter(str.charAt(index))){while((!isMath(str.charAt(index)))&&(isLetter(str.charAt(index)))){output+=(str.charAt(index));index++;if(index=str.length())returnoutput;}output+=(,非法字符));}else{if(str.charAt(index1)=='0'){if(isMath(str.charAt(index1+1))){output+=(,非法字符));}else{output+=(,数字,));}}elseoutput+=(,数字,));}}//字母判断elseif(isLetter(str.charAt(index))){10inti=index;while(isLetter(str.charAt(index))||isMath(str.charAt(index))){if(index=str.length())returnoutput;index++;}Stringsub=str.substring(i,index);//判断是是不是关键字if(isKeyword(sub))output+=((关键字,+sub+));elseoutput+=((标识符,+sub+));}//空格或者回车处理else{index++;}}returnoutput;}//判断是不是关键字publicbooleanisKeyword(Stringstr){booleanflag=true;String[]arr={public,static,void,main,String,int,boolean,private,if,else,while};11for(inti=0;iarr.length;i++){if(str.equals(arr[i])){flag=true;break;}elseflag=false;}returnflag;}//判断是不是字母publicbooleanisLetter(charcharr){if(((charr='a'&&charr='z')||(charr='A'&&charr='Z'))||charr=='_')returntrue;elsereturnfalse;}publicbooleanisMath(charcharr){if((charr='0')&&(charr='9'))returntrue;elsereturnfalse;}//判断是不是界符得方法publicbooleanisJieFu(charcharr){chararr[]={'[',']',';','{','}',''};for(inti=0;iarr.length;i++){if(charr==arr[i]){returntrue;12}}returnfalse;}//判断是不是运算符得方法publicbooleanisCompu(charcharr){booleanflag=false;chararr[]={'=','+','-','*','!','/','','','%'};for(inti=0;iarr.length;i++){if(charr==arr[i]){flag=true;break;}elseflag=false;}returnflag;}}2、界面类package词法分析器;importjava.awt.*;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.*;importjavax.
本文标题:江苏科技大学编译原理实验报告
链接地址:https://www.777doc.com/doc-5245109 .html