Java实现求FIRSTVT集(编译原理实验)

说明: 求一个非终结符的FIRSTVT集,满足两个规则:
(1)、对形如A→a…的产生式,则终结符a是非终结符A的FIRSTVT集;
(2)、若终结符a是非终结符A的FIRSTVT集,又有形如B→A…的产生式,则终结符a也是非终结符B的FIRSTVT集。
程序简介: 本程序包含两个类,一个FIRSTVT类封装了的数据的存取、方法以及输入输出的格式;另一个Grammar类,封装一个产生式。
FIRSTVT类结构:
在这里插入图片描述
FIRSTVT类源码:

package experiment3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class FIRSTVT {
    //用于存所有产生式
    public List<Grammar> grammars;

    //后进先出栈
    public ArrayDeque<String> stack;

    //数组F
    public int[][] F = new int[26][94];//非终结符范围A ~ Z,终结符范围'!' ~ '~'

    //结果
    Map<Character,List<Character>> result;

    public static final String RIGHT_INFER_QUOTE = " → ";

    public static final String REGEX = "\\|";

    public FIRSTVT() throws IOException {
        init();
    }

    public FIRSTVT(List<Grammar> grammars,ArrayDeque<String> stack){
        this.grammars = grammars;
        this.stack = stack;
    }

    /**
     * 输入以及初始化
     */
    public void init() throws IOException {
        grammars = new ArrayList<>();
        stack = new ArrayDeque<>();
        System.out.println("输入文法的产生式:形如A → Ba");
        System.out.println("约定所有非终结符为英文大写字母,终结符为!至~(ASCII码值33~126)");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while (!"".equals(line = br.readLine().trim())){
            String[] strings = line.split(RIGHT_INFER_QUOTE);
            for(String s : strings[1].split(REGEX)){
                Grammar grammar = new Grammar(strings[0],s);
                grammars.add(grammar);
                char cT = s.charAt(0);
                if (!Character.isUpperCase(cT)){//形如A → a...
                    insert(strings[0].charAt(0),cT);
                }else if (s.length()>1){
                    if (!Character.isUpperCase((cT = s.charAt(1)))){//形如A → Ba...
                        insert(strings[0].charAt(0),cT);
                    }
                }
            }
        }
        //System.out.println(grammars.toString());
        System.out.println("输入结束........");
    }

    /**
     *
     * @param A 非终结符
     * @param a 终结符
     */
    public void insert(char A,char a){
        if (F[A-'A'][a-'!'] == 0){
            F[A-'A'][a-'!'] = 1;
            stack.addLast(A+""+a);
            //输出栈顶的内容
            System.out.println("("+A+","+a+")");
        }
    }

    /**
     * 主程序
     */
    public void solve(){
        //init();
        if (stack == null){
            System.out.println("未初始化!");
            return;
        }
        while (!stack.isEmpty()){
            //取栈顶
            String s = stack.removeLast();
            char cN = s.charAt(0);
            char cT = s.charAt(1);
            for(Grammar grammar : grammars){
                if(grammar.right.charAt(0) == cN){//形如A → B...
                    insert(grammar.left.charAt(0),cT);
                }
            }
        }
    }


    /**
     *
     * @return  所有非终结符的FIRSTVT集
     */
    public Map<Character,List<Character>> getResult(){
        result = new HashMap<>();
        for(int i = 0;i<26;i++){
            for(int j = 0;j<94;j++){
                if(F[i][j] == 1){
                    char cN = (char)(i+'A');
                    char cT = (char)(j+'!');
                    if(result.containsKey(cN)){
                        result.get(cN).add(cT);
                    }else{
                        List<Character> cTList = new ArrayList<>();
                        cTList.add(cT);
                        result.put(cN,cTList);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 打印所有非终结符的FIRSTVT集
     */
    public void print(){
        System.out.println("所有非终结符的FIRSTVT集为:");
        //得到结果
        getResult();
        for(Character cN: result.keySet()){
            //得到非终结符的FIRSTVT集
            List<Character> cT = result.get(cN);
            System.out.println(String.format("FIRSTVT(%c)={%s}",cN,cT.toString().substring(1,3*cT.size()-1)));
        }
    }

    /**
     * 测试
     *
     * @param args
     * @throws IOException
     */
    /*测试案例
    S → #E#
E → E+T
E → T
T → T*F
T → F
F → P!F|P
P → (E)
P → i
    */
    public static void main(String[] args) throws IOException {
        FIRSTVT firstvt = new FIRSTVT();
        firstvt.solve();
        firstvt.print();
    }
}

Grammar类结构:
在这里插入图片描述
Grammar类源码:

package experiment3;

public class Grammar {
    public String left;//产生式左部
    public String right;//产生式右部

    public Grammar(){

    }

    public Grammar(String left,String right){
        this.left = left;
        this.right = right;
    }

    @Override
    public String toString() {
        return left + " → " +
                right;
    }
}

实验结果:
输入:
在这里插入图片描述
输出:
在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

b17a

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

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

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

打赏作者

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

抵扣说明:

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

余额充值