编译原理 LL1文法First集算法实现

简介:

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class First {
    private Map<String, Set<Character>> first = new TreeMap<String, Set<Character>>();
    private Map<String, String[]> mp = null;
    public First(Map<String, String[]> mp) {
        super();
        this.mp = mp;
    }
    public Map<String, Set<Character>> getFirstSet(){
        return first;
    }
    private Set<Character> findFirst(String curNode, String[] rightNodes){
         if(first.containsKey(curNode)) return first.get(curNode); 
         Set<Character> st = new TreeSet<Character>();
         for(int i=0; i<rightNodes.length; ++i){
                for(int j=0; j<rightNodes[i].length(); ++j){
                    String nextNode = ""+rightNodes[i].charAt(j);
                    if(!mp.containsKey(nextNode)){//终结点
                        st.add(nextNode.charAt(0));
                        break;
                    }
                    else{//非终结点
                        if(j+1<rightNodes[i].length() && rightNodes[i].charAt(j+1)=='\''){
                            nextNode += rightNodes[i].charAt(j+1);
                            ++j;
                        }
                        if(mp.containsKey(nextNode)){
                            Set<Character> tmpSt = findFirst(nextNode, mp.get(nextNode));
                            st.addAll(tmpSt);
                            if(!tmpSt.contains('$'))
                                break;
                        }
                    }
                }
         }
         first.put(curNode, st);
         return st;
    }
    
    public String firstKernealCode(){
         String content = "";
         for(String leftNode : mp.keySet()){
             String[] rightNodes = mp.get(leftNode);
             findFirst(leftNode, rightNodes);
         }
         //打印first集合
         System.out.println("First集合如下:");
         for(Map.Entry<String, Set<Character>> entry : first.entrySet()){
             content += entry.getKey() + "  :  " + entry.getValue() + "\n";
             System.out.println(entry.getKey() + "  :  " + entry.getValue());
         }
         return content;
    }
    
    public static void main(String[] args){
//        String[] rightLinearGrammar = {
//                "E->TE\'",
//                "E\'->+TE\'|$",
//                "T->FT\'",
//                "T\'->*FT\'|$",
//                "F->(E)|i"
//        };
        
        String[] rightLinearGrammar = {
                "S->ABc",
                "A->a|$",
                "B->b"
        };
        Map<String, String[]> mp = new LinkedHashMap<String, String[]>();
        try{
            for(int i=0; i<rightLinearGrammar.length; ++i){
                String split1[] = rightLinearGrammar[i].split("->");
                String split2[] = split1[1].split("\\|");
                mp.put(split1[0], split2);
            }
            
        } catch(Exception e){
            e.printStackTrace();
            System.out.println("右线性文法错误!");
        }
        new First(mp).firstKernealCode();
    }
}

目录
相关文章
|
6月前
|
网络安全
编译原理复习二:Top-Down分析LL(1)文法的判断与LL(1)分析表的构造(附题目与答案 超详细)
编译原理复习二:Top-Down分析LL(1)文法的判断与LL(1)分析表的构造(附题目与答案 超详细)
412 1
|
6月前
|
算法 Python
Python 数据结构和算法:解释什么是递归,提供一个使用递归的例子。
Python 数据结构和算法:解释什么是递归,提供一个使用递归的例子。
43 0
|
6月前
|
算法 Python
Python 数据结构和算法:解释什么是 Big O 表示法?举例说明几种常见的时间复杂度。
Python 数据结构和算法:解释什么是 Big O 表示法?举例说明几种常见的时间复杂度。
126 0
编译原理(六) 文法的分类
编译原理(六) 文法的分类
106 0
编译原理实验:NFA转化为DFA
编译原理实验:NFA转化为DFA
174 0
|
6月前
|
存储 编译器 测试技术
【编译原理】LL(1)分析法:C/C++实现
【编译原理】LL(1)分析法:C/C++实现
524 0
|
6月前
|
存储 算法 Python
Python 数据结构和算法: 解释动态规划的概念,并提供一个实际应用的例子。
Python 数据结构和算法: 解释动态规划的概念,并提供一个实际应用的例子。
43 0
编译原理(四) 语言及其文法的基本概念
编译原理(四) 语言及其文法的基本概念
|
存储 自然语言处理 算法
语法设计——基于LL(1)文法的预测分析表法
语法设计——基于LL(1)文法的预测分析表法
268 0
语法设计——基于LL(1)文法的预测分析表法