• 实验目的

(1)掌握有限自动机这一数学模型的结构和理论,并深刻理解下推自动机在LR分析法中的应用(即LR分析器)。

(2)掌握LR分析法的思想,学会特定分析表的构造方法,利用给出的分析表进行LR分析。

  • 实验内容

根据课堂讲授的形式化算法,编制程序实现对以下语法进行自底向上语法分析的LR分析器,设计分析表,对给出的输入语句进行语法分析,判断是否符合相应的文法要求。

programmain block

block  { stmts }

stmtsstmt stmts | e

stmt id = E ; |  while ( bool )  stmt  |  block

EE+F | F

F​​​​​​​F*G | G

G​​​​​​​(E) | T

bool ​​​​​​​ T <= T |T >= T |T

T ​​​​​​​ id | num

  • 实验要求

要求实现以下功能:

a) 设计分析表和语句的输入;

b) 要实现通用的LR分析思想的源代码;

c) 输出对语句的语法分析判断结果,如果可能给出错误的信息提示。

  • 算法分析

根据课本的LR分析器模型和LR分析算法,完成LR分析。对要求中的错误信息提示,指的是对应分析表中的空白处,每一个空白的地方都应该有对应的错误情况,因而有相应的错误信息。注意这里的语法分析,是在词法分析的基础上进行的。

#include<iostream>
#include<malloc.h>
using namespace std;
#define MAX 20
int table[12][9]=
{{5,-1,-1,4,-1,-1,1,2,3},{-1,6,-1,-1,-1,12,-1,-1,-1},{-1,22,7,-1,22,22,-1,-1,-1},{-1,24,24,-1,24,24,-1,-1,-1},{5,-1,-1,4,-1,-1,8,2,3},{-1,26,26,-1,26,26,-1,-1,-1},{5,-1,-1,4,-1,-1,-1,9,3},{5,-1,-1,4,-1,-1,-1,-1,10},{-1,6,-1,-1,11,-1,-1,-1,-1},{-1,21,7,-1,21,21,-1,-1,-1},{-1,23,23,-1,23,23,-1,-1,-1},{-1,25,25,-1,25,25,-1,-1,-1}
};
struct rule{char x;int y;
}r[6]={{'E',3},{'E',1},{'T',3},{'T',1},{'F',3},{'F',1}};
char index_char[9]={'i','+','*','(',')','#','E','T','F'};
int get_index_char(char i)
{for(int j=0;j<9;j++){if(index_char[j]==i)//检测是否是index_char中的字符 return j; }return -1;
}
typedef struct{int stack[MAX];int top;
}status;
void init_stack(status*p)//状态栈的初始化
{if(!p)cout<<"初始化状态栈出错!\n";p->top=-1;
}
void push(status*p,int x)//入栈
{if(p->top<MAX-1)//检测栈是否已满 {p->top++;//未满则推送入栈 p->stack[p->top]=x;}else cout<<"\n状态栈溢出!\n";//满则显示溢出
}
int pop(status*p)//出栈
{int x;if(p->top!=0)//检测栈是否已空 {x=p->stack[p->top];//为空,则将栈顶的x推送出栈 p->top--;return x;}else//空,则显示状态栈已空 {cout<<"\n状态栈1空!\n";return 0;}
}
int get_top(status*p)
{int x;if(p->top!=-1){x=p->stack[p->top];return x;}else{cout<<"\n状态栈2空!\n";return 0;}
}
void out_stack(status*p)
{int i;if(p->top<0){cout<<"\n状态栈3空!\n";}for(i=0;i<=p->top;i++){cout<<p->stack[i];}
}typedef struct{char stack[MAX];int top;
}symbol_instr;
void init_stack(symbol_instr*p)//符号栈、输入串初始化
{if(!p)cout<<"\n初始化状态栈出错!\n";p->top=-1;
}
void push(symbol_instr*p,char x)//入栈
{if(p->top<MAX-1)//检测栈是否已满 {p->top++;//未满,则将x送入栈中 p->stack[p->top]=x;}else cout<<"\n状态栈溢出!\n";//满,则显示符号栈或输入串溢出
}
char pop(symbol_instr*p)
{char x;if(p->top!=-1){x=p->stack[p->top];p->top--;return x;}else{cout<<"符号栈1空!\n";return 0;}
}
char get_top(symbol_instr*p)
{char x;if(p->top!=-1){x=p->stack[p->top];return x;}else{cout<<"符号栈2空!\n";return 0;}
}
void out_stack1(symbol_instr*p)
{int i;if(p->top<0){cout<<"符号栈3空!\n";}for(i=0;i<=p->top;i++){cout<<p->stack[i];}
}
void out_stack2(symbol_instr*p)
{int i;if(p->top<0){cout<<"符号栈4空!\n";}for(i=p->top;i>=0;i--){cout<<p->stack[i];}
}
void print(status*status_p,symbol_instr*symbol_p,symbol_instr*instr_p)
{int i;out_stack(status_p);for(i=0;i<20-status_p->top;i++)cout<<" ";out_stack1(symbol_p);for(i=0;i<20;i++)cout<<" ";out_stack2(instr_p);cout<<endl;} int goto_char(status*status_p,symbol_instr*instr_p){char x;int y,z;x=get_top(instr_p);y=get_top(status_p);z=get_index_char(x);return table[y][z];}
void action(status*status_p,symbol_instr*symbol_p,symbol_instr*instr_p)
{int i,j,x;char a;i=goto_char(status_p,instr_p);if(i==-1)cout<<"归约出错!\n";if(i==12)cout<<"归约成功!\n";if(i>=0&&i<=11){push(status_p,i);a=pop(instr_p);push(symbol_p,a);print(status_p,symbol_p,instr_p);action(status_p,symbol_p,instr_p);}if(i>=21&&i<=26){x=r[i-21].y;for(j=0;j<x;j++){pop(status_p);pop(symbol_p);}push(instr_p,r[i-21].x);action(status_p,symbol_p,instr_p);}
}int main()
{char x;status*status_p;//状态栈 symbol_instr*symbol_p,*instr_p;//符号栈、输入串/*分配长度为sizeof(ststus)字节的内存块 如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 当内存不再使用时,应使用free()函数将内存块释放。*/status_p=(status*)malloc(sizeof(status));symbol_p=(symbol_instr*)malloc(sizeof(symbol_instr));instr_p=(symbol_instr*)malloc(sizeof(symbol_instr));init_stack(status_p);init_stack(symbol_p);init_stack(instr_p);push(status_p,0);//为状态栈送入初始状态 0 push(symbol_p,'#');//为符号栈送入栈底符号 # cout<<"请输入要归约的输入串,以'#'字符结束!\n"; do{x=getchar();if(x!=' '||x!='\t'||x!='\n')//当输入字符不为空格、回车、制符表时,存入栈中 push(symbol_p,x);}while(x!='#');while(symbol_p->top!=0)//当栈不为空时 {x=pop(symbol_p);//从符号栈读取 push(instr_p,x);//送入输入串 }cout<<"\n\n";cout<<"\n状态栈              符号栈                输入串\n";print(status_p,symbol_p,instr_p);action(status_p,symbol_p,instr_p);return 0;
}

运行结果:

C++:编译实验之LR分析器相关推荐

  1. [编译原理]构造LR分析器和SLR移进归约分析表

    目录 目标 1.基础知识引入 1.1 文法 1.2 拓广文法 1.3 全部的项目集 2. 计算文法的LR(0)项目集的.识别活前缀的DFA 2.1 分析得到各个项目集 2.2 构建SLR分析表中的移进 ...

  2. 实验三 lr分析器的设计与实现_实验室规划设计趋势之一灵活性|无风管通风柜的灵活性是如何实现的?...

    点击上方蓝字关注 "法国依拉勃" "成功的空间是灵活的", 可以响应当前需求并能够适应未来需求的空间. 科学是不断发展和快速变化的领域, 实验室是需要大量财务投 ...

  3. 实验三 lr分析器的设计与实现_三电平ZVS半桥的控制模型与仿真 基于PSPICE

    前言: 因为最近有研究一些三电平的东西,所以找出了15年写的TL移相桥的文章,也算是旧文新发.必须要说的,5年前水平有限哈(但是蛮认真的),如果有错误请见谅. 正文:3650字 22图  预计阅读时间 ...

  4. 贵州大学-编译原理实验2-句法分析器

    贵州大学-编译原理实验2-句法分析器 考虑下面的C语言子集的文法,其中<>括起来的为非终结符,粗体为终结符. ® <statement_list> <statement_ ...

  5. java实验文法报告_西安邮电大学编译原理LL文法分析器实验(java).doc

    西安邮电大学编译原理LL文法分析器实验(java) <编译原理>实验报告 题目: 语法分析器的制作 学生姓名: 班 级: 软件1202 学 号: 指导教师: 成 绩: 西安邮电大学计算机学 ...

  6. 编译原理 实验三 LR(1)分析法 Java

    1. 实验目的 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法. 2. 实验内容 对下列文 ...

  7. 编译原理实验三 LR(1)分析法

    实验三 LR(1)分析法 构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文 法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的 语法分析方法. 二.实验内 ...

  8. 编译原理实验-LL1语法分析器(自动生成First集、Follow集求法)java实现

    编译原理实验-LL1语法分析器(自动生成First.Follow)java 博主在做实验时,参考众多他人代码,发现bug众多,在@moni_mm代码基础上,与伙伴把能看到的BUG都做出修正,同时增添了 ...

  9. 编译原理 实验2 语法分析器的构造

    [实验目的] 练习构造语法分析程序的方法,熟悉上下文无关文法的使用,加深对课堂教学的理解:提高词法分析方法的实践能力 [实验要求] 利用某一高级程序设计语言构造语法分析程序 [具体要求]对于给定的文法 ...

最新文章

  1. 在Ubuntu 16.04.6 LTS升级python 3.5.x到3.7.3之后导致gnome-ternimal无法打开的解决办法
  2. JSON数据格式介绍
  3. python中实例方法分类_python方法的分类(实例方法、类方法、静态方法)
  4. 使用OpenMP实现多线程,不仅是用在循环处理上
  5. JAVA编码规约(阿里)
  6. python必学的模块_Python常用的模块
  7. 013_Redis的主从模式
  8. MySQL的大小写问题
  9. 面试题整理7 二叉搜索树的后序遍历序列
  10. java执行mongodb语句_java下执行mongodb
  11. Spring Security——关闭未认证时重定向(302)到登录页面(loginPage)
  12. 只安装python_pip 只能安装python库吗
  13. go语言中的方法method
  14. 微纪实 | 人工智能产业落地最真实的样子
  15. webpack源码分析(2)---- webpack\bin\webpack.js
  16. app嵌入jsp页面的项目工作量_好程序员Java学习路线分享jsp为什么用的不多了
  17. 矩阵范数与向量范数的公式及其理解
  18. 2018年秋招笔试面试----小学渣求职历险记(中南篇)
  19. html特殊符号对照表空格,HTML 特殊符号编码对照表(1)
  20. Python爬虫之爬取网站图片

热门文章

  1. 不用点击_网站推广怎么样才能提高点击量和转化率-西安青云在线
  2. 计算机专业理论知识试题,计算机专业理论试题第II卷(非选择题)
  3. linux命令怎么查看文件时间排序,linux中ls命令按照文件大小排...-ls命令按大小与时间排序文件...-ls按时间排序输出文件列表的实例分析_169IT.COM...
  4. java打印前线程的id_logback打印日志输出线程ID:切面模式
  5. java虚拟机编码格式_Java虚拟机(JVM)默认字符集详解
  6. 直接用自己服务器做图床可以吗_用个人服务器搭建图床
  7. 主题图标_iPhone一键更换主题、图标神器
  8. JAVA EE 6 jar包集合_Java EE6将JSF facelets(xhtml)和ManagedBeans打包成JAR
  9. 用html还是xml做网页好,XML与HTML的比较
  10. 微信公众号api关注接口php,微信公众平台接口开发入门示例