编译原理Word文档格式.docx
- 文档编号:20429043
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:30
- 大小:367.56KB
编译原理Word文档格式.docx
《编译原理Word文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理Word文档格式.docx(30页珍藏版)》请在冰豆网上搜索。
ch;
while(j<
256)
ch=fgetc(fp);
if
(ch=='
\n'
)
//字符变量的内容是回车符吗?
i=j;
return
0;
//是回车符,保存字符个数返回0。
}//if
buffer[j]=ch;
//不是回车符,把字符变量的内容存入数组buffer(),字符个数加1。
++j;
}//While
1;
}//子程序结束
main()//main()开始
if((fp=fopen("
d:
\\a.c"
"
r"
))==NULL)//文件是否为NULL,这里的路径必须用两个斜杠’\\’,其中一个是C语言中的格式符。
printf("
THE
DOESN’T
OPEN!
"
);
//如果是,则输出错误提示。
exit(0);
while(!
feof(fp))//到文件尾否,到文件尾feof()函数则返回非零值,循环结束。
j;
readbuffer();
//如果没有到文件尾,则读入一个字符
i)//判读入一行的字符个数
%c"
buffer[j]);
//读入字符个数小于源文件语句行的字符个数,则输出字符
j++;
//一行字符个数加一
\n"
//否则输出回车
getch();
fclose(fp);
}//main()结束
//程序结束
再将输入的A.c文件内容改为如下:
\\a.c.。
{int
sum=0,i;
float
k;
scanf
("
%f
plese
input
(0-100)
to
total!
&
k)
for(i=0;
i<
i++)
sum
=sum+i;
再运行输入、扫描程序进行调试,输出必须与上面a.c文件中输入的代码相同。
[实验报告]:
1、写出调试程序出现的问题及解决的方法。
2、写实验报告及程序清单。
3、报告给出测试的结果。
实验二无符号数的有穷自动机的实现
4
无符号数的有穷自动机的实现。
利用状态表和有限自动机的运行原理编制程序,使得程序能够识别一个输入串是否为一个无符号定点实数。
1、理解有限自动机的作用;
进一步理解自动机理论。
2、用状态图和状态表表示有限自动机;
3、以程序实现有限自动机的运行过程;
掌握文法转换成自动机的技术及有穷自动机实现的方法。
[实验要求]:
1、设计要求:
利用状态图或状态表相关理论,利用有限自动机理论。
2、功能要求:
输入一个单行无空格的字符串(以“#”号结束),如果该字符串是一个合法的输入,则显示“接受”,否则显示“不接受”。
3、输入/输出示例(以无符号定点实数为例):
(1)输入:
“3.14”,输出:
“接受”;
(2)输入:
“3.1.4”,输出:
“不接受”;
(3)输入:
“3ab”,输出:
“不接受”。
[实验提示]:
1、无符号数的BNF描述如下:
0.<
无符号数>
∷=<
无符号数整数>
|<
无符号数实数>
1.<
.<
数字串>
[E<
比例因子>
]|<
]
2.<
∷=<
有符号数整数>
3.<
∷=[<
正负号>
]<
4.<
∷=+|-
5.<
6.<
∷=<
数字>
{<
7.<
∷=0|1|2|…|9
2、根据G[<
]文法构造成状态转换图(有穷自动机),见图1。
图1
例:
一个无符号定点小数的有穷自动机状态图:
见图2
图2
3、构造状态矩阵;
将有穷自动机的状态S1S2……Sn及输入的字a1a2……am构成一个n*m的矩阵。
1)根据状态矩阵设计出一个词法分析程序识别无符号数。
2)扫描无符号数,根据文法给出无符号数出错的位置。
[实验报告]:
1、写出无符号数词法分析的思想。
2、画出算法流程图。
3、写出调试程序出现的问题及解决的方法。
4、打印实验报告及程序清单。
5、报告给出测试的结果。
根据有限自动机原理设计出无符号定点小数的状态表:
行的下标值表示当前状态;
列的下标值表示输入的字符即数字或小数点(设0表示数字,1表示小数点)。
列行
0
数字
1
小数点
0
1
2
3
-1
3
第0列上的元素值表示为输入数字的后继状态;
第1列上的元素值为输入小数点的后继状态;
第i行(也就是行号)表示第i个状态,该行上对应列上的元素值是输入数字或小数点的后继状态。
有了状态表后就可以构造出一个两维数组state,从状态表可以看出这是一个4行2列的数组。
在程序中设计一个两维数组state来构造一个静态状态表,将状态表中的数赋予两维数组。
State[4][2]={{1,2},{1,2},{3,-1},{3,-1}};
状态表中行0,1,2,3表示状态,-1表示没有此状态,其中1表示整数部分的状态,2表示小数点的状态,3表示小数部分的状态。
程序中设变量S为为状态,初始状态s=0,d变量表示输入的字符,当输入字符是0-9的数字d=0,输入字符是小数点则d=1。
根据状态s和d就可以取出他的后继状态s=state[s][d],判断后继状态s的值就可识别无符号定点实数。
设置一个表示终态标志数组intQ[s]={0,1,0,1};
其中列号表示状态,对应的元素值为终态标志,0非终态,1终态。
从状态图中可以看到,只有在1和3状态下(也就是在输入数字时)出现正常结束,所以一列和三列上对应的元素值设为1。
试验示例:
有限自动机的运行
程序功能:
利用状态表和有限自动机的运行原理,识别一个输入串是否为一个有效的无符号定点实数。
输入:
1#
输出:
接受
输入:
3.14#
3ab#
不接受
1.2.3
输入数据要求:
不能有空格,以'
#'
结束(在本程序也可以不用'
结束)。
输出要求:
如果是无符号定点实数,显示“接受”;
否则显示“不接受”。
注:
同学们可以将状态表改变成识别“无符号实数”的有限自动机的状态表,编写程序、调试、运行。
实验三词法分析处理(查添符号表)
1、查添符号表(标识符为以字母开头的字母数字串)。
2、读入标识符,若表中已有该标识符,则取出其在表中的位置,输出该标识符极其编号;
否则产生一个新的编号,连同标识符一起添入名表;
最后输出标识符表。
1、了解符号表的几种结构,掌握符号表的存取方法。
2、了解编译时如何对标识符进行处理。
3、掌握词法扫描,查填符号表.
[实验要求]:
1、从键盘上输入标识符,标识符之间用逗号隔开,最后以分号结束(也可以用其他符号做结束标志)。
如:
a1,b,x1,x2,y,ac2;
2、编号从100开始,最后输出的标识符不能有重复出现;
3、标识符的长度必须小于或等于8个字符。
[实验步骤]:
1、根据标识符的文法规则,画出标识符的状态转换图。
2、画出读取标识符的程序框图。
3、写出程序,上机调试并输出结果。
1、标识符的BNF描述如下:
标识符>
字母>
{<
1.<
∷=A|B|C|…|Z|a|b|c|…|z
2.<
2、画出标识符的状态转换图,设计出一个词法分析程序识别出标识符。
读入一个字符,首字符必须是字母,其后读入的字符为字母或数字,若不符合这个文法则显示出错信息。
3、构建符号表,将识别出的标识符添入符号表。
若表中已存在该标识符,标识符不添入符号表,则输出该标识符及其在表中的编号,并统计单词出现的次数;
否则产生一个新的编号,连同标识符一起添入符号表,最后输出标识符表。
标识符的状态转换图:
实验结果分析:
如果在输入文件中分别出现字符串长度超过8个、有两个或者两个以上的”;
”连续出现、出现汉字非规定字符和以数字开头等会出现什么样的情况?
编程说明:
1、变量数组的说明:
1)定义一个工作数组A,该数组有8个元素(标识符长度为8)。
2)定义标识符表结构id包含两个成员,数组name存放登记标识符名字,变量addr记录标识符编号。
3)如果工作数组A中为合法标识符,则将其名字填入结构id中的name数组,将其编号填入addr数组。
若工作数组A中为非法标识符,错误标志errty置1,显示出错信息。
4)用变量K记录读入的标识符个数。
5)用变量I记录每个标识符的字符个数。
6)用变量errty记录标识符首字符非字符的错误标志。
7)用变量errty1记录标识符中有非字母数字字符的错误标志。
标识符输出形式:
标识符名称标识符编号
star1
next12
loop13
建立一个标识符表结构structid,结构中包括两个成员,一个数组name[]存放标识符名、另一个变量addr记录标识符编号。
结构如下:
标识符表structid{charname[25];
存放标识符的字符数组
intaddr;
单词在单词表中的地址
}indent[100];
标识符在表中存放的形式:
name
Addr
star
next1
loop1
buffer
:
2、程序框图:
(供参考)
实验四词法分析
(2)实验
学时数:
1.设计一个对形如下列的常量说明进行处理的词法分析程序:
constI=10;
j=100;
r=1.23;
c=‘good‘;
t=true;
1.常量说明,常量可以是字母打头的5个长度的数字、字母的组合,最后以“#”作为结束符。
2.处理各常量说明,计算每个常量的值和类型。
3.输出每个常量的名、值及类型。
4.将该语言的常量说明,也就是相应字符流转换成内码,并根据需要是否对于标识符填写相应的符号表供编译程序的以后各阶段使用。
1.了解词法分析的主要任务。
2.熟悉编译程序的编制。
3.掌握词法分析的处理方法。
1.写出常量识别的确定自动机(DFA)。
2.写出对应的自动机的语义过程。
3.编写程序。
4.结果分析。
常量说明的语法规则:
<
常量说明>
∷=const<
=<
数>
|<
字符串>
逻辑值>
{,<
每个常量说明的形式为:
<
常量说明词法分析程序,即是对每个常量说明形式进行分析处理,填写相应的表格。
(1)从源程序文件中读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)按拼写单词,并用(内码,属性)二元式表示。
(5)根据需要是否填写标识符表供以后各阶段使用
词法分析程序框图:
在词法分析中由主程序调用该读词程序(仅供参考)
程序中使用的数组:
(1)定义一个工作数组,进行标识符、字符常量、逻辑常量的中间处理。
(2)定义一个存放整形、字符型、逻辑型常量名的结构数组。
(3)定义存放整型、实型、字符型、逻辑型常量值的数组。
词法分析器功能:
词法分析程序即读词程序,其输入流是用高级语言书写的源程序,源程序由单词组成,单词又由字符组成的。
词法分析程序的主要任务:
就是完成读词,产生单词符号(即转换成属性字)的任务.
读源程序的字符序列,逐个拼出单词,并构造相应的内部表示TOKEN(内码,属性)。
同时检查源程序中的词法错误。
词法分析程序的其他任务:
滤掉空格,跳过注释、换行符,追踪换行标志,复制出错源程序,宏展开,……
词法分析完成的是编译的第一阶段工作。
词法分析程序把源程序字符流变为单词序列,输出到一个中间文件,作为语法分析程序的输入继续下一阶段的编译过程。
一般情况下,常将词法分析程序设计成一个子程序即读词程序,由语法分析程序调用。
编写词法分析程序时,用重复调用词法分析取单词子程序的方法得到整个源程序的内码流。
当词法分析程序识别并组合出一个单词符号时,就通过RETURN语句返回。
返回时应将单词的类别码送入存放类别码的变量单元中,供语法分析程序调用。
单词的种类与词法分析的输出:
Token表示最小的语义单位---单词的信息(单词内部表示的数据结构形式)。
单词类别
单词值
单词不是程序设计语言中的语法概念,是编译程序中引进的一个概念。
是最小的语义单位,是程序设计语言的基本语法符号,不能分割。
输出的单词符号常采用二元式表示即属性字:
单词符号一般可分为五种:
1.保留字,也称为关键字。
2.标识符,用来表示各种名字。
3.常数,各种类型的常数。
4.运算符。
5.界符,如逗号,分号,括号,。
。
词法分析器的分析过程:
调用getsym读词程序时,它通过getch读字符子程序从源程序中获得一个字符。
如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表(查保留字表时可以使用二分法查找以提高效率。
),如果查到为保留字,则把sym变量(单词)赋成相应的保留字类型值;
如果没有查到,则这个单词是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym置为ident标识符类型值,把这个单词存入id变量。
如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。
如果识别出其它合法的符号(比如:
赋值号、大于号、小于等于号等),则把sym则成相应的类型。
如果遇到不合法的字符,把sym置成nul。
程序设计语言的描述采用扩充的BNF表示:
分程序>
∷=[<
常量说明部分>
][<
变量说明部分>
过程说明部分>
复合语句>
∷=CONST<
常量定义>
};
∷=标识符=无符号整数|字符串常数|逻辑型常数
语句>
∷=<
赋值语句>
条件语句>
当型循环语句>
过程调用语句>
读语句>
写语句>
|ε
∷=标识符:
表达式>
∷=IF<
条件>
THEN<
∷=WHILE<
DO<
∷=标识符|标识符(<
)
关系运算符>
|ODD<
∷=[+|-]<
项>
加型运算符>
因子>
乘型运算符>
∷=标识符|无符号整数|(<
∷=+|-
∷=*|/
∷==|<
>
=|>
|>
=
……
其中:
>
:
用左右尖括号括起的字符串表示非终结符号
∷=:
定义为
{}:
表示该语法成分可以0—n次重复。
[]:
表示方括号内为可选项,即0或1次。
建立一个静态保留字表,供词法分析过程中查找.
保留字如:
funcbeginendintexitreadprinttruefalseifthenelsewhileconst
保留字表结构如下:
charTable[][8]={"
func"
begin"
end"
int"
exit"
read"
printf"
true"
false"
if"
"
then"
else"
while"
,”const”};
实验五语法分析实验
1、有文法规则:
E∷=E+T│E-T│T
T∷=T*F│T/F│F
F∷=F↑P│p
P∷=(E)│i
建立LL
(1)分析表。
2、根据建立的分析表,用LL
(1)分析法对任意输入的符号串进行分析(例:
输入串i+i*i↑i-i/I),判断其是否符合文法。
用LL
(1)分析法编写语法分析程序。
消除递归前的文法
消除递归后的等价文法
E∷=E+T│E-T│TE∷=TE1
T∷=T*F│T/F│FE1∷=+TE1│-TE1│ε
F∷=F↑P│pT∷=FT1
P∷=(E)│iT1∷=*FT1│/FT1│ε
F∷=PF1
F1∷=↑PF1│ε
P∷=(E)│i
1、根据已有的文法规则建立LL
(1)分析表。
2、输出分析过程。
1、掌握和了解语法分析过程,学会如何根据语法规则对源程序(输入串)逐一分析词法时得到的属性字,检查语法错误,确定语法结构。
2、了解几种常用的语法分析方法。
3、熟悉和了解LL
(1)分析方法的逻辑结构、LL
(1)分析过程和LL
(1)分析表的构造方法。
4、掌握自顶向下的分析技术,用LL
(1)分析方法进行语法分析。
根据某一文法编制调试LL
(1)分析程序,以便对任意输入的符号串进行分析。
加深对预测分析LL
(1)分析法的理解。
实验预习提示
1、LL
(1)语法分析程序概述:
LL
(1)语法分析程序以单词串形式的源程序作为输入或分析的对象。
它的基本任务是:
根据语言的语法规则(即根据描述该语言的前后文无关文法),分析源程序的语法结构,即分析如何由这些单词组成各种语法范畴(如下标变量、各种表达式、各种语句、程序段或分程序,乃至整个源程序等等),并在分析过程中,对源程序进行语法检查。
目前,已存在许多语法分析方面的方法。
但就产生语法树的方向而言,可大致把它们分为自顶向下和自底向上两大类。
所谓自顶向下的语法分析,就是对已给的输入符号串w,试图自上而下地为它构造一棵语法树。
LL
(1)语法分析就是此种分析。
2、LL
(1)分析法的功能
LL
(1)分析法的功能:
利用LL
(1)控制程序根据显示栈顶内容、向前看符号以及LL
(1)分析表,对输入符号串自上而下的分析过程。
3、LL
(1)分析法的前提
改造文法:
消除二义性、消除左递归、提取左因子,判断是否为LL
(1)文法。
注意:
1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;
2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);
3.对学有余力的同学,可以事先将测试用的表达式存放在文本文件中,一行存放一个表达式,以分号分隔;
同时将预期的输出结果写在另一个文本文件中,以便与输出结果进行对照。
试处理:
根据LL
(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
LL
(1)方法:
自上而下分析法:
从文法的开始符号出发,反复使用各种产生式,寻找与输入符号匹配的最左推导。
对输入字符串进行分析。
对照规则从左到右扫描输入字符串。
消除文法中的左递归。
消除左递归:
例有一文法:
改写为:
E∷=E+T│TE∷=TE’[1]
T∷=T*F│FE’∷=+TE’[2]|ε[3]
F∷=(E)│iT∷=FT’[4]
T’∷=*FT’[5]|ε[6]
F∷=(E)[7]|ε[8]
LL
(1)方法产生LL分析表;
而LL
(1)方法则不能判断每个产生式的结束;
LL
(1)方法要用符号栈。
因此在做语法分析时要建立分析表,根据建立的分析表,对输入串I+I*I^I-I/I进行语法分析,判断其是否符合文法;
再根据分析表中的匹配关系编写出语法分析程序。
分析表的建立:
分析表是指分析棧中元素与输入串中元素的一种匹配关系。
在语法分析中利用分析表对输入串进行分析。
对当前输入的字符串中字符ai与分析棧顶符号X1比较分析,由分析表来决定选择某种规则进行推导,按分析表进行某种相应的操作。
建立分析棧:
文法识别开始符号#和识别符号E首先进分析棧,在分析棧中每读入一个字符都与分析棧顶符号进行比较分析。
当棧顶符号与当前输入串中的符号ai相匹配,则将棧顶符号从棧顶删除。
并应把规则右部的产生式逆代入到分析棧中(逆推入分析棧,替换分析棧中的X1)。
LL
(1)分析的动作
●替换:
当X1VN时选相应候选式去替换X1。
●匹配:
当X1VT时它与Y1进行匹配,其结果可能成功,也可能失败,如果成功则去掉X1和Y1,否则报错。
●接受:
当格局为(空,空)时报分析成功。
●报错:
出错后,停止分析。
LL
(1)分析例1:
有一个文法G:
文法G[A]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理