消除文法中一切左递归算法
生活随笔
收集整理的這篇文章主要介紹了
消除文法中一切左递归算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第一次寫博客。。。編譯原理課的一個實驗。
感覺自己花了挺長的時間,所以作為博客保留下來,挺有紀念意義的??(因為我是菜鳥)
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
總結
以上是生活随笔為你收集整理的消除文法中一切左递归算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中的定制类(转载)
- 下一篇: 斐波那契数 c 语言实现