当前位置: 首页 > 其他范文 > 其他范文

编译原理实验_词法分析实验-LL1文法分析实验

作者:pp79 | 发布时间:2020-11-20 18:23:36 收藏本文 下载本文

……………第一针…………装 订 线……………第二针………… 课程名称 编译原理 学号 XXX 学生姓名 XXX 教师 XXX 专业 计算机科学 实验 地点 家 实验时间 200 20 年 年 5 5 月 月 1 15 5 日 开发环境 软、硬件 :

软件 开发语言 :C C ++ 开发环境: : 4 windows10 64 位 实验 一 名称 词法分析程序(2 学时)实验目的 理解词法分析在编译程序中的作用;加深对有穷自动机模型的理解; 掌握词法分析程序的实现方法和技术。

实验 内容 选择部分 C 语言的语法成分,设计其词法分析程序,要求能够识别关键字、运算符、分界符、标识符、常量(至少是整型常量,可以自己扩充识别其他常量)等,并能处理注释、部分复合运算符(如>=等)。单词以二元式形式输出、输出有词法错误的单词及所在行号。

实验 要求(1)待分析的简单的语法 关键字:begin if then while do end … 运算符和界符::= +-* / < <= > >= <> = ==;()# , … 其他单词是标识符 id 和整型常数 num,通过以下正规式定义:

id=l(l|d)*(l:letter d:digit)num=dd* 空格、注释:在词法分析中要去掉。

(2)各种单词符号对应的种别编码(参考这张表,可以不同)种别编码略有改动(3)待分析的源程序:

(a)int main(){ { int a=1,b=2;b b /a;/* 注释部分 */ b>a;c=a+b;cout<0)){ { if((2x = = = 7 7))i3=z;} } 核心 代码 :

(按模块顺序,每一个模块先做简要 功能 说明 及输入输出介绍,再附核心代码,如果只有代码,没有说明,酌情减分)核心代码中附带解释的注释 #include #include using namespace std;//关键字 string key[10]={"begin","if","then","while","do","end","int","main","return","cout"};//关键字的种别码 int keyNum[10]={1,2,3,4,5,6,7,8,12,13};//运算符和界符 string symbol[25]={"=","==","+","-","*","/","","(",")","[","]","{","}",",",":",";",">","<",">=","<=","!=",""","#","!","<<"};//运算符和界符的种别码 int symbolNum[25]={18,21,22,23,24,25,1000,26,27,28,29,30,31,32,33,34,35,36,37,38,40,41,0,-1,42};//存放文件取出的字符 string letter[1000];

//将字符转换为单词 string words[1000];length;//保存程序中字符的数目 int num;// 程序中字符的指针 //判断运算符和界符,返回种别码,没有就返回 0 int isSymbol(string s){ int i;for(i=0;i<25;i++){ if(s==symbol[i])return symbolNum[i];} return 0;} /** 判断是否为数字 输入:字符串 返回:布尔值 */ bool isNum(string s){ if(s>="0" && s<="9")return true;} /** 判断是否为字母 输入:字符串 返回:布尔值 */ bool isLetter(string s){ if(s>="a" && s<="z")return true;} /** 判断是否为关键字 输入:字符串 返回:是返回关键字的种别码,否返回 0 */ int isKeyWord(string s){ int i;for(i=0;i<10;i++){ if(s==key[i])return keyNum[i];

} return 0;} /** 返回单个字符的类型 输入:字符串(只有一个字符)返回:1 是字母,2 是数字,3 是“/”,4 是运算符和界符 */ int typeword(string str){ if(str>="a" && str<="z")// 字母 return 1;if(str>="0" && str<="9")//数字 return 2;if(str=="/")return 3;if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}" ||str=="+"||str=="-"||str=="*")//判断运算符和界符 return 4;} /** 功能:从输入流中提取出关键字返回 输入参数:字符串(只包含起始字符),以及起始字符所在输入流中的位置 返回:字符串,提取成功的关键字 */ string identifier(string s,int n){ j=n+1;int flag=1;while(flag){ if(isNum(letter[j])|| isLetter(letter[j])){ s=(s+letter[j]).c_str();if(isKeyWord(s)){ j++;num=j;return s;} j++;} else{

flag=0;} } num=j;return s;} /** 功能:从输入流中提取出符号 输入参数:字符串(只包含起始字符),以及起始字符所在输入流中的位置 返回:字符串,提取成功的符号串 */ string symbolStr(string s,int n){ int j=n+1;string str=letter[j];if(str==">"||str=="="||str=="<"||str=="!"){ s=(s+letter[j]).c_str();j++;} num=j;return s;} /** 功能:从输入流中提取出注释的内容 输入参数:字符串(只包含起始字符),以及起始字符所在输入流中的位置 返回:字符串,提取成功的注释 */ string get_note(string s,int n){ int j = n+1;if(letter[j]=="*"){ s=(s+letter[j]).c_str();j++;while(!(letter[j]=="*"&&letter[j+1]=="/")){ //如果没找到注释的终结就一直找 s=(s+letter[j]).c_str();j++;} * 加上 s=(s+letter[j++]).c_str();// 把 / 加上 num = j;return s;} }

/** 功能:从输入流中把数字提取出来 输入参数:字符串(只包含起始字符),以及起始字符所在输入流中的位置 返回:字符串,提取成功的数字 */ string Number(string s,int n){ j=n+1;int flag=1;while(flag){ if(isNum(letter[j])){ s=(s+letter[j]).c_str();j++;} else{ flag=0;} } num=j;return s;} void print(string s,int n){ cout<<"("<

print(str1,10);// 返回种别码是 10,这个是标识符 break;case 2: str1=Number(str,num);print(str1,20);// 返回种别码是 20,这个是无符号数字 break;case 3: // 以“/”开头很可能是注释,下面判断 if(letter[num+1]=="*"){ str1 = get_note(str,num);print(str1,43);} else{ // 不是注释就采用和 4 一样的符号类型返回 str1=symbolStr(str,num);print(str1,isSymbol(str1));} break;case 4: str1=symbolStr(str,num);print(str1,isSymbol(str1));break;} } } /** 程序的入口 */ int main(){ char w;int i,j;freopen("test.txt","r",stdin);//读取本地文件 可以把结果写到结果文件中去 //freopen("result.txt","w",stdout);//从控制台输出,而不是文本输出 length=0;while(cin>>w){ if(w!=" "){ tter[length]=w;length++;} //去掉程序中的空格 } TakeWord();// 词法分析入口 fclose(stdin);//关闭文件

fclose(stdout);//关闭文件 return 0;} 运行结果 :(截图)词法分析结果:

(注释可以忽略,这里显示了)

实验二名称 预测分析程序(2 学时)实验目的 掌握 LL(1)文法分析思想;掌握预测分析程序的构造方法。

实验内容 设计及实现能够识别表达式的预测分析程序。

实验要求(1)总体要求:

1)根据文法手工或程序方式构造预测分析表; 2)采用程序方式构造预测分析表时,需计算 First()和 Follow()集合,有一定难度; 3)根据预测分析表,设计并实现预测分析总控程序,完成自上而下的语法分析器。

(2)文法的定义(可以选择此文法,也可以自己选择其他文法)

(3)给出当输入串为:(i 1 +i 2)*(i 3 +i 4)的分析过程。(输出分析过程中的栈,输入串和利用的产生式等信息)核心代码 :

(按模块顺序,每一个模块先做简要功能说明及输入输出介绍,再附核心代码,如果只有代码,没有说明,酌情减分)预测分析表 :(为了方便 M M 代表 E ES ’,S 代表 T T ’)预测分析表程序中的部分 核心 代码(注:

模块的具体功能输入输出在模块前注释体现)#include

dio.h> ring> #include //从文件中读取到所要分析的语句 char statement[20] = " ";// 文件中语句的指针 int index = 0;//非终结符表 , 为了编程方便,使用 M 代表 E", S 代表 T" char NN[5] = { "E","M","T","S","F" };//非终结符的个数,有 5 个 int nnLength = 5;//终结符表 char TT[6] = { "i","+","*","(",")","#" };//终结符的个数,有 6 个 int ttLength = 6;/** 产生式表: 0->TE" 1+TE" 2E"->空 3->FT" 4*FS 5T"->空 6(E)7: F->i */ // 产生式表的左部 char CreateL[8][5] = { "E->","M->","M->","T->","S->","S->","F->","F->" };// 产生式表的右部 char CreateR[8][10] = { "TM","+TM","","FS","*FS","","(E)","i" };/** 预测分析表:-2 不属于终结符的 follow set-1 : 该行终结符的 follow 集合 注:-1 和-2 作为出错处理 非负数: CreateR 数组中的编号。

*/ int ANA_TABLE[5][6] = { { 0,-2,-2,0,-1,-1}, {-2,-2,2,2 }, {3,-1,-2,3,-1,-1},-2,5, 4,-2,5, 5}, { 7,-1,-1,6,-1,-1 } };char stack[50];int top =-1;/** 功能:打开文件,找到所要分析的文件,读入到数组缓冲区中使用 输入:本地要分析的语句文件 输出:无 */ void input(){ int i = 0;FILE *fp;if((fp = fopen("E:man.txt", "r"))== NULL){ printf("Open error!");exit(0);} char ch = fgetc(fp);while(ch!= EOF){ statement[i] = ch;i++;ch = fgetc(fp);} fclose(fp);} /** 功能:入栈操作 输入:一个字符(终结符或非终结符)输出:无 */ void push(char a){ top++;

stack[top] = a;} /** 功能:弹栈操作 输入:一个字符(终结符或非终结符)输出:返回一个字符(出栈)*/ char pop(){ return stack[top--];} /** 功能:判断终结符表中是否包含此字符 输入:待判断的字符 输出:0:不包含 1:包含 */ int includevt(char x){ for(int i = 0;i < ttLength;i++){ if(TT[i] == x)return 1;} return 0;} /** 功能:返回预测分析表中的信息,用于下一步的分解 输入:

x:是当前栈顶元素,a:是语句的当前待匹配项 输出:预测分析表的分解指示信息,返回 CreateR 的下标 */ int includean(char x, char a){ int i, j;for(i = 0;i < nnLength;i++)// 非终结符查找 if(NN[i] == x)break;for(j = 0;j < ttLength;j++)// 终结符查找 if(TT[j] == a)break;return ANA_TABLE[i][j];}

/** 分析过程入口函数,从 main 中调用 功能:用于调用各个模块完成语法分析的过程,并打印信息 */ void analysis(){ = 0;int tagg = 0;// 文法开始符和"#"逐个压入栈中 "#");push(NN[0]);// 读入第一个输入符号 a = statement[index];char x;do { if(tag == 0)//把栈顶符号弹出并用 x 保留 x = pop();tag = 0;printf("%cttt%ct", x, a);if(includevt(a)== 1){ if(includevt(x)== 1){ if(x == a){ // 结束标志 if(a == "#"){ tagg = 1;printf("结束n");} else printf("匹配终结符%cn", x);index++;//下一输入符号传给 a 变量 a = statement[index];} else { tag = 1;printf("出错,跳过%cn", a);index++;

a = statement[index];} } else if(includean(x, a)>= 0){ int h = includean(x, a);printf("展开非终结符%s%sn", CreateL[h], CreateR[h]);int k;for(k = 0;k < 10;k++)if(CreateR[h][k] == "")break;if(k == 4){ // printf("+++++++++++pop %c n",x);} else { //逆序逐个把 yk、yk?1、…、y1 压入栈中 while(k!= 0){ k--;push(CreateR[h][k]);} } } else if(includean(x, a)==-1){ tag = 1;printf("出错,从栈顶弹出%cn", x);x = pop();} else { tag = 1;printf("出错,跳过%cn", a);index++;a = statement[index];} } else { tag = 1;printf("出错,跳过%cn", a);

index++;a = statement[index];} } while(x!= "#");if(tagg == 0){ %cttt%ct", x, a);printf("结束n");} } /** 功能:主函数,程序的入口 */ int main(){ printf("语法分析结果展示如下:n");// 从文件中读入数据(要分析的语句)input();printf("读入语句数据中......");// 展示结果 要分析的语句是:%sn", statement);分析过程:n");printf("栈顶元素tt 当前单词记号tt 动作n");printf("=========================================================================n");analysis();system("pause");return 0;} 运行结果 :(截图)

格式要求:各单元格 空白行尽量少。

编译原理实验指导书

编译原理实验三

编译原理实验指导书-实验六

直流分析实验

数值分析实验

本文标题: 编译原理实验_词法分析实验-LL1文法分析实验
链接地址:https://www.dawendou.com/fanwen/qitafanwen/244577.html

版权声明:
1.大文斗范文网的资料来自互联网以及用户的投稿,用于非商业性学习目的免费阅览。
2.《编译原理实验_词法分析实验-LL1文法分析实验》一文的著作权归原作者所有,仅供学习参考,转载或引用时请保留版权信息。
3.如果本网所转载内容不慎侵犯了您的权益,请联系我们,我们将会及时删除。

重点推荐栏目

关于大文斗范文网 | 在线投稿 | 网站声明 | 联系我们 | 网站帮助 | 投诉与建议 | 人才招聘 | 网站大事记
Copyright © 2004-2025 dawendou.com Inc. All Rights Reserved.大文斗范文网 版权所有