编译原理课程设计教案Word格式.docx
《编译原理课程设计教案Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计教案Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
2
//输入字符的种类:
d
和
.
DIGIT
0
//输入数字在状态表中位于第0列
//State[][]为状态表,以整数组形式存放,0,1,2,3表示状态,-1表示没有此状态
int
State[STATE_NUMBER][CHAR_NUMBER]=
{{1,-1},{1,2},
{3,-1},
{3,-1}};
Q[STATE_NUMBER]
=
{0,1,0,1};
//终态标志:
0非终态,1终态。
//缓冲区:
//输入缓冲区:
由专门函数操作(ReadALine(),GetChar())
BUFFER_SIZE
1000
//表达式缓冲区大小
char
Buffer[BUFFER_SIZE];
//表达式缓冲区,以'
\0'
表示结束
ipBuffer
0;
//表达式缓冲区当前位置序号
ch;
//存放取得的一个字符
//函数声明:
bool
Run();
//对存储在缓冲区的一行字符串(以'
#'
结束)进行运行
void
Init();
//全局初始化
ReadALine();
//从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中
GetChar();
//从缓冲区取一个字符,返回该字符的同时将它存于全局变量ch中
//主程序:
main()
{
while(ReadALine())
//读一行成功,对它进行判断
if(Run())
//对该行进行运行,看是否能被接受?
printf("
接受\n\n"
);
else
不接受\n\n"
}
//返回:
如果是无符号定点实数,返回true;
否则返回:
false
Run()
S=0;
//S存放运行时的当前状态,目前为初态
while(GetChar()!
='
)
if(ch
>
'
0'
&
ch<
9'
)
S
State[S][DIGIT];
//将状态转换成输入后的状态
//其他都为非法字符
return
false;
if(S
==
-1)
//处于非法状态
//运行结束,判断S是否为终态
if(Q[S]
1)
//终态
true;
//非终态
Init()
//好像无需初始化
程序功能:
输入一个字符串,判断它是否是a。
\n"
======================================================\n\n"
//从键盘读一行(没有空格),存于表达式缓冲区Buffer[]中,以'
结束,并置ipBuffer=0;
//读到非空字符串:
返回
true;
读到单独的“#”:
ReadALine()
l;
请输入以\"
#\"
号结束的无空格字符串:
"
scanf("
%s"
Buffer);
l
strlen(Buffer);
//读入的字符串的长度
if(l
0)
//输入了空字符串,重新输入
if(Buffer[0]
//输入单独的'
表示不再输入
Buffer[l]
;
//最后一个字符用结束标记'
代替(本来是'
//初始化缓冲区指针
//成功:
返回字符;
不成功:
返回'
GetChar()
if((ch
Buffer[ipBuffer])
!
++;
课题二:
简单词法分析器设计(C或C++)
二、设计目的要求:
1、目的:
通过设计、编程、调试出一个具体词法分析程序,加深对词法分析原理的理解,掌握其设计方法。
2、要求:
1)整理出所有单词符号及内部表示
分类:
各关键字、标识符、运算符、分界符、常数
2)画出状态转换图
3)编程。
要求用自动机的方法进行编程。
①预处理,去除注释、多余空格、回车换行符等。
②词法分析程序能通过实例数据的测试。
备注:
设计词法分析程序时,应考虑能为语法分析程序调用。
4)写出设计报告,内容为:
状态转换图、单词符号及内部表示、符号表、出错处理、编程方法等。
三、实验内容:
选择一个词法分析方法,编写一个的词法分析器,对下面的实例进行测试。
测试用例:
programtestexample;
{读入一组整数,统计并输出:
其中非负整数之和,整组数的10倍平均值}
vark,sum1,sum2,x:
int;
constnum=20,times=10;
begin
sum1:
=0;
sum2:
k:
=num;
whilek>
=1do
read(x);
ifx>
=0
thensum1:
=sum1+x;
sum2:
=sum2+x;
=k-1;
end;
write(sum1,times*sum2/num);
end.
算法思想、程序流程图、不要写代码)
利用单词的构成规则,对输入的字符串进行分析再归类即可。
(流程图学生自己画)
课题三:
语法分析器的设计
通过设计、编程、调试出一个具体语法分析程序,能调用词法分析程序为其提供单词符号串,进行语法分析,掌握语法分析方法和程序设计方法。
任选一种语法分析方法进行程序设计,语法分析程序能通过实例数据的测试。
写出设计报告,内容为:
所选的语法分析方法、算法、改写的文法、符号表、出错处理、编程方法等。
SPL语言的文法
程序>
:
:
=<
程序首部>
<
说明部分>
程序主体>
=program<
标识符>
;
*:
字母>
┃<
字母数字串>
=a┃b┃┅┃y┃z
数字>
=0┃<
非0数字>
=1┃┅┃8┃9
=var<
变量组>
int;
┃const<
常量组>
┃var<
const<
<
=<
整数>
数字串>
=begin<
执行语句>
end.
语句>
赋值语句>
条件语句>
循环语句>
读语句>
写语句>
复合语句>
表达式>
+<
项>
-<
*<
因子>
/<
=(<
)┃<
=if<
关系符>
then<
==┃>
┃>
=┃<
=while<
do<
=read(<
=write(<
表达式组>
end
【备注】1.SPL语言源程序格式自由;
2.SPL语言源程序中可以插入注解,用“{”、“}”括起来。
测试用例同课题二
根据自己选择语法分析方法(LL
(1)、LR(0)、OPG),先设计分析表再设计主控程序。
(LL
(1))主要算法:
构造算符优先分析表的算法以下几个步骤:
(1)构造文法G中非终结符号的FIRSTVT集合
FIRSTVT集合用一个整型二维数组F[q][f]表示,其值为0或1。
F是一个q*f的二维数组(q=文法G中非终结符号个数,f=文法G中终结符号个数)。
对于文法G的所有终结符,构造数组F[q][f]的算法(该算法使用一个STACK栈,用于存放含有一个非终结符和一个终结符对的结构体X。
)如下:
BEGIN
for任何非终结符P和终结符a对(P,a)
确定P在非终结符数组VN[]中的位置q1和a在终结符数组VT[]中的位置f1
F[q1][f1]=0;
for任何形如P-》a…或P-》Qa…的产生式
IFNOTF[q1][f1]F[q1][f1]=0;
将(P,a)放入结构体x;
X进STACK栈;
END
WHILESTACK栈非空
将STACK栈的栈顶元素出栈
FOR每个形如Q-》P…的产生式
确定Q在非终结符数组VN[]中的位置q2
IFNOTF[q2][f1]
BEGIN
F[q2][f1]=1;
将(Q,a)放入结构体X;
END.
(2)构造文法G中非终结符号的LASTVT集合
类似于构造FIRSTVT集合,LASTVT集合用一个整型数组L[P,a]表示,其值为0或1。
L是一个q*f的二维数组(q=文法G中非终结符号个数,f=文法G中终结符号个数)。
对于文法G的所有终结符,构造数组L[q][f]的算法(该算法法使用一个STACK栈,用于存放含有一个非终结符和一个终结符对的结构体D。
BEGIN
确定P在非终结符数组VN[]中的位置q1和a在终结符数组VT[]中的位置f1
L[q1][f1]=0;
for任何形如P-》…a或P-》…Qa的产生式
IFNOTL[q1][f1]L[q1][f1]=0;
将(P,a)放入结构体d;
D进STACK栈;
FOR每个形如Q-》…P的产生式
IFNOTL[q2][f1]
L[q2][f1]=1;
将(Q,a)放入结构体D;
(3)构造文法G的优先关系表
使用文法G中任何非终结符号的FIRSTVT集合和LASTVT集合,可以构造文法G的优先关系表。
优先关系表用一个二维字符数组Z[][]表示,Z是一个f*f的数组(f=文法G中终结符号个数)。
Z表的值为‘0’、‘》’、‘《’或‘=’。
构造优先关系表Z[][]的算法如下:
{FOR每个形如产生式P-》Qa…或P-》…Qa
{在lastvt集的数组L[][]中确定Q对应的行元素值为1的下标j和a对应的列的下标l;
在算符优先表的数组Z[][]中,将Z[j][l]的值置‘》‘;
FOR每个形如产生式P-》aQ…或P-》…aQ
{在firstvt集的数组F[][]中确定Q对应的行元素值为1的下标j和a对应的列的下标l;
在算符优先表的数组Z[][]中,将Z[j][l]的值置‘《‘;
FOR每个形如产生式P-》…ab…或P-》…aQb…
{在终结符号集合的数组中找到a,b所对应的下标j,k;
在算符优先表的数组Z[][]中,将Z[j][l]的值置‘=‘;
}
(4)判别文法G是否为算符优先文法
2.设计算符优先分析程序的算法
(1)判别输入串是否为文法G的句子
根据查找最左子素短语的方法,得到算符优先分析算法如下:
在算法中使用了一个符号栈B,用来存放终结符和非终结符,k代表符号栈S的使用深度:
{WHILE文法G为算符优先文法
DO{
将字符串放入数组string[]中;
K=0,初始化栈B[k]=’#’;
把当前字符读入字符变量a中;
IFS[k]为终结符J=k
ELSEJ=K-1
找出B[k]所对应的终结符及a所对应的终结符在Z[][]中的位置q,q3
IFZ[q][q3]==’=’或’<
’K=k+1,B[k]=a入栈
ELSE打印“出错”
WHILEZ[q][q3]==‘》’
{DO{
R3=B[j]并找出r3在VT[]中的位置q5;
IFB[j-1]属于VT[]J=J-1;
ELSEJ=J-2;
找出B[j]在VT[]中的位置q6;
WHILE(Z[q6][q5]==‘=’)
{将B[j+1]…B[k]归约为N
k=j-1;
B[k]=N;
WHILE(a!
=’#’)
IF(a==’#’)输出“YES”
ELSE输出“NO”
(LR(0))主要算法:
·
求解闭包算法:
⑴ch赋值为所求产生式圆点后的字符。
⑵从第一个产生式开始,遍历所有文法产生式,对行如E->
.a的项目,
E==ch,且原闭包集中不含此项目,执行(3),(4),否则返回。
3将该产生式加入该闭包。
4递归调用闭包算法对新加入产生式进行闭包运算。
求解Go集合算法
1ch赋值为吸收字符
2遍历该项目集的所有项目,对行如E->
a.bB的项目,b==ch,创建新项目集并将该项目加入新项目集。
3如若该新项目集已存在,撤消,否则返回新项目集下标。
求项目集算法
4对零项目求解求解闭包,得出项目集
5对项目集
求解Go集,得出新产生项目集的最大下标i;
⑸从项目集
到项目集
依次编历各项目集,求解该项目集闭包和该项目集Go集,
在此步中i值可能发生变化.
构表算法
①对项目集
的每个项目圆点后的字符
②如果为空,判断是否为结束产生式,则将相应数组元素赋值abc
③否则为规约项目,赋相应
④如果为大写字母,则为移进项目,通过判断Go()求得I,赋相应I;
⑤否则,通过判断Go()求得I,赋相应
。
(OPG)主要算法和数据结构:
算符优先分析法是一种简单且直观的自下而上分析方法,特别适合于分析程序语言中的各类表达式,并且宜于手工实现。
算术优先分析,是依照算术表达式的四则运算过程来进行语法分析。
通常在算术表达式求值过程中,运算次序是先乘除后加减,这说明了乘除运算的优先级高于加减运算的优先级,乘除为同一优先级但运算符在前边的先做,这称为左结合,同样加减运算也是如此,这也说明了运算的次序只与运算符有关,而与运算对象无关,因而直观算符优先分析法的关键是对一个给定文法G,人为地规定其算符的优先顺序,即给出优先级别和同一个级别中的结合性质,算符间的优先关系表示规定如下:
a
b表示a的优先性低于b。
b表示a的优先性等于b,即与b相同。
b表示a的优先性高于b。
但必须注意,这三个关系和数学中的<,=,>是不同的。
当有关系a
b时,却不一定有关系b
a,当有关系a
b时,却不一定有b
a,例如:
通常表达式中运算符的优先关系有+
-,但没有-
+,有'
('
)'
,但没有'
即这种分析方法要预先规定运算符(确切地说是终结符)之间的优先关系和性质,然后借助于这种关系来比较相邻运算符的优先级,以确定句型的“可归约串”来进行归约。
定义:
设有一文法G,如果G中没有形如A→…BC…的产生式,其中B和C为非终结符,则称G为算符文法例如:
表达式文法E→E+E|E*E|(E)|i
其中任何一个产生式中都不包含两个非终结符相邻的情况,因此该文法是算符文法
1)文法
2)算法:
FIRSTVT;
LASTVT;
优先关系表;
判断G是否是算符优先文法
3)构造算符优先表程序设计:
G的产生式存储和输入,可以定义、、;
所涉及的主要数据结构(FITSTVT和LASTVT集合;
STACK栈
主要数据结构
1算符文法G的产生式存储和输入
定义一个二维数组p[10][10]存储G的产生式,h为产生式的个数,其元素为字符数组,每行字符存放的字符串最长为10,每一行存放一个产生式,算符文法G的产生式可以通过键盘,以字符方式输入,每个产生式以“#”结束。
2所涉及的主要数据结构
①firstvt集合和lastvt集合;
用整形数组f[p,a]和l[p,b]表示,都是a*b的二维数组,(a为文法中非终结符的个数,b为文法中终结符的个数),其中p属于N,a属于T,输出的第一行T表示所有终结符,第一列N表示所有的非终结符.
②优先关系表用一个数组k[a,b]表示,k是一个b*b的二维数组(b为文法的终结符的个数),其元素为二维字符数组,每个字符数组所存的字符串的长度为1,其中a,b属于终结符,r[a,b]=’=’,’<
’,’>
’,或为空,数组r[a,b]类型为字符型.输出时,第一行T表示所有的终结符,第二行T表示所有的终结符.
③一维数组T[n]存放所有的终结符,一维数组N[a]存放所有的非终结符,变量a,b分别表示非终结符,终结符.一维数组A[n]表示每个产生式的第一个字符在非终结符N[n]中的位置,B[n]表示没一个产生式的个数,f[p,a]为字符型,表示a是否是p的firstvt,l[p,a]为字符型,表示a是否为p的lastvt,k[a,a]表示终结符存在那种关系;
’=’,,’<
’或空,如果存在两种对应关系,则说明该文法不是算符优先文法。
课题四:
WHILE循环语句的翻译程序设计
WHILE循环语句的翻译程序设计
1、写出符合题目要求的文法及属性文法。
2、完成题目要求的中间代码三地址表示的描述。
3、写出递归下降法的思想,完成语法分析和语义分析程序设计。
4、编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
5、设计报告格式按要求书写。
课程设计报告书正文的内容应包括:
1系统描述(问题域描述);
2文法及属性文法的描述;
3语法分析方法描述及语法分析表设计;
4给出中间代码形式的描述及中间代码序列的结构设计;
5简要的分析与概要设计;
6详细的算法描述(流程图或伪代码);
7给出软件的测试方法和测试结果;
8研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);
按照课程设计的要求,写一个能识别while循环语句的文法,通过一定的变换使它符合递归下降法的要求,然后按照这个文法编写一个程序,该程序能识别输入的语句是否符合while语句的文法,或者能不能通过文法的开始符号推导出该语句。
该程序应该包括词法分析器,能对输入的语句进行词法分析,然后再对结果进行语法分析。
词法分析器应能识别关键字,标示符,常量,操作符等。
该程序的语法分析器能对输入的语法进行分析,判断输入语句能否满足while循环语句的文法。
通过递归下降的方法对语句进行分析,看能否通过开始符号推导出来。
该程序的语义分析器就是对分析结果进行输出,要求输出结果是三地址形式的。
1、文法描述
while语句>
=while(<
条件表达式>
)(<
|<
|<
无符号整数>
)<
条件运算符>
(<
=>
|=
(<
=(<
)<
算术运算符>
=+|-|