计算机科学与技术系
实 验 报 告
专业名称 计算机科学与技术
课程名称 编译原理
项目名称 LR(1)分析法
班 级
学 号
姓 名
同组人员 无
实验日期 2016.11.4
一、实验目的与要求:
(简述本次实验要求达到的目的,涉及到的相关知识点,实验的具体要求。)
目的:掌握LR(1)分析法的基本原理
掌握LR(1)分析表的构造方法
掌握LR(1)驱动程序的构造方法
要求:
1. 对LR(1)语法规则有明确的定义;
2. 编写的分析程序能够对实验结果进行正确的语法分析;
3. 对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成。
二、实验内容
(根据本次实验项目的具体任务和要求,完成相关内容,可包括:实验目的、算法原理、实验仪器、设备选型及连线图、算法描述或流程图、源代码、实验运行步骤、关键技术分析、测试数据与实验结果、其他)
具体任务:构造LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。
对下列文法,用LR(1)分析法对任意输入的符号串进行分析:
(1)E-E+T
(2)E-E—T
(3)T-T*F
(4)T-T/F
(5)F-(E)
(6)F-i
输出的格式如下:
(1)LR(1)分析程序,编制人:姓名,学号,班级
(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串
(3)输出过程如下:
步骤 | 状态栈 | 符号栈 | 剩余输入串 | 动作 |
1 | 0 | # | i+i*i# | 移进 |
(4)输入符号串为非法符号串(或者为合法符号串)
备注:(1)在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写
明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。
(2) 在此位置输入符号串为用户自行输入的符号串。
l1正则化的作用原理:LR分析方法是已知的最一般的无回溯移进-归约方法,它能够和其他移进-归约方法一样有效地实现。同时利用数据结构中堆栈的性质,来分析一个具体的句型。
步骤:分析一个LR(1)文法的产生式。
正确无误的构造一个LR(1)的项目集。
根据LR(1)的项目集构建LR(1)分析表。
针对具体句型进行实例分析。
关键技术分析:LR(1)文法中只有三个动作:移进,规约和接受,这三个动作也是通过查表得来的额,任何时候如果都是唯一确定这三个动作中的一个,我们就可以让LR(1)文法正确的运行。首先需要构建项目集,才能根据项目集的状态转换构建分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为
动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。而分析器的动作就是由栈顶状态和当前输入符号所决定。
流程图:
代码:
#include<iostream>
#include<stack>
#include<string>
using namespace std;
string action[12][6]={
"S5","0","0","S4","0","0", //ACTION表
"0","S6","0","0","0","acc",
"0","r2","S7","0","r2","r2",
"0","r4","r4","0","r4","r4",
"S5","0","0","S4","0","0",
"0","r6","r6","0","r6","r6",
"S5","0","0","S4","0","0",
"S5","0","0","S4","0","0",
"0","S6","0","0","S11","0",
"0","r1","S7","0","r1","r1",
"0","r3","r3","0","r3","r3",
"0","r5","r5","0","r5","r5"};
int gotoarr[12][3]={1,2,3, //GOTO表
0,0,0,
0,0,0,
0,0,0,
8,2,3,
0,0,0,
0,9,3,
0,0,10,
0,0,0,
0,0,0,
0,0,0,
0,0,0};
char vt[6]={'i','+','*','(',')','#'}; //存放终结符
char vn[3]={'E','T','F'}; //存放非终结符
string Production[6]={"E->E+T","E->T","T->T*F","T->F","F->(E)","F->i"};//产生式集合
int count=0;//记录当前进行处理的输入字符串字符位置
int line=1;//记录处理的步骤数
bool flag=false;
int StatusNumber=1;//栈中状态数
string stacktd="#";//记录符号栈中内容
int Status[50]={0};//记录状态栈
stack <char> Stack;//创建一个符号栈
stack <int> status;//创建一个状态栈
void Judge(int &i,int j,char arr[],char ch,string s){//判断输入串是否由文法终结符组成
flag=false;
for(int l=0;l<j;l++)
{
if(ch==arr[l])
{
flag=true;
i=l;
break;
}
}
if(flag==false)
{
cout<<"\tError"<<endl;
count=s.size();
}
}
void Outputstatus()
{
//输出状态集
for(int i=0;i<StatusNumber;i++)
cout<<Status[i];
}
void Outputstring(string s)
{
//输出未处理的字符串
for(int i=count;i<s.size();i++)
cout<<s.at(i);
}
void Output(string s)
{
//输出步骤、状态集、符号集、输入串
cout<<line<<"\t";
Outputstatus();
cout<<"\t"<<stacktd<<"\t";
Outputstring(s);
cout<<"\t\t";
line++;
}
void Shift(int i,string s)
{//移进函数S
Output(s);
cout<<"ACTION["<&p()<<","<<s.at(count)<<"]=S"<<i<<",状态"<<i<<"入栈"<<endl;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论