内容目录
编译原理lab5
1. 阅读PL/0编译器源代码(C语言版-仅词语法分析),熟悉该编译程序的整体架构,识别出各语法单位对应的子程序,读懂各子程序之间的调用关系,读懂词法分析程序是如何接入到编译程序主体的。本次实验要求你对PL/0语言进行扩充,使之支持repeat,语法定义如下:<直到型循环语句>::=repeat <语句> until <条件>
下面是PL/0的语法描述图,请画出扩充repeat后的PL/0语法图,只需要画<语句>部分,可使用画图工具,也可手画拍照上传。说明:语法描述图的画法为:


扩充repeat后的PL/0语法图如下:

2. 接上题,请对提供的PL/0编译器源代码(C语言版-仅词语法分析)进行扩充,使之支持repeat(只需要完成词语法分析):(1)提交扩充后的C源程序;(2)自行编写一个含有repeat语句的PL0源程序作为编译器输入,给出输入输出截图。
主要部分修改如下:
#define norw 15 /* 保留字个数,扩充了repeat和until */
/* 符号 */
enum symbol {
nul, ident, number, plus, minus,
times, slash, oddsym, eql, neq,
lss, leq, gtr, geq, lparen,
rparen, comma, semicolon, period, becomes,
beginsym, endsym, ifsym, thensym, whilesym,
writesym, readsym, dosym, callsym, constsym,
varsym, procsym,repeatsym,untilsym
};
/*
* 初始化
*/
void init()
{
int i;
...
/* 设置保留字名字,按照字母顺序,便于二分查找 */
strcpy(&(word[0][0]), "begin");
strcpy(&(word[1][0]), "call");
strcpy(&(word[2][0]), "const");
strcpy(&(word[3][0]), "do");
strcpy(&(word[4][0]), "end");
strcpy(&(word[5][0]), "if");
strcpy(&(word[6][0]), "odd");
strcpy(&(word[7][0]), "procedure");
strcpy(&(word[8][0]), "read");
strcpy(&(word[9][0]), "repeat"); /* 扩充repeat */
strcpy(&(word[10][0]), "then");
strcpy(&(word[11][0]), "until"); /* 扩充util */
strcpy(&(word[12][0]), "var");
strcpy(&(word[13][0]), "while");
strcpy(&(word[14][0]), "write");
/* 设置保留字符号 */
wsym[0] = beginsym;
wsym[1] = callsym;
wsym[2] = constsym;
wsym[3] = dosym;
wsym[4] = endsym;
wsym[5] = ifsym;
wsym[6] = oddsym;
wsym[7] = procsym;
wsym[8] = readsym;
wsym[9] = repeatsym;
wsym[10] = thensym;
wsym[11] = untilsym;
wsym[12] = varsym;
wsym[13] = whilesym;
wsym[14] = writesym;
}
/*
* 语句处理
*/
void statement(int* ptx)
{
int i;
if (sym == ident) /* 准备按照赋值语句处理 */
{
...
}
else
{
if (sym == readsym) /* 准备按照read语句处理 */
{
...
}
else
{
if (sym == writesym) /* 准备按照write语句处理 */
{
...
}
else
{
if (sym == callsym) /* 准备按照call语句处理 */
{
...
}
else
{
if (sym == ifsym) /* 准备按照if语句处理 */
{
...
}
else
{
if (sym == beginsym) /* 准备按照复合语句处理 */
{
...
}
else
{
if (sym == whilesym) /* 准备按照while语句处理 */
{
...
}
else /* 扩充repeat语句 */
{
if (sym == repeatsym)
{
getsym();
statement(ptx);
if (sym == untilsym)
{
getsym();
}
else
{
error(19);
}
condition(ptx);
}
}
}
}
}
}
}
}
}
输入pl/0源程序如下:
const BEGIN=1,END=100;
procedure addup;
var a,b,sum;
begin
a:=BEGIN;
b:=END;
sum:=0;
repeat
begin
sum := sum+a;
a := a+1;
end
until a >= b;
write(sum);
end;
begin
call addup;
end.
输入输出截图如下:

代码链接
https://gitee.com/WilliamSamShen/complier-concepts/tree/master/Lab/lab5