合工大 编译原理 实验三 LR(1) 分析法

本项目使用c++实现,利用Windows API制作了简易的UI界面。
具体功能如下:

  1. 支持查看文法,项目族,LR(1) 分析表,句子归约过程。
  2. 可使用包含左递归的文法且在过程中不生成新终结符
  3. 利用Graphviz查看DFA转换图

详细功能、示例截图、项目代码请见GitHub:LR(1)分析

部分核心代码如下:
1.求FIRST集(该方法尚属测试阶段,如有问题欢迎大佬批评指出)

//利用检测FIRSTset变动情况来求FIRST集的函数,试图忽视左递归与回溯,并不产生新的非终结符
void CheckLR1class::getFIRSTsets() {multimap<string, string> CopyedGrammarFormula = GrammarFormula;      //备份的文法表达式列表while (true) {bool isFIRSTsetincreased = false;//本次遍历是否存在FIRST集变动for (auto i = FIRSTset.begin(); i != FIRSTset.end() && isFIRSTsetincreased == false; i++) {     //删去first集中存在空字符且在产生式右部首位的字符,这样可以保证遍历到B->Ab,A->€中的bif (i->second.find(NULLCHARACTER) != i->second.end()) {for (auto ii = CopyedGrammarFormula.begin(); ii != CopyedGrammarFormula.end(); ii++) {if (ii->first.at(0) == i->first) {auto oldii = ii;CopyedGrammarFormula.insert(make_pair(ii->first.substr(1),ii->second));ii++;CopyedGrammarFormula.erase(oldii);isFIRSTsetincreased = true;}}}}for (auto i = CopyedGrammarFormula.begin(); i != CopyedGrammarFormula.end(); i++) {//ReversedGrammarFormula.insert(i->second, i->first);if (Vnset.find(i->first.at(0)) == Vnset.end() && (FIRSTset.find(i->second.at(0))== FIRSTset.end() || FIRSTset[i->second.at(0)].find(i->first.at(0)) == FIRSTset[i->second.at(0)].end())) {  //终结符且未收录直接添加FIRSTset[i->second.at(0)].insert(i->first.at(0));isFIRSTsetincreased = true;}if (Vnset.find(i->first.at(0)) != Vnset.end() && FIRSTset[i->first.at(0)].size() != 0) {                       //非终结符且该符号非终结符非空bool isallhasincluded = true;                                                                                  //若存在不包括则添加for (auto tmpj = FIRSTset[i->first.at(0)].begin(); tmpj != FIRSTset[i->first.at(0)].end(); tmpj++) {//判断右侧非终结符FIRST集是否已被包含在自身FIRST集中,如果包含则不添加,并不视为FIRST集改动;否则添加,并记录为FIRST集改动bool isthishasincluded = false;for (auto tmpi = FIRSTset[i->second.at(0)].begin(); tmpi != FIRSTset[i->second.at(0)].end(); tmpi++) {                       if (*tmpi == *tmpj && *tmpj!=NULLCHARACTER) {isthishasincluded = true;}                 }if (isthishasincluded == false) {isallhasincluded = false;}}if (isallhasincluded == false) {for (auto tmpj = FIRSTset[i->first.at(0)].begin(); tmpj != FIRSTset[i->first.at(0)].end(); tmpj++) {if (*tmpj != NULLCHARACTER) {FIRSTset[i->second.at(0)].insert(*tmpj);isFIRSTsetincreased = true;}                  }}}}if (isFIRSTsetincreased == false) {break;}}}

2.制作DFA分析
本函数使用队列来进行生成DFA,队列中储存需要展开(求取其子节点)的项目族,每次取队列中的队首进行展开,并将其子节点添加到队列中(前提为未曾在队列中出现过)。

void CheckLR1class::makeAnalysedSheet() {statusblock initalstatusblock;/*tmp.GrammarSentence = string{ mostcharacter };tmp.GrammarVn = "0";tmp.index = 0;*/SymbolSet tmpsymbolset;tmpsymbolset.insert('#');//tmp.SearchSymbol = tmpsymbolset;ProjectSentence tmp = make_tuple("0", string{ mostcharacter }, tmpsymbolset, 0);initalstatusblock.ProjectItem.insert(tmp);initalstatusblock += getCLOSURE(initalstatusblock);//set<set<ProjectSentence>> alreadyexpanedstatusblock;        //已经展开过的状态族集合的集合 由于statusblock结构中存在自增变量无法利用stack<statusblock> searchingstack;searchingstack.push(initalstatusblock);while (searchingstack.empty() == false) {statusblock currentstatusblock = searchingstack.top();collapsesameFormula(currentstatusblock);searchingstack.pop();SymbolSet symbol_iter = getSymbols(currentstatusblock);for (auto i = symbol_iter.begin(); i != symbol_iter.end(); i++) {statusblock tmpfetchedstatusblock = GO(currentstatusblock, *i);collapsesameFormula(tmpfetchedstatusblock);GOset[currentstatusblock][*i] = tmpfetchedstatusblock;bool isfinded = false;for (auto GOset_iter = GOset.begin(); GOset_iter != GOset.end(); GOset_iter++) {if (GOset_iter->first == tmpfetchedstatusblock) {isfinded = true;}}if(isfinded==false )      //尚未进行展开searchingstack.push(tmpfetchedstatusblock);}}//该函数产生父节点与子节点之间的对应关系map,故后续需转化输出处理
}

合工大 编译原理 实验三相关推荐

  1. 合工大 编译原理 实验1

    用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析.通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值:若遇到错误则显示"Error&q ...

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

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

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

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

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

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

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

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

  6. 编译原理 - 实验三 - 递归下降语法分析器的调试及扩展

    一. 语法分析介绍 语法分析是编译过程的核心部分,它的主要任务是按照程序语言的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行语法检查,为语义分析和代码生成做准备.执行语法分析任 ...

  7. 编译原理实验三【中间代码生成程序设计】

    基本要求: ①掌握中间代码生成的基本方法. ②掌握语法制导翻译模式. ③完成算术表达式的中间代码生成程序. 重点及难点:掌握语法制导翻译模式的核心思想和工作原理,在此基础上完成基于算数表达式的中间代码 ...

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

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

  9. 合工大 程序设计艺术 实验三 房间最短路径

    题目 给顶一个内含阻碍墙的房间,求解出一条从起点到终点的最最短路径.房间的边界 固定在 x=0,x=10,y=0 和 y=10.起点和重点固定在(0,5)和(10,5).房间里还有 0 到 18 个 ...

最新文章

  1. Java基础篇:反射
  2. Network simulation using OPNET
  3. JAVA_WEB--jsp语法
  4. java 数字 下划线_为什么要在Java SE 7的数字中使用下划线-在数字文字中使用下划线...
  5. NoSuchElementException
  6. python_paramiko模块
  7. 汉诺塔C语言实现(纯代码)
  8. VDN平台各种数据库连接设置
  9. Maven下载安装及修改setting内容
  10. LOJ 6437 PKUSC2018 PKUSC
  11. 手机酒店预订的革命之作——全新艺龙无线手机客户端测评
  12. linux权限 rwxr xr x,小白求助:权限rwxr-xr-x是啥意思?
  13. 解决 PHP http_build_query() 预期得到 not 却得到 ¬ 的问题
  14. 大厂如何开发和部署前端代码?淘宝8年案例解读
  15. Shell 脚本正则表达式(一)
  16. 《江苏省ITS体系框架与规划——需求分析子课题》工作大纲评审会在南京举行[转贴,出处:ITSC 作者:刘浩,张可]
  17. 关闭微信小程序电脑端的位置定位
  18. 【开发技术】2万字详细介绍Docker 和 web项目的部署监控,docker部署,拉取kafana,prometheus镜像监控
  19. linux nmon的安装及使用
  20. 计算机专业建议买苹果笔记本吗,笔记本买win还是买Mac?也许可以参考这些建议...

热门文章

  1. Gutenberg 5.8发布了基于块的新小部件屏幕原型
  2. VSCODE 空格键自动补全
  3. 不要再搞混Vue的响应式原理和双向数据绑定了
  4. 腾讯云----首次登录提示“腾讯云实例鉴权失败,请确认实例已启用密码鉴权并且账号密码正确”
  5. nginx本地服务器代理
  6. 德国精品软件 看图软件介绍 Ashampoo® Photo Commander 12
  7. BZOJ1875: [SDOI2009]HH去散步
  8. 液压控制系列之活塞位置测量(带原点标定功能)
  9. sqli-labs————less 21
  10. 2022.10.26 英语背诵