first集,follow集,LL(1)分析表

 

点击下载源码

 

 

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LL {
	private static List<String> prt = new ArrayList<String>();
	private static List<First> first = new ArrayList<First>();
	private static List<First> follow = new ArrayList<First>();
	private static List<TableE> table = new ArrayList<TableE>();

	public static void main(String[] args) {
		LL l = new LL();
		l.read();// 从文件读取文法表达式并且对读到的表达式进行预处理
		System.out.println("读入文法分析分解后为:");
		l.printP();
		l.FindFirstP();
		/*******************************************************
		 * 应该加入次数控制,判定,全部first集已经不再发生变化,停*
		 * 止调用FindFirstS()函数!*****************************
		 * *****************************************************/
		l.FindFirstS();
		l.FindFirstS();
		/*******************************************************/
		l.findFollowP();
		l.findFollowP();
		/*******************************************************/
		System.out.println("first集:");
		l.printF(first);
		System.out.println("follow集:");
		l.printF(follow);
		/*******************************************************/
		l.createTable();// 创建LL(1)表
		l.printT();// 打印表

	}

	public void read() {// 读取文件函数
		BufferedReader br = null;
		String line = "";
		try {
			br = new BufferedReader(new FileReader(".\\G(E).txt"));
			System.out.println("读入的文法是:");
			while ((line = br.readLine()) != null) {
				System.out.println(line);
				pretreatment(line); // 调用预处理方法
			}
		} catch (FileNotFoundException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
		try {
			if (br != null) {
				br.close();
				br = null;
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void pretreatment(String line) {// 对输入字符进行预处理。分割 形如
		// A->B|a的表达式为A->B和A->a
		Pattern p = Pattern
				.compile("([A-Z]?[']?)([-]?[>]?)([\\w\\W &&[^|]]*)([|]?)");// 重复问题。
		Matcher m = p.matcher(line);
		String emp = "";
		boolean flag = false;

		do {
			flag = false;
			// boolean b=m.find();
			// System.out.println("find "+b);
			if (m.find()) {
				String str = "";
				if (m.group(1).length() > 0 && m.group(2).length() > 0) {
					emp = m.group(1);
					str = emp + "->" + m.group(3);// 解决正则表达式问题。第二次寻找时组1和组3有交叉的问题
				} else
					str = emp + "->" + m.group(1) + m.group(2) + m.group(3);

				// System.out.println(m.group(3)+" "+m.group(4)+" "+m.group(3).length());
				prt.add(str);

				if (m.group(4).length() > 0)
					flag = true;
				// System.out.println("flag "+flag);
			}

		} while (flag);

	}

	public void printP() {// 打印全部的文法表达式
		Iterator<String> it = prt.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
	}

	public void printF(List<First> first) {// 打印全部first或follow集
		Iterator<First> it = first.iterator();
		while (it.hasNext()) {
			First ft = it.next();
			ft.print();
		}
	}

	public void FindFirstP() {// 进行找first集的第一步操作。
		Iterator<String> it = prt.iterator();
		Pattern p = Pattern.compile("([A-Z][']?)(->)([\\w\\W&&[^A-Z]]*)([.]*)");
		while (it.hasNext()) {
			Matcher m = p.matcher(it.next());
			if (m.find() && m.group(3).length() > 0) {
				// System.out.println(m.group(1));
				if (!cmpAdd(m.group(1), m.group(3), first)) {
					First fc = new First(m.group(1));
					// System.out.println(m.group(1));
					fc.addf(m.group(3));
					first.add(fc);
				}

			}
		}
	}

	public void FindFirstS() {// 进行查找first集的进一步操作。
		Iterator<String> it = prt.iterator();
		while (it.hasNext()) {
			String str = it.next();
			Pattern p = Pattern.compile("([A-Z][']?)(->)([A-Z][']?)");
			Matcher m = p.matcher(str);
			if (str.matches("[A-Z][']?->[[A-Z][']?]+")) {// 如果表达式符合Y->Y1Y2Y3......Yk的形式则执行
				p = Pattern.compile("([A-Z]?[']?)([-]?[>]?)([A-Z][']?)");
				m = p.matcher(str);
				String emp = "";
				boolean flag;
				do {
					flag = false;
					if (m.find()) {
						First fc, ff;
						if (m.group(1).length() > 0) {
							emp = m.group(1);
						}
						ff = findE(emp, first);
						if (m.group(3).length() > 0) {
							fc = findE(m.group(3), first);
							if (fc.conteinZero()) {// 如果Yi的first集中含有ε,直接将Yi的first集中的内容加到ff中
								flag = true;
								ff.addf(fc);
							} else {// 如果Yi的first集中不含有ε,直接将Yi的first集中的内容加到ff中,并且取出加入的ε
								ff.addf(fc);
								ff.reMove('ε');// 因为只要前面的都为有ε即可,最后取到一个可以不含ε

							}
						}
					}
				} while (flag);
			} else if (m.find()) {// 如果表达式不符合Y->Y1Y2Y3......Yk的形式则执行
				// System.out.println(m.group(1)+" "+m.group(3));
				First f1 = findE(m.group(1), first);
				First f2 = findE(m.group(3), first);
				f1.addf(f2.exceptZore());
			}
		}
	}

	private First findE(String name, List<First> first) {// 在找到A的first/follow集中的集合。
		Iterator<First> it = first.iterator();
		First ft = null;
		while (it.hasNext()) {
			ft = it.next();
			if (ft.getName().equals(name)) {
				return ft;
			}
		}
		ft = new First(name);
		first.add(ft);
		return ft;
	}

	private boolean cmpAdd(String name, String str, List<First> first) {// 把新找到的A的First/Follow集中元素加入到其相应的集中。
		Iterator<First> it = first.iterator(); // 加入成功返回true,否则返回false;
		while (it.hasNext()) {
			First ft = it.next();
			if (ft.getName().equals(name)) {
				ft.addf(str);
				return true;
			}
		}
		return false;
	}

	private void findFollowP() {// 创建follow集
		Pattern p = Pattern
				.compile("([A-Z]?[']?)([-]?[>]?)([\\w\\W &&[^A-Z]]*)([[A-Z][']?]*)([\\w\\W &&[^A-Z]]*)");
		Iterator<String> it = prt.iterator();
		Matcher m = null;
		boolean IsFirst = true;
		while (it.hasNext()) {
			String wf = it.next();
			m = p.matcher(wf);
			boolean match = false;

			String ename = "";
			String emp = "";
			do {
				match = m.find();
				if (match) {
					emp = emp + m.group();// 获取到现在为止获取到的wf中的字符。
					if (m.group(1).length() > 0) {
						ename = m.group(1);
					}
					// System.out.println(emp+" "+wf.length()+" "+emp.length()+" "+m.group(4));
					First fc = findE(ename, follow);
					if (IsFirst) {
						fc.addf('#');// 文法开始符处理与其他非终结符处理的不同之处。
						IsFirst = false;
					}
					if (wf.length() == emp.length()) { // 将所取到的字符相加得到总字符长度与原字符长度比较即可
						if (m.group(5).length() > 0) {
							// System.out.println(m.group(5));
							String emp5 = m.group(5);
							String en = "";
							Pattern p1 = Pattern.compile("([A-Z][']?)");
							Matcher m1 = p1.matcher(m.group(4));
							while (m1.find()) {
								en = m1.group();
							}
							if (en.length() > 0) {
								First f = findE(en, follow);
								f.addf(emp5);
							}

						} else if (m.group(4).length() > 0) {
							Pattern p1 = Pattern.compile("([A-Z][']?)");
							Matcher m1 = p1.matcher(m.group(4));
							List<String> lT1 = new ArrayList<String>();
							List<String> lT2 = new ArrayList<String>();
							while (m1.find()) {
								// System.out.println(emp+" "+m.group(4)+" "+m1.group());
								lT1.add(m1.group());
								lT2.add(m1.group());
							}
							Iterator<String> it1 = lT1.iterator();
							while (it1.hasNext()) {
								String name1 = it1.next();
								// System.out.println(" "+name1);
								String name2 = "";
								Iterator<String> it2 = lT2.iterator();

								while (it2.hasNext()) {
									name2 = it2.next();
									// System.out.println(name2+" "+name1);
									if (name2.equals(name1))
										break;
								}
								First flw = findE(name1, follow);
								boolean flage = true;
								while (it2.hasNext()) {// 必须是紧紧跟随在E之后的终结符才算follow集中
									name2 = it2.next();
									// System.out.println(name2+" "+name1);
									First fst = findE(name2, first);
									flw.addf(fst.exceptZore());
									if (!fst.conteinZero()) {
										flage = false;
										break;// 重要,否则,将会导致程序失败。使如A->BCD形式的表达式,
										// 含ε时,仍旧将D的first集中的内容加入到了B的follow集中
									}
								}
								if (flage) {// 完成A->aBb形式,将A的follow集加到B的follow集中。
									First main = findE(ename, follow);
									flw.addf(main);
								}
							}
						}
						match = false;
					} else if (m.group(5).length() > 0) {
						// System.out.println(m.group(5));
						String emp5 = m.group(5);
						String en = "";
						Pattern p1 = Pattern.compile("([A-Z][']?)");
						Matcher m1 = p1.matcher(m.group(4));
						while (m1.find()) {
							en = m1.group();
						}
						if (en.length() > 0) {
							First f = findE(en, follow);
							f.addf(emp5);
						}
					}

				}

			} while (match);

		}
	}

	private void createTable() {// 创建ll(1)表
		Iterator<String> it = prt.iterator();
		Pattern p = Pattern.compile("([A-Z][']?)(->)([\\w\\W&&[^A-Z]]?)");
		Matcher m = null;
		while (it.hasNext()) {
			String exp = it.next();
			m = p.matcher(exp);
			boolean b = m.find();
			// System.out.println(b);
			if (b && m.group(1).length() > 0) {
				// System.out.println(m.group(1));
				First ft = this.findE(m.group(1), first);
				if (IsSingle(m.group(1) + m.group(2))) {// 只用m.group(1)时,会造成E与
					// E'匹配产生错误。丢失表项
					// System.out.println(m.group(1));
					String collect = ft.exceptZore().getCollect();
					int length = collect.length();
					for (int i = 0; i < length; i++) {
						TableE t = new TableE(m.group(1), collect.charAt(i),
								exp);
						if (!isHas(t))
							table.add(t);
					}
				} else if (m.group(3).length() > 0) {
					// System.out.println(m.group(1)+" "+m.group(3));
					// First ft=this.findE(m.group(1), first);
					if (m.group(3).charAt(0) != 'ε') {
						// System.out.println(m.group(1));
						if (ft.conteinChar(m.group(3).charAt(0))) {
							// System.out.println(m.group(1));
							TableE t = new TableE(m.group(1), m.group(3)
									.charAt(0), exp);
							if (!isHas(t))
								table.add(t);
						}
					}
				}

				if (ft.conteinZero()) {
					First ff = this.findE(m.group(1), follow);
					String collect = ff.exceptZore().getCollect();
					int length = collect.length();
					for (int i = 0; i < length; i++) {
						TableE t = new TableE(m.group(1), collect.charAt(i), m
								.group(1)
								+ "->ε");
						if (!isHas(t))
							table.add(t);
					}
				}

			}
		}
	}

	private boolean isHas(TableE t) {// 判断在表中是不是已经存在了M[A,a],
		Iterator<TableE> it = table.iterator();
		while (it.hasNext()) {
			if (it.next().isEquals(t))
				return true;
		}
		return false;
	}

	private boolean IsSingle(String str) {// 判断表达式 A->a是不是唯一表达式。
		Iterator<String> it = prt.iterator();
		Pattern p = Pattern.compile(str);
		int sign = 0;
		while (it.hasNext()) {
			Matcher m = p.matcher(it.next());
			if (m.find()) {
				sign++;
			}
			if (sign > 1)
				return false;
		}
		return true;
	}

	private void printT() {// 打印整张表格
		Iterator<TableE> it = table.iterator();
		System.out.println("创建的LL(1)分析表:");
		String emp = "";
		while (it.hasNext()) {
			TableE t = it.next();
			String current = t.getNT();
			if (current.equals(emp))
				t.print();
			else {
				System.out.println();
				t.print();
				emp = current;
			}
		}
	}
}


 

 

/**********************************************
 * 创建表格对象,行名为非终结符,列名为终结符号名。内容为文法表达式
 * */
public class TableE {
	private String nT;
	private char yT;
	private String exp;
	public TableE(String nt,char c,String exp){
		this.yT=c;
		this.nT=nt;
		this.exp=exp;
	}
	public boolean isEquals(TableE t){//判断两个表格元素是否完全相同
		if(t.nT.equals(this.nT)&&t.yT==this.yT&&t.exp.equals(this.exp))
			return true;
		return false;
	}
	public boolean cmpTnT(String nT,char yT){//查看表格元素是否已经创建。
		if(this.yT==yT&&this.nT.equals(nT))
			return true;
		else 
			return false;
	}
	public void print(){//打印当前的表格对象
		System.out.println("["+this.nT+"] ["+this.yT+"] ("+this.exp+ ") ");
	}
	public String getExp(){//获取表格对象的内容,文法表达式。
		return this.exp;
	}
	public String getNT() {//获得非终结符。
		
		return this.nT;
	}
}


 

 

/*创建非终结符的first集和follow集的类
 * 其中非终结符 是字符串name,其对应的集合用字符串来表示
 * 
 * */

public class First {
	private String first;
	private String name;
	public First(String name,First f){
		//用一个非终结符的first/follow集合来创建新的一个。
		this.name=name;
		this.first=f.first;		
	}
	public First(String name){//创建新的First对象
		this.name=name;
		this.first="";
	}
	public First(String name,String first){//分别赋值的方式创建对象
		this.name=name;
		this.first=first;
	}
	public String getName(){//获取name元素,即非终结符
		return this.name;
	}
	public String getCollect(){//获取对象的first元素
		return this.first;
	}
	public void addf(char str){//在集合中添加新元素
		int length=first.length();
		if(length==0)
			first=first+str;
		else{
			for(int i=0;i<length;i++){
				if(str==first.charAt(i))
					return;
			}
				first=first+str;
		}
	}
	public First exceptZore(){//求当前对象除了'ε'之外的firt内容
		int length=this.first.length();
		String emp="";
		if(length>0){
			for(int i=0;i<length;i++){
				if(this.first.charAt(i)!='ε')
					emp=emp+this.first.charAt(i);
				//else emp=emp;
			}				
		}
		return new First(this.name,emp);
	}
	public boolean conteinZero(){//判断当前对象的first元素中是否含有'ε'
		int length=this.first.length();
		if(length>0){
			for(int i=0;i<length;i++){
				if(this.first.charAt(i)=='ε')
					return true;
				}
		}
		return false;
	}
	public boolean conteinChar(char c){//判断当前对象first中是否含有字符c
		int length=this.first.length();
		if(length>0){
			for(int i=0;i<length;i++){
				if(this.first.charAt(i)==c)
					return true;
				}
		}
		return false;
	}
	public void addf(First fc){//将某一对象的 集合中的元素加入到当前元素的集合中
		if(fc.first.length()>0){
			for(int i=0;i<fc.first.length();i++)
				this.addf(fc.first.charAt(i));
		}
	}
	public void addf(String str){//将获得的新集合加入党当前对象的集合中
		if(str.length()>0){
			for(int i=0;i<str.length();i++)
				this.addf(str.charAt(i));
		}
	}
	 public void print(){//打印当前对象 的元素,以集合方式打印集合first中的元素
		 System.out.print(name+": {");
		 for(int i=0;i<first.length()-1;i++)
			 System.out.print(first.charAt(i)+",");
		 if(first.length()>0)
			 System.out.print(first.charAt(first.length()-1));
		 System.out.println("}");
	 }
	public void reMove(char c) {//从当前元素中去掉某一字符c
		int length=first.length();		
		if(length>0){
			String emp="";
			for(int i=0;i<length;i++){
				if(c!=first.charAt(i))
					emp=emp+first.charAt(i);
					
			}
				first=emp;
		}
		
	}
}

 

 

 

运行结果:

读入的文法是:
E->TE'
E'->+TE'|ε
T->FT'
T'->*FT'|ε
F->(E)|i
读入文法分析分解后为:
E->TE'
E'->+TE'
E'->ε
T->FT'
T'->*FT'
T'->ε
F->(E)
F->i
first集:
E': {+,ε}
T': {*,ε}
F: {(,i}
E: {(,i}
T: {(,i}
follow集:
E: {#,)}
T: {+,#,)}
E': {#,)}
F: {*,+,#,)}
T': {+,#,)}
创建的LL(1)分析表:

[E] [(] (E->TE')
[E] [i] (E->TE')

[E'] [+] (E'->+TE')
[E'] [#] (E'->ε)
[E'] [)] (E'->ε)

[T] [(] (T->FT')
[T] [i] (T->FT')

[T'] [*] (T'->*FT')
[T'] [+] (T'->ε)
[T'] [#] (T'->ε)
[T'] [)] (T'->ε)

[F] [(] (F->(E))
[F] [i] (F->i)


 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值