编译原理实验报告
Compilers Principles Experiment Report
所在学院:
所在班级:
学生姓名:______ _
学
号:__
指导教师:
教 务 处
实验一 词法分析程序
1、实验目的:设计、编制和调试一个具体的词法分析程序,加深对词法分析的理解。
2、要求:
(1)通过对 PL/0 词法分析程序(GETSYS)的分析,编制一个具有以下功能的词法分析程
序:
a. 输入为字符串(或待进行词法分析的源程序),输出为单词串,即由(单
词,类别)
所组成的二元组序列;
b. 有一定的错误检查能力,例如能发现 2a 这类不能作为单词的字符串。
(2)提交设计报告,报告内容包括:
实验目的、要求,算法描述,程序结构,主要变量说明,程序清单,调试
情况,设计技巧,心得体会。
3、算法描述:
首先把常用关键字放在一个数组变量里,逐个判断输入的一个字符串是否为关
键字,然后判断是否为字母,是否为数字,判断是否为标识符的时候需要加入判断
2a 类的标识符不合法。
4、程序结构:
#include
using namespace std;
#define MAX 21
/*
保留字|关键字:1
操作符|运算符:2
分界符:3
标识符:4
常数:5
无识别:6
*/
char ch = ' ';
char* keyWord[21] =
{"iostream","void","int","char","string","bool","return","using","namespace","main",
"break","include","begin","end","if","else","while","switch","for","else if","std"};
char token[20];//定义获取的字符
//判断是否是关键字
bool isKey(char * token)
{
for(int i = 0;i < MAX;i++)
{
if(strcmp(token,keyWord[i]) == 0)
return true;
}
return false;
}
//判断是否是字母
bool isLetter(char letter)
{
if((letter >= 'a' && letter <= 'z')||(letter >= 'A' && letter <= 'Z'))
return true;
else
return false;
}
//判断是否是数字
bool isDigit(char digit)
{
if(digit >= '0' && digit <= '9')
return true;
else
return false;
}
//词法分析
void analyze(FILE *fpin)
{
while((ch = fgetc(fpin)) != EOF){
if(ch == ' '||ch == '\t'||ch == '\n'){}
else if(isLetter(ch)){
//首是字母
//空格 回车
char token[30]={'\0'};
int i=0;
while(isLetter(ch)||isDigit(ch)){
//后面是字母或者数字
token[i] = ch;
i++;
ch = fgetc(fpin);
}
//回退一个指针
fseek(fpin,-1L,SEEK_CUR);
if(isKey(token)){
//关键字
cout<
cout<
cout<<"+"<<"\t\t2"<<"\t 运算符"<
ch = fgetc(fpin);
if(ch == '=')cout<<":="<<"\t\t2"<<"\t 运算符"<
':{
ch = fgetc(fpin);
if(ch == '=')cout<<">="<<"\t\t2"<<"\t 运算符"<"<<"\t\t2"<<"\t 运算符"<>input;
if((fpin = fopen(input,"r")) != NULL)
break;
else
cout<<"路径输入错误"<fclose(fpin);
}
5、主要变量说明:
#define MAX 21 //定义关键字数量
char token[20];//定义获取的字符
char*keyWord[21]={"iostream","void","int","char","string","bool","return
","using","namespace","main","break","include","begin","end","if","else","wh
ile","switch","for","else if","std"};//保存关键字
6、程序清单:
只包含一个 源.cpp 文件
7、调试情况:
完美运行,可以完成词法分析,并且可以判断 2a 标识符不合法
8、设计技巧:
设计判断 2a 不合法的时候,需要在判断首字符为数字的分支下,然后判断后面字符
是否为字母,当为字母的时候,输出不合法。
9、心得体会:
这次项目使我认真学习了词法分析方法,让我对 c++也有了更深的认识,学习到很
多相关知识,了解到了很多和项目相关的函数,查了很多资料,实验过后让我可以根据
自己的不足之处进行认真的学习,更加的充实我自己。
实验二 基于 LL(1)方法的语法分析程序
1、目的:设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。
2、要求:
根据 LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作
为分析算法的输入:
直接输入根据已知文法构造的分析表 M;
b.输入文法的 FIRST(α)和 FOLLOW(U)集合,由程序自动生成文法的分析表 M;
c.输入已知文法,由程序自动构造文法的分析表 M。
程序具有通用性
所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为 LL(1)文
法。
有运行实例
对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的
句子,并要求输出分析过程。
提交实验报告,报告内容参考“词法分析程序”
3、算法描述
预测分析程序的总控程序在任何时候都是按 STACK 栈顶符号 X 和当前的输入符号 a
行事的。如下图所示,对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:
若 X = a = ‘#’,则宣布分析成功,停止分析过程。
若 X = a ≠‘#’,则把 X 从 STACK 栈顶弹出,让 a 指向下一个输入符号。
若 X 是一个非终结符,则查看分析表 M。
若 M[X,a]中存放着关于 X 的一个产生式,那么,先把 X 弹出 STACK 栈顶,然后把产
生式的右部符号串按反序一一推进 STACK 栈(若右部符号为ε,则意味着不推什么东西
进栈)。
在把产生式的右部符号退进栈的同时应该做这个产生式对应的语义动作(目前暂且
不管)。
若 M[X,a]中存放着“出错标志”,则调用出错诊断程序 ERROR。
4、程序结构
#include
#include
#include