编译原理实现预测分析法(LL(1))

实现预测分析法的原理其实很简答,步骤如下:

1.判断文法有没有左递归,若有左递归,则对该文法消除左递归

2.对处理后的文法进行遍历,求出终结符号和非终结符号

3.求出first集合和follow集合

4.判断是不是LL(1)文法,若是,则构建预测分表

5.若是LL(1)文法,输入一个句子,模拟输出进栈出栈情况

截图如下:




代码如下:


package cn.mahui;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


public class Function {
public static List<String> oneFirstList=new ArrayList<>();
public static List<String> oneFollowList=new ArrayList<>();
/**
* 从指定文件中读取文法
* @param path(文件的路径)
* @return
* @throws IOException 
*/
public static String readGrammarFile(String path) throws IOException{
StringBuilder grammar=new StringBuilder();
File file=new File(path);
@SuppressWarnings("resource")
BufferedReader bufferedReader=new BufferedReader(new FileReader(file));
String readline;
while((readline=bufferedReader.readLine())!=null){
grammar.append(readline+"\n");
}
return grammar.toString();
}
/**
* 获得文法的产生式
* @param scanner(输入的文法)
* @return
*/
public static List<String> getGrammar(String scanner){
List<String> oldList=new ArrayList<>();
String[] grammarItems=scanner.split(" |\n");
for(int i=0;i<grammarItems.length;i++){
oldList.add(grammarItems[i]);
}
return oldList;
}
/**
* 获得每一条产生式
* @param scanner(输入的文法)
* @return
*/
public static List<String> getGrammarItems(String scanner){
List<String> oldList=new ArrayList<>();
List<String> oldListItems=new ArrayList<>();
String[] grammarItems=scanner.split(" |\n");
for(int i=0;i<grammarItems.length;i++){
oldList.add(grammarItems[i]);
String[] items=grammarItems[i].split(">|\\|");
//添加每一条产生式
for(int k=1;k<items.length;k++)
oldListItems.add(grammarItems[i].charAt(0)+"-->"+items[k]);
}
return oldListItems;
}
/**
* 如果vn包含str,则返回真,不包含返回false
* @param vn
* @param ch(要判断的字符串)
* @return
*/
public static boolean isContain(List<String> vn,String str){
for(int i=0;i<vn.size();i++){
if(vn.get(i).equals(str)){
return true;
}
}
return false;
}
/**
* 获得所有非终结符
* @param grammarItem(输入的文法)
* @return
*/
public static List<String> getVN(String grammarItems){
List<String> vn=new ArrayList<>();
String[] string=grammarItems.split("\n");
for(int i=0;i<string.length;i++){
int index=string[i].indexOf("-");
String str=string[i].substring(0, index);
if(vn.size()==0){
vn.add(str);
}else{
if(!isContain(vn, str)){
vn.add(str);
}
}
}
return vn;
}
/**
* 消除文法的左递归
* @param oldListItems(未消除左递归的每一台产生式的集合)
* @return
*/
public static  List<String> removeLeftRecursive(List<String> oldListItems){
List<String> newList=new ArrayList<>();
for(int i=0;i<oldListItems.size();i++){
if(oldListItems.get(i).charAt(0)==oldListItems.get(i).charAt(4)){
for(int j=0;j<oldListItems.size();j++){
if(oldListItems.get(j).startsWith(""+oldListItems.get(i).charAt(0))
&&oldListItems.get(j).length()==5){
newList.add(oldListItems.get(i).charAt(0)+"-->"+oldListItems.get(j).charAt(4)+oldListItems.get(i).charAt(0)+"’");
newList.add(oldListItems.get(i).charAt(0)+"’"+"-->"+oldListItems.get(i).substring(5, oldListItems.get(i).length())+oldListItems.get(i).charAt(0)+"’");
//~代表空
newList.add(oldListItems.get(i).charAt(0)+"’"+"-->"+"~");
}
}
}else{
int tag=0;
for(int k=0;k<newList.size();k++){
if(newList.get(k).contains(oldListItems.get(i).substring(1, oldListItems.get(i).length()))){
tag=1;
break;
}
}
if(tag==0){
newList.add(oldListItems.get(i));
}
}
}
return newList;
}
/**
* 获得非终结符号的first集合
* @param vn(非终结符号的集合)
* @param newList( 消除左递归后的文法)
* @return
*/
public static Map<String,List<String>> getFirst(List<String> vn,List<String> newList){
Map<String,List<String>> firstList=new HashMap<>();
for(int i=0;i<vn.size();i++){
oneFirstList.clear();
getOneFirst(vn.get(i),newList);
List<String> temp=new ArrayList<>();
for(int k=0;k<oneFirstList.size();k++){
temp.add(oneFirstList.get(k));
}
firstList.put(vn.get(i), temp);

}

return firstList;
}

/**
* 得到任意一个非终结符号的first集合
* @param vnItem(任意一个非终结符号)
* @param newList(消除左递归后的文法)
* @return
*/
public static void getOneFirst(String vnItem,List<String> newList){
for(int i=0;i<newList.size();i++){
if(vnItem.length()==1){

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值