第一次写博客。。。编译原理课的一个实验。

  感觉自己花了挺长的时间,所以作为博客保留下来,挺有纪念意义的  (因为我是菜鸟)

package com.insist.entity;import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;/*** * @author SNOOPY 消除一切左递归*/
public class EliminateLeftRecursion {private static int n;// 实际输入产生式个数public static void main(String[] args) {Scanner scan = new Scanner(System.in);System.out.println("请输入产生式个数:");n = scan.nextInt();// 创建产生式数组存放输入的产生式List<Regular> regulars = new ArrayList<Regular>();for (int i = 0; i < n; i++) {Regular reg = new Regular();System.out.println("请输入产生式左部:");String left = scan.next();reg.setLeft(left);System.out.println("请输入产生式的右部:");String right = scan.next();reg.setRight(right);regulars.add(reg);}/** 测试输出------->成功 for (Regular reg: regulars) { System.out.println(reg.getLeft()+"---->"+reg.getRight()); }*/// 构造一个字符型的数组用来存放排序好的非终结符String[] Vn = new String[50];// 对所有的产生式按照一定的顺序存放Vn[0] = regulars.get(0).getLeft();// 把产生式第一个非终结符放到集合中int flag = 0;int count = 0;for (int i = 1; i < n; i++) {// 对非终结符排序并存取 1、遍历产生式数组for (int j = 0; j < i; j++) {// 如果产生式左部等于在它前面的产生式的左部if (regulars.get(i).getLeft().equals(regulars.get(j).getLeft())) {// 说明有重复的flag++;}}if (flag == 0) {// 说明没有重复,则加入非终结符数组中count++;Vn[count] = regulars.get(i).getLeft();}flag = 0;}/** 测试非终结符数组------------>成功 for (int i = 0; i < Vn.length; i++) { if(Vn[i]!=null){ System.out.println(Vn[i]); } }*/for (Regular reg : regulars) {if (reg != null) {System.out.println(reg.getLeft() + "---->" + reg.getRight());}}regulars = subFunction(regulars, Vn, count);for (Regular reg : regulars) {if (reg != null) {System.out.println(reg.getLeft() + "---->" + reg.getRight());}}}public static List<Regular> subFunction(List<Regular> regulars, String[] Vn, int count) {int flag = 0;// 判断是否存在间接左递归并转化为直接左递归for (int i = 0; i <= count; i++) {// 对每一个非终结符 迭代for (int j = 0; j < i; j++) {// 对每一个小于i的非终结符遍历for (int k = 0; k < regulars.size(); k++) // 对每一个产生式if (Vn[i].equals(regulars.get(k).getLeft())) {// i非终结符与第k产生式左边第一个字母相等-->锁定非终结符集合中的一个非终结符的产生式if (regulars.get(k).getRight().substring(0, 1).equals(Vn[j])) { // g产生式右边产生式第一个符号与第j个非终结符相等-->说明存在间接左递归for (int h = 0; h < regulars.size(); h++) {if (regulars.get(h).getLeft().equals(Vn[j])) {// 进行替换
                                    String str;str = regulars.get(k).getRight().substring(1);// 截取右边第一个以后的字符Regular reg = new Regular();reg.setLeft(regulars.get(k).getLeft());reg.setRight(regulars.get(h).getRight() + str);regulars.add(reg);}}regulars.remove(k);}}}}// 消除所有直接左递归for (int i = 0; i <= count; i++) {flag = 0;for (int j = 0; j < regulars.size(); j++) {// 判断是否存在直接左递归if (regulars.get(j).getLeft().equals(Vn[i])) {System.out.println(regulars.get(j).getLeft() + " ======= " + Vn[i]);if (regulars.get(j).getLeft().equals(regulars.get(j).getRight().substring(0, 1))) {System.out.println("消除间接左递归后存在直接左递归");flag++;}}}if (flag != 0) {// 存在直接左递归for (int j = 0; j < regulars.size(); j++) {if (regulars.get(j).getLeft().equals(Vn[i])) {// 寻找与存在直接左递归的非终结符左部相同的的产生式if (regulars.get(j).getLeft().equals(regulars.get(j).getRight().substring(0, 1))) {// 直接左递归的产生式String str = regulars.get(j).getRight().substring(1);String temp = regulars.get(j).getLeft();String temp1 = "'";regulars.get(j).setLeft(temp + temp1);regulars.get(j).setRight(str + regulars.get(j).getLeft());Regular reg = new Regular();reg.setLeft(regulars.get(j).getLeft());reg.setRight("ε");regulars.add(reg);} else {String temp = regulars.get(j).getLeft();String temp1 = "'";temp = temp + temp1;regulars.get(j).setRight(regulars.get(j).getRight() + temp);}}}}}return regulars;}
}

package com.insist.entity;import java.io.Serializable;/*** * @author SNOOPY**/
public class Regular implements Serializable {private static final long serialVersionUID = 1L;private String right;// 定义产生式右部private String left;// 定义产生式左部public String getRight() {return right;}public void setRight(String right) {this.right = right;}public String getLeft() {return left;}public void setLeft(String left) {this.left = left;}
}

转载于:https://www.cnblogs.com/snoopylovefiona/p/4593726.html

消除文法中一切左递归算法相关推荐

  1. 第四章:文法中的递归以及消除方法

    在介绍递归文法之前,首先介绍一下递归下降分析器及其原理,然后分析右递归是如何处理的,再来分析左递归和间接左递归. 递归下降分析器 自顶向下语法分析的目的是为输入串寻找最左推导,或者说,从根节点(文法开 ...

  2. 如何消除摄影中的运动模糊?

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|计算机视觉life 如果你试过去拍摄一些运动场景,例如拍 ...

  3. LL(1)文法中FIRST集和FOLLOW集的计算方法

    文章目录 深入理解 FIRST集的定义 FIRST集的实际意义 FIRST集的计算方法 FOLLOW集的定义 FOLLOW集的实际意义 FOLLOW集的计算方法 预测分析表的实质 LL(1)文法的判断 ...

  4. 《电脑音乐制作实战指南:伴奏、录歌、MTV全攻略》——2.7 消除歌曲中某个合音或乐器...

    本节书摘来自异步社区<电脑音乐制作实战指南:伴奏.录歌.MTV全攻略>一书中的第2章,第2.7节,作者 健逗,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2. ...

  5. 如何正确的使用Java8中的Optional类来消除代码中的null检查

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:一书生VOID lw900925.github.io/jav ...

  6. R语言ggplot2可视化移除数据中的NA值再可视化实战:消除图形中非常突出的NA柱状图、使用subset函数、使用drop_na函数

    R语言ggplot2可视化移除数据中的NA值再可视化实战:消除图形中非常突出的NA柱状图.使用subset函数.使用drop_na函数 目录

  7. 消除 Xcode7 中 directory not found for option 'xxxx' 警告

    消除 Xcode7 中 directory not found for option 'xxxx' 警告 升级Xcode7之后,你会遇到一些警告信息,诸如以下一条: ld: warning: dire ...

  8. LeakCanary——消除Android中的内存泄露

    2019独角兽企业重金招聘Python工程师标准>>> ##LeakCanary ####简介 LeakCanary是Square公司最近公布的开源项目,旨在消除Android中的内 ...

  9. c++中的左值与右值

    转载自 http://www.cnblogs.com/catch/p/3500678.html 左值 (lvalue)和右值 (rvalue) 是 c/c++ 中一个比较晦涩基础的概念,有的人可能甚至 ...

最新文章

  1. 默的各种写法图片_SEO标题写法?
  2. python游戏编程入门电子书-请问自学 Python 有必要买课程吗?
  3. 概率论 第二章 随机变量及其分布
  4. 【code】Splay 模板
  5. pat 甲级 1034. Head of a Gang (30)
  6. sql docker容器_了解SQL Server Docker容器中的备份和还原操作
  7. Firewalld防火墙转换成Iptables
  8. 计算机日常英语,计算机英语的常用句子
  9. android7.1获取存储权限,Android外部存储
  10. ARM指令集和X86指令集对比
  11. mysql unicode转换为中文_中文转换成Unicode编码 和 Unicode编码转换为中文
  12. android 修改机型,教你一个无需Root就能修改手机型号的简单方法
  13. ESP32使用百度语音合成 实现文字转语音播放
  14. 专精特新是什么,为什么要申报“专精特新”中小企业
  15. #先进先出#每批次采购价格不同,计算期末库存成本
  16. 怎么清楚计算机硬盘搜索记录,win7系统怎么清除搜索记录_windows7删除计算机搜索记录的方法...
  17. 分享一个特别好用的站长在线工具箱
  18. linux脚本编写图形,shell图形化界面脚本实现
  19. 本地——云服务器文件传输
  20. 极简汉字史 第一章 文象列而结绳移 鸟迹明而书契作

热门文章

  1. File类3 文件读取
  2. bitand( ) 函数用法
  3. 面向对象的多态性(3)
  4. 【解决方案】Windows10局域网内配置文件夹共享(附网络中没有找到的情况解决方案)
  5. 随笔(2018.9.2.)
  6. lisp直线连接圆象限电_圆并不难,为什么很多考生就是学不会?
  7. mysql中主从_MySQL的主从
  8. 【MySQL经典案例分析】 Waiting for table metadata lock
  9. Redis的安装和部署
  10. uva455periodic strings周期串