编译原理实验(三)——LR(0)语法分析

  • 实验要求
  • 参考程序
  • 实验结果
    • 程序输入说明
    • 截图

实验要求

根据LR(0)分析法编写一个语法分析程序 直接输入根据已知文法构造的分析表M;对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。

参考程序

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <iomanip>
using namespace std;const int maxSize = 20; //输入规模的最大大小
const string errorstr = "你输入的语言该文法无法识别";
const int outWidth = 20; //设置输出字符串所占宽度int terminatorNum;    //输入终结符的数量
int nonterminatorNum; //输入非终结符的数量
int stateNum;         //输入状态数
int num;              //输入产生式个数
int Goto[maxSize][maxSize];
char action[maxSize][maxSize];
int terAction[maxSize][maxSize];
string chang[maxSize];           //产生式
map<char, int> terminatorSet;    //输入终结符的集合,用map 映射表示在分析表的第几列
map<char, int> nonterminatorSet; //输入非终结符的集合,用map 映射表示在分析表的第几行
vector<char> signStack;          // 符合栈为了更好的输出栈中的内容,用vector数组模拟栈行为
vector<int> stateStack;          // LR0文法状态栈void analysisProcess(string); //对输入的语言用LL1预测分析表进行分析
string intToString(int);      //将整数转化为字符串,并且大于9的数+()int main()
{cout << "请输入产生式的个数:";cin >> num;cout << "请按顺序输入产生式:\n";for (int i = 1; i <= num; ++i)cin >> chang[i];cout << "请输入终结符的个数:";cin >> terminatorNum;char str;cout << "请依次按照分析表输入终结符(包含结束符#):" << endl;for (int i = 1; i <= terminatorNum; ++i){cin >> str;terminatorSet[str] = i;}cout << "请输入非终结符的个数:";cin >> nonterminatorNum;cout << "请依次按照分析表输入终结符:" << endl;for (int i = 1; i <= nonterminatorNum; ++i){cin >> str;nonterminatorSet[str] = i;}cout << "请输入最后一个状态数(从0开始):";cin >> stateNum;cout << "请依次输入非终结符goto表的内容,对于出错错误的请输入-1:\n";for (int i = 0; i <= stateNum; ++i){for (int j = 1; j <= nonterminatorNum; ++j){cin >> Goto[i][j];}}cout << "请依次输入终结符action的内容,对于出错错误的请输入-1:\n";cout << "输入格式按照 移进(S state) 规约(R state) 接受(A -1) 出错(E -1),state代表状态数\n";for (int i = 0; i <= stateNum; ++i){for (int j = 1; j <= terminatorNum; ++j){cin >> action[i][j] >> terAction[i][j];}}cout << "请输入要分析语言: ";string L;cin >> L;analysisProcess(L);
}void analysisProcess(string str)
{str += "#";cout << setw(outWidth) << setiosflags(ios::left) << "步骤";cout << setw(outWidth) << setiosflags(ios::left) << "状态栈";cout << setw(outWidth) << setiosflags(ios::left) << "符号栈";cout << setw(outWidth) << setiosflags(ios::left) << "产生式"<< "输入串" << endl;signStack.clear();stateStack.clear(); //清空状态栈,符合栈signStack.push_back('#');stateStack.push_back(0);        //初始化符合栈,状态栈int i = 0, ip = 0;              //i代表进行到第几步 a是分析到输入语言字符串第几个int Sm;                         //当前状态栈栈顶状态int a = terminatorSet[str[ip]]; //当前剩余输入串的首字符在输入终结符表的位置cout << setw(outWidth) << setiosflags(ios::left) << (++i);cout << setw(outWidth) << setiosflags(ios::left) << "0";cout << setw(outWidth) << setiosflags(ios::left) << "#";cout << setw(outWidth) << setiosflags(ios::left) << " " << str << endl;string outStr;while (++i){Sm = stateStack.back();if (action[Sm][a] == 'S'){/*移进:当前输入符号ai移进符号栈,将action表中指出的状态S进状态栈*///cout<<terAction[Sm][a];stateStack.push_back(terAction[Sm][a]);signStack.push_back(str[ip]);a = terminatorSet[str[++ip]];cout << setw(outWidth) << setiosflags(ios::left) << i;outStr = "";for (int t = 0; t < stateStack.size(); ++t)outStr += intToString(stateStack[t]);cout << setw(outWidth) << setiosflags(ios::left) << outStr;outStr = "";for (int t = 0; t < signStack.size(); ++t)outStr += signStack[t];cout << setw(outWidth) << setiosflags(ios::left) << outStr;cout << setw(outWidth) << setiosflags(ios::left) << " " << str.substr(ip) << endl;}else if (action[Sm][a] == 'R'){int j = terAction[Sm][a];int size = chang[j].size() - 3;if (chang[j][3] == '@')size = 0; //为空产生式for (int t = 0; t < size; ++t)stateStack.pop_back();for (int t = 0; t < size; ++t)signStack.pop_back();Sm = stateStack.back();char A = chang[j][0]; //规约符号signStack.push_back(A);stateStack.push_back(Goto[Sm][nonterminatorSet[A]]);cout << setw(outWidth) << setiosflags(ios::left) << i;outStr = "";for (int t = 0; t < stateStack.size(); ++t)outStr += intToString(stateStack[t]);cout << setw(outWidth) << setiosflags(ios::left) << outStr;outStr = "";for (int t = 0; t < signStack.size(); ++t)outStr += signStack[t];cout << setw(outWidth) << setiosflags(ios::left) << outStr;cout << setw(outWidth) << setiosflags(ios::left) << chang[j] << str.substr(ip) << endl;}else if (action[Sm][a] == 'A'){cout << "该文法识别该语言" << endl;return;}else{cout << errorstr << endl;return;}}
}string intToString(int num)
{int j = num;if (j == 0)return "0";string str = "";while (j){str += char(j % 10 + '0');j /= 10;}str.reserve();if (num > 9)str = "(" + str + ")";return str;
}

实验结果

程序输入说明

输入的终结符与终结符都为单个字符
空(ε\varepsilonε)用@表示
参考文法:

分析表:

输入数据案例

4
S->aAcBe
A->b
A->Ab
B->d6
a c e b d #3
S A B9
1 -1 -1
-1 -1 -1
-1 3 -1
-1 -1 -1
-1 -1 -1
-1 -1 7
-1 -1 -1
-1 -1 -1
-1 -1 -1
-1 -1 -1S  2 E -1 E -1  E -1    E -1    E -1
E -1    E -1    E -1    E -1    E -1    A -1
E -1    E -1    E -1    S 4 E -1    E -1
E -1    S 5 E -1    S 6 E -1    E -1
R 2 R 2 R 2 R 2 R 2 R 2
E -1    E -1    E -1    E -1    S 8 E -1
R 3 R 3 R 3 R 3 R 3 R 3
E -1    E -1    S 9 E -1    E -1    E -1
R 4 R 4 R 4 R 4 R 4 R 4
R 1 R 1 R 1 R 1 R 1 R 1abbcde

截图


编译原理实验(三)——LR(0)语法分析相关推荐

  1. 编译原理-实验四-LR(0)语法分析程序的设计

    一.实验目的 了解LR(0)语法分析算法的基本思想,掌握LR(0)语法分析程序的构造方法. 二.实验内容 根据LR(0)语法分析算法的基本思想,设计一个对给定文法进行LR(0)语法分析的程序,并用C. ...

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

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

  3. 编译原理 实验四 LR(0)分析法(LR0分析表的自动生成)

    写在前面 由于代码较长,csdn对文章总长度有字数限制,想只看完整代码的请移步另一篇博客. https://blog.csdn.net/qq_46640863/article/details/1257 ...

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

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

  5. 合工大 编译原理 实验三

    合工大 编译原理 实验三 LR(1) 分析法 本项目使用c++实现,利用Windows API制作了简易的UI界面. 具体功能如下: 支持查看文法,项目族,LR(1) 分析表,句子归约过程. 可使用包 ...

  6. 编译原理实验三 语义分析程序设计与实现

    一.实验目的 在实现词法.语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,并完成 ...

  7. java编程实现算符优先分析法,编译原理实验三-算符优先分析法

    编译原理实验3-算符优先分析法 #include #include #include #include #define SIZE 128 char priority[6][6]; //算符优先关系表数 ...

  8. 编译原理-实验二-LL(1)语法分析程序的设计

    一.实验目的 了解LL(1)分析器的基本构成及用自顶向下的LL(1)方法对表达式进行语法分析的方法,掌握LL(1)语法分析程序的构造方法. 二.实验内容 根据LL(1)语法分析算法的基本思想,设计一个 ...

  9. 编译原理—实验二LL(1)语法分析(一)

    一.实验目的 1.熟悉LL(1)语法分析的基本原理,语法分析的过程,以及语法分析中要注意的一些问题. 2. 复习高级语言及线性表.栈.图等典型数据结构,进一步加强用高级语言来解决实际问题的能力. 二. ...

  10. 编译原理实验三:对完整程序进行词法分析并输出对应的二元组

    实验要求 [任务介绍]根据给定源语言的构词规则,从任意字符串中识别出该语言所有的合法的单词符号,并以等长的二元组形式输出. [输入]字符串形式的源程序. [输出]单词符号所构成的串(流),单词以等长的 ...

最新文章

  1. 主机入侵防御系统(HIPS)分析
  2. 不理解Zookeeper一致性原理,谈何异地多活改造
  3. java model 中文乱码_Java解压zip 解决编码和中文乱码问题
  4. BufferQueue 和 gralloc
  5. linux卸载git,并且安装新版本git
  6. 微服务架构和SOA的区别
  7. Uncaught (in promise) DOMException 报错
  8. mysql存储过程split_mysql存储过程实现split示例
  9. java 内存指针_C指针和内存
  10. delphi中webbrowse控件中模拟点击文本超链接_功能测试——控件测试
  11. html5电商销售网站统计后台模板html5电商销售网站统计后台模板
  12. 通俗易懂的方式讲解最大流和最小割问题
  13. 关于ubuntu20.04通过Software and updates安装NVIDIA驱动
  14. macpro如何清理磁盘空间_在MacBook上,释放磁盘空间的7种方法
  15. qq邮箱 服务器认证失败怎么回事,为什么我的QQ邮箱登录不了 QQ邮箱无法登陆怎么解决...
  16. 最新小程序反编译的获取流程
  17. 谈谈架构 -- architect
  18. 如何导出计算机硬盘重数据,硬盘对拷教程,100%保存原硬盘数据
  19. HDU 6148 Valley Numer(数位DP)
  20. 汇编踩过的坑(error A1010,A2085 ,divide error,A2070,注意事项)

热门文章

  1. 链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现
  2. 华为SDC相机开发(2.运行demo)
  3. 转载:void(*fun)()与void*fun()的区别
  4. 某些Office 精简版 Win7运行问题(Windows7 不支持 Thinstall)
  5. win10如何安装Rational rose(详解)
  6. 17 医疗挂号系统_【微信支付】
  7. 《 V I M 教 程 》 —— 版本 1.5
  8. 闪讯利用openwrt路由器拨号教程(二)
  9. 51单片机 DHT11温湿度传感器 MQ2传感器
  10. 五子棋小游戏——Java