《 — 编译原理 —》
实 验 指 导 书
适用专业:
厦 门 理 工 学 院 计 算 机 系 ( 部 )
2010 年 8 月
前 言
1
本课程的基本内容介绍,通过学习学生需要掌握的基本知识。
为了使学生更好地理解和深刻地把握这些知识,并在此基础上,训
练和培养哪些方面的技能,设置的具体实验项目,其中哪几项实验为
综合性、设计性实验。
各项实验主要了解、掌握的具体知识,训练及培养的技能。
本指导书的特点。
对不同专业选修情况说明。
实验 2 :语法分析(预测分析)
2
实验学时:4
实验类型:(演示、验证、综合、设计(√)、研究)
实验要求:(必修)
一、实验目的
通过本次实验的学习,学生需要掌握 LL(1)语法分析原理和方法的基础上,开
发一个简单的预测分析器。
二、实验内容
1、完成以下描述算术表达式的 LL(1)文法的 LL(1)分析程序(LL(1)分析表见教材)。
G[E]:
E→TE′
E′→ATE′|ε
T→FT′
T′→MFT′|ε
F→ (E)|i
A→+|-
M→*|/
说明:终结符号 i 为用户定义的简单变量,即标识符的定义。
三、实验原理、方法和手段
1.基本思想:
LL(1)分析器主要由栈、输入缓冲区、预测分析程序、分析表等四大部分组成。
其中最重要的两个核心部分是预测分析程序和分析表。预测分析程序又称总控程
序,它一方面负责栈中符号的入栈、出栈等功能,另一方面还要读取输入缓冲区
中的符号,并不断更新指向输入缓冲区的指针。分析表是预测分析程序的指示灯,
它指明了每一个状态下预测分析程序应该执行什么动作。预测分析器的工作模型
如图 1 所示:
3
图 1 预测分析器模型
2.基本方法:
构造预测分析表 M[A, a]:
(1)对文法的每个产生式 A ,执行(2)和(3)
(2)对 FIRST()的每个终结符 a,把 A 加入 M[A, a]
(3)如果在 FIRST()中,对 FOLLOW(A)的每个终结符 b(包括$), 把 A
加入 M[A, b]
(4)M 中其它没有定义的条目都是 error
四、实验组织运行要求
老师讲解+学生自主动手实验
1、输入串最好是词法分析的输出二元式序列,即“实验项目 1”的输出结果。
输出为输入串是否为该文法定义的算术表达式的判断结果。
2、LL(1)分析过程应能发现输入串出错。
3、设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。
4、要求有详细实验原理的分析步骤,包括 FIRST、FOLLOW 集合、LL(1)分析
表的构造。
五、实验条件
PC 机一台
六、实验步骤
示例程序:
#include
#include
#include
#include "demo.h"
#define SIZE 100
4
char stack[SIZE];
int bottom = 0, top = 0;
void push(char ch) {
}
char pop() {
}
int get_id(FILE *fp) {
char temp[100];
int id;
fscanf(fp, "%d", &id);
fgets(temp, 100, fp);
return id;
}
void translate(int id, char *a) {
switch(id) {
case 0:
*a = '#';
break;
case 12:
*a = 'i';
break;
case 22:
*a = '+';
break;
case 23:
*a = '-';
break;
case 24:
*a = '*';
break;
case 21:
*a = '/';
break;
}
}
bool is_terminate(char ch) {
if (ch == 'i' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '#')
return true;
return false;
5
}
void trans(char ch, char a, int *i, int *j) {
switch (ch) {
case 'E':
*i = 0;
break;
case 'e':
*i = 1;
break;
case 'T':
*i = 2;
break;
case 't':
*i = 3;
break;
case 'F':
*i = 4;
break;
case 'A':
*i = 5;
break;
case 'M':
*i = 6;
break;
}
switch (a) {
case 'i':
*j = 0;
break;
case '+':
*j = 1;
break;
case '-':
*j = 2;
break;
case '*':
*j = 3;
break;
case '/':
*j = 4;
break;
case '(':
6
*j = 5;
break;
case ')':
*j = 6;
break;
case '#':
*j = 7;
break;
}
}
void search_table(char ch, char a) {
int i, j;
trans(ch, a, &i, &j);
char temp[20] = {'\0'};
strcpy(temp, TABLE[i][j]);
if (strcmp(temp, "~") == 0) {
pop();
return;
}
else if (strcmp(temp, "") != 0) {
pop();
for (unsigned ii = 0; ii < strlen(temp); ii++) {
push(temp[ii]);
}
return;
}
else {
printf("Error!\n");
exit(0);
}
}
void main() {
FILE *in;
int id = 0;
char a = 0;
in = fopen("result.txt", "r");
push('#');
push('E');
id = get_id(in);
translate(id, &a);
7
while (true) {
if (is_terminate(stack[top-1])) {
if (stack[top-1] == a && a == '#') {
printf("success.\n");
return;
}
else if (stack[top-1] == a) {
pop();
id = get_id(in);
translate(id, &a);
}
else {
printf("Error!\n");
return;
}
}
else if (!is_terminate(stack[top-1])) {
search_table(stack[top-1], a);
}
}
fclose(in);
}
七、思考题
无
八、实验报告
按照厦门理工学院实验报告格式,撰写实验报告,每个实验报告最后要写实
验心得。
九、其它说明
学生可以不局限于示例程序,可以自由发挥想象力选择要编写的应用程序,
老师对好的实现给予一定成绩作为奖励。
8