LL(1)文法java代码

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;


public class complies {
    public static void main(String[] args) throws Exception {
        getFF ff = getFF.getinstanceFF();
        ff.readTxt();
        ff.getFirst();
        ff.getFollow();
        ff.getSelect();
        ff.test();
    }
}

class getFF{
    private static final getFF FF = new getFF(); 
    private HashMap<Character,Nonterminal> nonterminals = new HashMap<>();
    private ArrayList<String> grammars = new ArrayList<>();
    private Character first = null;//文法开始符

    //单例模式
    private getFF(){}
    public static getFF getinstanceFF(){
        return FF;
    }

    //初始化各个非终结符的实例
    public void readTxt() throws IOException {
        File file = new File("grammar.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));

        System.out.println();
        System.out.println("===定义的文法是(可在grammar.txt文件中按下述格式输入文法):===");
        System.out.println("===这里#符号代表空,&符号代表结束符,大写字母代表非终结符,->代表箭头,其余符号代表终结符===");
        String str = null;
        while((str = br.readLine())!=null){
            if(str.length()==0){//防止空行出现
                continue;
            }
            grammars.add(str);
            System.out.println(str);
        }
        System.out.println();

        first = grammars.get(0).charAt(0);

        for(String line : grammars){//初始化非终结符各个实例
            if(!nonterminals.containsKey(line.charAt(0))){
                nonterminals.put(line.charAt(0),new Nonterminal());
            }
        }

        br.close();
    }

    //求First集并展示
    public void getFirst() throws IOException{
        for(String line : grammars){//完成第一次循环并判断该非终结符是否可为空
            Nonterminal temp = nonterminals.get(line.charAt(0));
            for(int i = 3;i < line.length();++i){
                char c = line.charAt(i);
                if(c == '#'){
                    temp.setIsnull(true);
                }
                else if((i==3||line.charAt(i-1)=='|')){
                    if((c < 'A'||c > 'Z')){
                        temp.addFirst(c);//加入终结符集合
                    }
                    else{
                        temp.addFirstnonterminals(c);//加入非终结符集合(即T->F,F的first要加入T的first)
                    }
                }
            }
        }

        for(String line : grammars){//加入非终结符集合(即T->FH,如果F可为空,则H的first要加入T的first)
            Nonterminal temp = nonterminals.get(line.charAt(0));
            for(int i = 3;i < line.length();++i){
                if(i == 3 || line.charAt(i-1)=='|'){
                    while(i < line.length() && line.charAt(i) >= 'A' && line.charAt(i) <= 'Z'
                            && nonterminals.get(line.charAt(i)).isIsnull()){
                        if(i==line.length()-1||(i+1<line.length()&& line.charAt(i+1)=='|')){
                            temp.addFirst('#');
                            temp.setIsnull(true);
                        }
                        if( i+1 < line.length() && line.charAt(i+1)>= 'A' && line.charAt(i+1) <= 'Z'){
                            temp.addFirstnonterminals(line.charAt(++i));
                        }
                        else{
                            ++i;
                        }
                    }
                }
            }
        }

        boolean isChanged = true;
        var keyset = nonterminals.keySet();
        while(isChanged){
            isChanged = false;
            for(Character nonterminal : keyset){
                Nonterminal temp = nonterminals.get(nonterminal);
                var firstNonterminals = temp.getFirstNonterminals();
    
                for(Character firstterminal : firstNonterminals){
                    int num = temp.getFirst().size(); 
                    temp.addFirst(nonterminals.get(firstterminal).getFirst());
                    if(!isChanged && num != temp.getFirst().size()){
                        isChanged = true;
                    }
                }
            }
        }

        for(Character nonterminal : keyset){//S->AB
            if(nonterminals.get(nonterminal).isIsnull()){
                nonterminals.get(nonterminal).addFirst('#');
            }
        }        

        System.out.println("======各个非终结符的First集======");
        for(Character nonterminal : keyset){
            System.out.print(nonterminal+":");
            for(Character first : nonterminals.get(nonterminal).getFirst()){
                System.out.print(first+" ");
            }
            System.out.println();
        }
    }

    //求Follow集并展示
    public void getFollow(){
        nonterminals.get(grammars.get(0).charAt(0)).addFollow('$');//将$置入Follow(文法开始符号的follow集)

        for(String line : grammars){
            Character first = line.charAt(0);
            for(int i = line.length() - 1;i >= 3;--i){
                Character c = line.charAt(i);
                if(c =='#'){
                    continue;
                }
                if(i>3 && line.charAt(i-1) >= 'A' && line.charAt(i-1) <= 'Z' ){//follow集加入终结符,并处理各个非终结符Follow集的包含关系
                    if((c<'A' || c>'Z') && c!='|'){
                        nonterminals.get(line.charAt(i-1)).addFollow(c);
                    }
                    else if(c >= 'A' && c <= 'Z' && !nonterminals.get(c).isIsnull()){//当为空时,后面的步骤会添加first集,因此这里不用重复添加
                        nonterminals.get(line.charAt(i-1)).addFollow(nonterminals.get(c).getFirst());
                    }
                }
                if(i == line.length()-1||(i+1<line.length() && line.charAt(i+1)=='|')){//处理各个非终结符Follow集的包含关系
                    if(c >= 'A' && c <= 'Z'){
                        nonterminals.get(c).addFollowNonterminals(first);
                        while(i >= 4 && line.charAt(i-1) >= 'A' && line.charAt(i-1) <= 'Z' 
                                && nonterminals.get(line.charAt(i)).isIsnull()){
                            nonterminals.get(line.charAt(i-1)).addFollow(nonterminals.get(line.charAt(i)).getFirst());//#符号稍后处理
                            nonterminals.get(line.charAt(--i)).addFollowNonterminals(first);
                        }
                    }
                   
                }

            }
        }
        
        var keyset = nonterminals.keySet();
        boolean isChanged = true;
        while(isChanged){
            isChanged = false;
            for(Character nonterminal : keyset){
                Nonterminal temp = nonterminals.get(nonterminal);
                var followNonterminals = temp.getFollowNonterminals();
                for(Character followNonterminal : followNonterminals){
                    int num = temp.getFollow().size(); 
                    temp.addFollow(nonterminals.get(followNonterminal).getFollow());
                    if(!isChanged && num != temp.getFollow().size()){
                        isChanged = true;
                    }
                }
            }
        }

        System.out.println();
        System.out.println("======各个非终结符的Follow集======");
        for(Character nonterminal : keyset){
            System.out.print(nonterminal+":");
            for(Character follow : nonterminals.get(nonterminal).getFollow()){
                if(follow == '#'){
                    continue;
                }
                System.out.print(follow+" ");
            }
            System.out.println();
        }
    }

    //求Select集并展示
    public void getSelect(){
        System.out.println();
        System.out.println("=========Select集=========");

        for(String line : grammars){
            Character temp = line.charAt(0);
            Nonterminal nonterminal = nonterminals.get(temp);
            HashSet<Character> first = new HashSet<>();
            String nowLine = temp.toString() + "->";

            for(int i = 3;i<= line.length();++i){
                if(i==line.length()){
                    nonterminal.addGrammar(first, nowLine);
                    nowLine = temp.toString() + "->";
                    first= new HashSet<>();
                    continue;
                }
                if(line.charAt(i) == '|'){
                    nonterminal.addGrammar(first, nowLine);
                    nowLine = temp.toString() + "->";
                    first= new HashSet<>();
                    continue;
                }
                else{
                    nowLine += line.charAt(i);
                }
            }
        }

        //求各个产生式的first集合
        Set<Character> keySet = nonterminals.keySet();
        for(char key : keySet){
            Nonterminal temp = nonterminals.get(key);
            Set<String> keySet2 = temp.getGrammar().keySet();
            for(String key2 : keySet2){
                HashSet<Character> hashSet = temp.getGrammar().get(key2);
                Character c = key2.charAt(3);
                if(c == '#'){
                    hashSet.addAll(temp.getFollow());
                }
                else if(c < 'A' || c > 'Z'){
                    hashSet.add(c);
                }
                else{
                    hashSet.addAll(nonterminals.get(c).getFirst());
                    for(int i=4;i < key2.length();++i){
                        if(nonterminals.get(key2.charAt(i-1)).isIsnull()){
                            hashSet.addAll(nonterminals.get(key2.charAt(i)).getFirst());
                            if(i==key2.length()-1&&nonterminals.get(key2.charAt(i)).isIsnull()){
                                hashSet.addAll(temp.getFollow());
                            }
                        }
                    }
                }
            
            }
        }

        //打印select集
        for(Character key :keySet){
            Nonterminal temp = nonterminals.get(key);
            Set<String> keySet2 = temp.getGrammar().keySet();
            for(String key2:keySet2){
                System.out.print("select("+key2+") = {");
                HashSet<Character> hashSet = temp.getGrammar().get(key2);
                for(Character c : hashSet){
                    if(c == '#'){
                        continue;
                    }
                    System.out.print(c+" ");
                }
                System.out.println("}");
            }
        }
        System.out.println();
    }

    public void test(){
        String input = "i+i*i$";
        Queue<Character>que = new LinkedList<>();
        for(Character i :input.toCharArray()){
            que.offer(i);
        }
        Stack<Character>sta2 = new Stack<>();//栈
        sta2.push('$');
        sta2.push(first);

        while(sta2.size() > 1){
            Character c1 = sta2.pop();
            Character c2 = que.peek();
            if(c1>='A'&&c1<='Z'){
                Nonterminal temp = nonterminals.get(c1);
                HashMap<String,HashSet<Character>> tempGrammars = temp.getGrammar();
                Set<String> keySet = tempGrammars.keySet();
                boolean found = false;
                for(String key : keySet){
                    if(tempGrammars.get(key).contains(c2)){
                        found = true;
                        for(int i = key.length()-1;i>=3;--i){
                            if(key.charAt(i)=='#'){
                                break;
                            }
                            sta2.push(key.charAt(i));
                        }
                        break;
                    }
                }
                if(!found){
                    System.out.println(input + "  判断失败");
                    return;
                }
                
            }
            else if(c2 == '$'){
                if(c1<'A'||c1>'Z'){
                    System.out.println(input + "  判断失败");
                    return;
                }
                else{
                    if(!nonterminals.get(c1).isIsnull()){
                        System.out.println(input + "  判断失败");
                        return;
                    }
                }
            }
            else{
                if(c1!=c2){
                    System.out.println(input + "  判断失败");
                    return;
                }
                else {
                    que.poll();
                }
            }
            
        }
        System.out.println(input+"  判断成功");
    }
    
}

class Nonterminal{
    private boolean isnull = false;
    private HashSet<Character>firstNonterminals = new HashSet<>();
    private HashSet<Character>followNonterminals = new HashSet<>();
    private HashSet<Character>First = new HashSet<>();
    private HashSet<Character>Follow = new HashSet<>();
    private HashMap<String,HashSet<Character>>grammar = new HashMap<>();
    
    public HashMap<String,HashSet<Character>> getGrammar() {
        return grammar;
    }
    public void addGrammar(HashSet<Character>set, String grammar) {
        this.grammar.put(grammar,set);
    }

    public boolean isIsnull() {
        return isnull;
    }
    public void setIsnull(boolean isnull) {
        this.isnull = isnull;
    }

    public HashSet<Character> getFirstNonterminals() {
        return firstNonterminals;
    }
    public void addFirstnonterminals(Character firstnonterminal) {
        firstNonterminals.add(firstnonterminal);
    }

    public HashSet<Character> getFollowNonterminals() {
        return followNonterminals;
    }
    public void addFollowNonterminals(Character followNonterminal) {
        followNonterminals.add(followNonterminal);
    }

    public HashSet<Character> getFirst() {
        return First;
    }
    public void addFirst(Character first) {
        First.add(first);
    }
    public void addFirst(HashSet<Character>First) {
        this.First.addAll(First);
    }
    
    public HashSet<Character> getFollow() {
        return Follow;
    }
    public void addFollow(Character follow) {
        Follow.add(follow);
    }
    public void addFollow(HashSet<Character>Follow) {
        this.Follow.addAll(Follow);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ricky Alexander

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值