编译原理语法分析(java)

今天老师要让我们写一个语法分析器,,布置的内容是,给一个已经消除了左递归和回溯的文法,

让我们写出整个语法分析过程,,我竟然记错了,,花了几个小时写了个,消除左递归


《直接递归的消除》  时间有点紧,写的有点乱,(关键是没按照命名标准来命名),以后再改吧,,没用什么数据结构,都是java内部lang.string中的方法,

若有道友写出C语言版本的,可以分享出来(谢谢)

《循环左递归》以后再写,时间好紧

文件:D:\\text.txt

内容:(可以自行修改),我是按照这个来的,,其他的也都可以

E=E+T/T
T=T*F/F
F=(E)/i


结果:

O=+TO/ε
E=TO
K=*FK/ε
T=FK
F=(E)/i

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
public class yufafenxi {
	public yufafenxi() {
		// TODO Auto-generated constructor stub
		try {
			readFile();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	int length=0;
	
	//读取文件,得到每行的内容
	public ArrayList<String> readFile() throws Exception{
		FileInputStream fileInputStream=new FileInputStream("D:\\text.txt");
		InputStreamReader reader=new InputStreamReader(fileInputStream);
		BufferedReader bufferedReader=new BufferedReader(reader);
		String text=null;
		ArrayList<String> all=new ArrayList<>();
		while((text=bufferedReader.readLine())!=null){
			all.add(text);
		}
		length=all.size();
		return all;
	}
	
	//得到P非终结字符的字符数组{S T F}
	public char[] getP(ArrayList<String> list){
		char[] state=new char[1024];
		for(int i=0;i<list.size();i++){
			String current=list.get(i);
			state[i]=current.toCharArray()[0];//得到状态S T F
		}
		return state;
	}
	
	//得到候选集合{E+T,T,T*F,F,(E),i}
	public ArrayList<String> getHouxuanstring(ArrayList<String> list){
		ArrayList<String> houxuanAll=new ArrayList<>();
		for(int i=0;i<list.size();i++){
			String current=list.get(i);
			String waitcurrent=current.substring(2, current.length());
			houxuanAll.add(waitcurrent);
		}
		return houxuanAll;
	}
	
	//得到候选分割的集合{E+T,T}{T*F,F}{(E),i}
	public String[] getJihe(String text){
		String waitcurrent=text.substring(2, text.length());
		String[] currentAll=waitcurrent.split("/");//得到候选式存入字符串数组
		return currentAll;
	}
	
	//得到原始首符集{E,T,T,F,(,i}
	public HashMap<Integer, String> getHouxuanshi(ArrayList<String> list){
		HashMap<Integer, String>map=new HashMap<>(); 
		for(int i=0;i<list.size();i++){
			String current=list.get(i);
			String waitcurrent=current.substring(2, current.length());
			String[] currentAll=waitcurrent.split("/");//得到候选式存入字符串数组,,后续会转变为字符数组
			String word="";
			for(int j=0;j<currentAll.length;j++){
				word+=currentAll[j].charAt(0);//得到首位字符
			}
			map.put(i,word);//得到首符集,每行的首字符(合起来存为一个字符串,以后可以分割)
		}
		return map;
	}
	
	/**
	 * P与原始首符集匹配,相等则存在左递归,消除左递归,生成新的文法
	 * @param p 文法左端非终结符
	 * @param map p的first集合
	 * @param list 每行的文法
	 */
	public ArrayList<String> removeLeftDigui(char[] p,HashMap<Integer, String> map,ArrayList<String> list){
		ArrayList<String> newList=new ArrayList<>();
		String longText="";
		String aChange="";
		//先比较左端非终结符和各自的FIRSE集合,此处为一对多的匹配
		char[] needChar={'Q','W','P','L','M','N','K','O'};//新的左端非终结符
		
		//生成新的文法是,每次从中拿一个作为左端非终结符
		ArrayList<String> Char=new ArrayList<>();
		for(int i=0;i<needChar.length;i++){
			Char.add(needChar[i]+"");
		}
		
		for(int i=0;i<length;i++){
			//再次循环达到一对F(1)匹配,一对F(2)匹配...
			char[] houxuanshi=map.get(i).toCharArray();//每行的first集合
			String houxuanText=new String(houxuanshi);
			
			char use=Char.get(Char.size()-1).charAt(0);//新的非终结符
			Char.remove(Char.size()-1);//移除已经用过的字符
			String hang=list.get(i);//i行的文法
			
			for(int j=0;j<houxuanshi.length;j++){
				//i行存在左递归,则
				if(houxuanText.contains(p[i]+"")){
					String[] allHouxuanshi=getJihe(hang);
					/**
					 * 候选式FIRSE与P的比较 
					 * 1:不相同
					 * 2:相同
					 */
					if(p[i]==houxuanshi[j]){
						
						/**
						 * 生成新的候选式,如E+T
						 * +T——>allHouxuanshi[j].substring(1, allHouxuanshi[j].length())
						 * O——>use
						 * longText为新生成的一行文法
						 */
						String newText=allHouxuanshi[j].substring(1, allHouxuanshi[j].length())+use;
						longText=longText+newText+"/";
						
					}
					
					if(p[i]!=houxuanshi[j]){
						String newText=allHouxuanshi[j]+use;
						aChange=aChange+newText+"/";
					}
				}
			}
			
			if(longText.equals(""))continue;
			//新文法存入list中
			//得到新生成的文法行,候选式中需要添加空字符
			String AllLongText=use+"="+longText+"ε";
			newList.add(AllLongText);
			/**
			 * 两个字符串变量每经一轮循环都置空,因为已经生成了一行新的文法
			 * 下一轮循环会生成新的文法,所以需要置空
			 */
			AllLongText="";
			longText="";
			//得到改变的文法行,候选式中不需要空字符
			String AllaChange=p[i]+"="+aChange;
			newList.add(AllaChange);
			/**
			 * 同上
			 */
			AllaChange="";
			aChange="";
			//将存在左递归的行置空,省下来的都是不存在左递归的行,直接添加到新文法中	
			list.set(i, "");		
		}
		
		//去掉最后的/字符
		for(int i=0;i<newList.size();i++){
			String CurrentElement=newList.get(i);
			if(CurrentElement.endsWith("/")){
				CurrentElement=CurrentElement.substring(0, CurrentElement.length()-1);
				newList.set(i, CurrentElement);
			}
		}
		//将不存在左递归的行,添加到新文法
		for(int i=0;i<list.size();i++){
			if(!list.get(i).equals("")){
				newList.add(list.get(i));
			}
		}
		return newList;
	}
	//输出新的文法
	public void printNewWenfa(ArrayList<String> arrayList){
		for(int i=0;i<arrayList.size();i++){
			System.out.println(arrayList.get(i));
		}
	}
	
	public static void main(String[] args) throws Exception {
		yufafenxi yufafenxi=new yufafenxi();//初始化程序
		ArrayList<String> list=yufafenxi.readFile();//读取文件,得到所有行的字符串
		char[] p=yufafenxi.getP(list);//得到左端非终结符
		yufafenxi.getHouxuanstring(list);//得到候选集合(未使用)
		HashMap<Integer, String> map=yufafenxi.getHouxuanshi(list);//得到首符集即各行的FIRST集合
		ArrayList<String> arrayList=yufafenxi.removeLeftDigui(p, map, list);//消除直接左递归
		yufafenxi.printNewWenfa(arrayList);//打印新的文法
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值