编译原理LL(1)文法(Java版)

这个版本为编译原理LL(1)文法实验代码的Java版本,比c++的那个多了一个窗口(虽然很丑,但是总比没有要好),好了,直接上代码

使用idea,在src下建一个叫bianyi的包(建议名字和我的一样,不然小白跑不起来~~)

创建DataCenter类

package bianyi;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class DataCenter {
    public final char emptyChar = '$';                              //空符号
    public final char endingChar = '#';                             //文法结束符号
    private List<String> grammarCollection;                         //文法集合
    private Map<Character,List<String>> newGrammarCollection;       //处理后的文法集合,格式为,“非终结符->产生式”,不含“|”
    private Set<Character> alphabetVn;                              //非终结符集合
    private Set<Character> alphabetVt;                              //终结符集合
    private char beginChar;                                         //开始符号
    private Map<Character,Set<Character>> firstCollection;          //FIRST集合
    private Map<Character,Set<Character>> followCollectionOfVn;     //FOLLOW集合
    private Map<Character,Map<Character,String>> analysisTable;     //预测分析表
    private List<List<String>> outLineString;                       //每一行的显示输出

    public void setOutLineString(List<List<String>> outLineString) {
        this.outLineString = outLineString;
    }

    public List<List<String>> getOutLineString() {
        return outLineString;
    }

    public Map<Character, List<String>> getNewGrammarCollection() {
        return newGrammarCollection;
    }

    public List<String> getGrammarCollection() {
        return grammarCollection;
    }

    public void setGrammarCollection(List<String> grammarCollection) {
        this.grammarCollection = grammarCollection;
    }

    public void setNewGrammarCollection(Map<Character, List<String>> newGrammarCollection) {
        this.newGrammarCollection = newGrammarCollection;
    }

    public Set<Character> getAlphabetVn() {
        return alphabetVn;
    }

    public void setAlphabetVn(Set<Character> alphabetVn) {
        this.alphabetVn = alphabetVn;
    }

    public Set<Character> getAlphabetVt() {
        return alphabetVt;
    }

    public void setAlphabetVt(Set<Character> alphabetVt) {
        this.alphabetVt = alphabetVt;
    }

    public char getBeginChar() {
        return beginChar;
    }

    public void setBeginChar(char beginChar) {
        this.beginChar = beginChar;
    }

    public Map<Character, Set<Character>> getFirstCollection() {
        return firstCollection;
    }

    public void setFirstCollection(Map<Character, Set<Character>> firstCollection) {
        this.firstCollection = firstCollection;
    }

    public Map<Character, Set<Character>> getFollowCollectionOfVn() {
        return followCollectionOfVn;
    }

    public void setFollowCollectionOfVn(Map<Character, Set<Character>> followCollectionOfVn) {
        this.followCollectionOfVn = followCollectionOfVn;
    }

    public Map<Character, Map<Character, String>> getAnalysisTable() {
        return analysisTable;
    }

    public void setAnalysisTable(Map<Character, Map<Character, String>> analysisTable) {
        this.analysisTable = analysisTable;
    }
}

创建CreateFirst类

package bianyi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/*
* 思想:
如果产生式右部第一个字符为终结符,则将其计入左部first集

如果产生式右部第一个字符为非终结符执行以下步骤
求该非终结符的first集
将该非终结符的非$first集计入左部的first集
若存在$,则将指向产生式的指针右移
若不存在$,则停止遍历该产生式,进入下一个产生式
若已经到达产生式的最右部的非终结符,则将$加入左部的first集
处理数组中重复的first集中的终结符
* */
public class CreateFirst {
    private DataCenter dataCenter;
    private Map<Character, Set<Character>> firstCollection;                 //FIRST集合

    public CreateFirst(DataCenter dataCenter) {
        this.dataCenter = dataCenter;
        firstCollection = new HashMap();
    }

    //构造FIRST集合
    public void buildFirst(){
        for (Character characterVt : dataCenter.getAlphabetVt()){           //终结符的first集只包含自身
            firstCollection.put(characterVt,new HashSet());
            firstCollection.get(characterVt).add(characterVt);
        }

        for (Character  characterVn: dataCenter.getAlphabetVn())
            buildVnFirst(characterVn);

        dataCenter.setFirstCollection(firstCollection);                     //保存first集
    }

    //构造非终结符的first集
    private Set<Character> buildVnFirst(Character characterVn){
        if(firstCollection.containsKey(characterVn))return firstCollection.get(characterVn);
        HashSet<Character> arrayFirst = new HashSet();
        for (String i : dataCenter.getNewGrammarCollection().get(characterVn)) {
            for (int j = 0; j < i.length(); j++) {
                Set<Character> temp = buildVnFirst(i.charAt(j));
                for (Character k : temp) {
                    if (k!=dataCenter.emptyChar)
                        arrayFirst.add(k);
                }
                if (!temp.contains(dataCenter.emptyChar))break;
                if(j == i.length() - 1)arrayFirst.add(dataCenter.emptyChar);
            }
        }
        firstCollection.put(characterVn,arrayFirst);
        return firstCollection.get(characterVn);
    }
}

创建CreateFollow类

package bianyi;
import java.util.*;
/*
* 思想:
对于文法G中每个非终结符A构造FOLLOW(A)的办法是,连续使用下面的规则,直到每个FOLLOW不在增大为止.
对于文法的开始符号S,置#于FOLLOW(S)中;
若A->aBb是一个产生式,则把FIRST(b)\{ε}加至FOLLOW(B)中;
若A->aB是一个产生式,或A->aBb是一个产生式而b=>ε(即ε∈FIRST(b))则把FOLLOW(A)加至FOLLOW(B)中
* */
public class CreateFollow {
    private DataCenter dataCenter;
    private Map<Character, Set<Character>> followCollectionOfVn;     //FOLLOW集合
    private List<List<Character>> insertPointer;                     //插入指针向量
    public CreateFollow(DataCenter dataCenter) {
        this.dataCenter = dataCenter;
        followCollectionOfVn = new HashMap();
        insertPointer = new ArrayList();
    }

    //构造follow集合
    public void buildFollow(){
        for (Character characterVn : dataCenter.getAlphabetVn())
            followCollectionOfVn.put(characterVn,new HashSet());

        followCollectionOfVn.get(dataCenter.getBeginChar()).add(dataCenter.endingChar);     //文法的开始符号的FOLLOW集添加'#'
        for (Character characterVn : dataCenter.getAlphabetVn()) {
            for (String nString : dataCenter.getNewGrammarCollection().get(characterVn)) {
                for (int countIndex = 0; countIndex < nString.length(); countIndex++) {
                    if (buildVnFOLLOW(nString.charAt(countIndex),nString,countIndex+1) && characterVn!=nString.charAt(countIndex)){
                        List<Character> temp = new ArrayList();
                        temp.add(characterVn);
                        temp.add(nString.charAt(countIndex));
                        insertPointer.add(temp);
                    }
                }
            }
        }
        addElement();
        dataCenter.setFollowCollectionOfVn(followCollectionOfVn);
    }

    //构造非终结符FOLLOW集合
    private Boolean buildVnFOLLOW(char characterVn, String nString, int countIndex){
        if (!dataCenter.getAlphabetVn().contains(characterVn))return false;
        for (int i = countIndex; i < nString.length(); i++) {
            Set<Character> temp = dataCenter.getFirstCollection().get(nString.charAt(countIndex));
            for (Character character : temp) {
                if (character!=dataCenter.emptyChar)followCollectionOfVn.get(characterVn).add(character);
            }
            if (!temp.contains(dataCenter.emptyChar))
                return false;
        }
        return true;
    }

    //A->aB情况,把follow(A)添加至follow(B)
    private void addElement(){
        for (Character characterVn : dataCenter.getAlphabetVn()) {
            for (List<Character> pointer : insertPointer) {
                for (Character character : followCollectionOfVn.get(pointer.get(0))) {
                    followCollectionOfVn.get(pointer.get(1)).add(character);
                }
            }
        }
    }
}

创建CreateTable类

package bianyi;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/*
思想:
对文法G的每个产生式A->a执行第二步和第三步;
对每个终结符a∈FIRST(a),把A->a加至M[A,a]中;
若ε∈FIRST(a),则把任何b∈FOLLOW(A)把A->a加至M[A,b]中;
把所有无定义的M[A,a]标上出错标志.
* */
public class CreateTable {
    private DataCenter dataCenter;
    private Map<Character, Map<Character,String>> analysisTable;     //预测分析表

    public CreateTable(DataCenter dataCenter) {
        this.dataCenter = dataCenter;
        analysisTable = new HashMap();
    }

    //构造分析表
    public void buildAnalysisTable(){
/*        for (Character characterVn : dataCenter.getAlphabetVn()) {                          //表格初始化为空
            for (Character characterVt : dataCenter.getAlphabetVt()) {
                Map<Character,String> temp = new HashMap();
                temp.put(characterVt,"");
                if (characterVt!=dataCenter.emptyChar)analysisTable.put(characterVn,temp);
            }
            Map<Character,String> temp = new HashMap();
            temp.put(dataCenter.endingChar,"");
            analysisTable.put(characterVn,temp);
        }*/
        for (Character characterVn : dataCenter.getAlphabetVn()){                               //表格初始化为空
            analysisTable.put(characterVn,new HashMap());
        }
        for (Character characterVn : dataCenter.getAlphabetVn()) {
            for (Character characterVt : dataCenter.getAlphabetVt()) {
                if (characterVt!=dataCenter.emptyChar)
                    analysisTable.get(characterVn).put(characterVt,"");
            }
            analysisTable.get(characterVn).put(dataCenter.endingChar,"");
        }

        for (Character characterVn : dataCenter.getAlphabetVn()) {
            for (String nString : dataCenter.getNewGrammarCollection().get(characterVn)) {
                buildVnAnalysisTable(characterVn,nString);
            }
        }
        dataCenter.setAnalysisTable(analysisTable);
    }

    //构造非终结符分析表
    private void buildVnAnalysisTable(char characterVn, String nString){
        Set<Character> characters = dataCenter.getFirstCollection().get(nString.charAt(0));
        for (Character character : characters) {
            if (character!=dataCenter.emptyChar)analysisTable.get(characterVn).put(character,nString);
        }
        if (characters.contains(dataCenter.emptyChar)){
            for (Character character : dataCenter.getFollowCollectionOfVn().get(characterVn)) {
                analysisTable.get(characterVn).put(character,nString);
            }
        }
    }
}

创建Implement类

package bianyi;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/*
* 思想:
预测分析程序的总控程序在任何时候都是按STACK栈顶符号X和当前的输入符号行事的,对于任何(X,a),总控程序
每次都执行下述三种可能的动作之一;
若X=a=”#”,则宣布分析成功,停止分析过程.
若X=a≠”#”,则把X从STACK栈顶逐出,让a指向下一个输入符号.
若X是一个非终结符,则查看分析表M,若M[A,a]中存放着关于X的一个产生式,那么,首先把X逐出STACK栈顶,
然后把产生式的右部符号串按反序一一推进STACK栈(若右部符号为ε,则意味着不推什么东西进栈).
在把产生式的右部符号推进栈的同时应做这个产生式相应得语义动作,若M[A,a]中存放着”出错标志”,则调用出错诊察程序ERROR.
* */
//对输入的字符串进行分析
public class Implement {
    private DataCenter dataCenter;
    private String receiveString;                                   //需要分析的字符串
    private List<List<String>> outLineString;                       //每一行的显示输出

    public Implement(DataCenter dataCenter, String receiveString) {
        this.dataCenter = dataCenter;
        outLineString = new ArrayList();
        this.receiveString = receiveString;
    }

    //存储每行的内容
    private void outLineCreate(int countOfStep, StringBuffer stackOfString, int indexOfReceiveString, String createFormula, String behave){
        List<String> outLine = new ArrayList();
        outLine.add(Integer.toString(countOfStep));
        outLine.add(stackOfString.toString());
        String temp = "";
        for (int i = 0; i < indexOfReceiveString; i++) {
            temp+=" ";
        }
        temp+=receiveString.substring(indexOfReceiveString);
        outLine.add(temp);
        outLine.add(createFormula);
        outLine.add(behave);
        outLineString.add(outLine);
    }

    //输入需要分析的字符串
    public void inputString()
    {
        System.out.print("请输入字符串:");
        Scanner scanner = new Scanner(System.in);
        receiveString = scanner.nextLine();
    }

    //字符串分析程序总控
    public void analysisBegin(){
        receiveString+="#";                                         //输入的字符串尾添加‘#’
        List<Character> stackOfChar = new ArrayList();              //初始化符号栈
        StringBuffer stackOfString = new StringBuffer();            //初始化符号栈的字符串表示
        int countOfStep = 0;                                        //步骤计数器
        int indexOfReceiveString = 0;                               //即将处理输入串的字符下标
        stackOfChar.add('#');
        stackOfChar.add('E');
        stackOfString.append("#E");
        outLineCreate(countOfStep,stackOfString,indexOfReceiveString,"","初始化");
        while (true){
            countOfStep++;                                          //步骤计数器加一
            if (!dataCenter.getAlphabetVn().contains(stackOfChar.get(stackOfChar.size()-1))){                           //如果为非终结符
                if (stackOfChar.get(stackOfChar.size()-1) == receiveString.charAt(indexOfReceiveString)){               //如果栈顶和字符串顶字符相同
                    if (stackOfChar.get(stackOfChar.size()-1) == '#'){                                                  //栈顶和字符串顶字符都为‘#‘
                        outLineCreate(countOfStep,stackOfString,indexOfReceiveString,"","success");   //解析成功,退出循环
                        break;
                    }else{
                        indexOfReceiveString++;                                                                         //下标加一
                        stackOfChar.remove(stackOfChar.size()-1);                                                 //移除栈顶元素
                        stackOfString.deleteCharAt(stackOfString.length()-1);                                           //移除字符串栈顶字符
                        outLineCreate(countOfStep,stackOfString,indexOfReceiveString,"","GETNEXT(I)");//存储行数据
                    }
                    continue;
                }
                outLineCreate(countOfStep,stackOfString,indexOfReceiveString,"","ERROR");             //解析失败,退出循环
                break;
            }

            String temp = dataCenter.getAnalysisTable().get(stackOfChar.get(stackOfChar.size() - 1)).get(receiveString.charAt(indexOfReceiveString));//得到分析表里面的内容
            if (temp == null || temp.isEmpty()){
                outLineCreate(countOfStep,stackOfString,indexOfReceiveString,"","ERROR");             //解析失败,退出循环
                break;
            }
            StringBuffer createFormula = new StringBuffer();                            //产生式构建
            createFormula.append(stackOfChar.get(stackOfChar.size() - 1));
            createFormula.append("->");
            createFormula.append(temp);
            stackOfChar.remove(stackOfChar.size()-1);                             //移除栈顶元素
            stackOfString.deleteCharAt(stackOfString.length()-1);                       //移除字符串栈顶字符
            if (temp.charAt(temp.length()-1) == dataCenter.emptyChar){
                outLineCreate(countOfStep,stackOfString,indexOfReceiveString,createFormula.toString(),"POP");                 //非终结符->空,显示pop指令
                continue;
            }
            StringBuffer behave = new StringBuffer("POP,PUSH(");						//动作字符串初始化
            for (int i = temp.length() - 1; i >= 0; i--) {                              //将产生式右部倒插入栈及栈字符以及生成动作字符串
                stackOfChar.add(temp.charAt(i));                                        //栈顶添加新元素
                stackOfString.append(temp.charAt(i));
                behave.append(temp.charAt(i));
            }
            behave.append(')');
            outLineCreate(countOfStep,stackOfString,indexOfReceiveString,createFormula.toString(),behave.toString());
        }
        dataCenter.setOutLineString(outLineString);
    }
}

创建InPut类

package bianyi;
import java.util.*;

//进行文法写入,得到新文法,非终结符,终结符,开始符号
public class InPut {
    private DataCenter dataCenter;
    private List<String> grammarCollection;                         //文法集合
    private Set<Character> alphabetVn;                              //非终结符集合
    private Set<Character> alphabetVt;                              //终结符集合
    private char beginChar;                                         //开始符号
    private Map<Character,List<String>> newGrammarCollection;       //处理后的文法集合,格式为,“非终结符->产生式”,不含“|”

    public InPut(DataCenter dataCenter) {
        this.dataCenter = dataCenter;
        alphabetVt = new HashSet();
        alphabetVn = new HashSet();
        grammarCollection = new ArrayList();
        newGrammarCollection = new HashMap();
    }

    //写入文法
    public void readGrammar(){
        System.out.println("请输入文法(end表示输入结束,$代表空):");
        Scanner scanner = new Scanner(System.in);
        String partGrammar;
        while(true){
            partGrammar = scanner.nextLine();
            if("end".equals(partGrammar))
                break;
            else
                grammarCollection.add(partGrammar);
        }
        dataCenter.setGrammarCollection(grammarCollection);
    }

    //处理输入的文法,识别开始符号,非终结符号,终结符号,并得到处理后的文法
    public void analysisGrammar(){
        beginChar = dataCenter.getGrammarCollection().get(0).charAt(0);             //识别开始符号
        dataCenter.setBeginChar(beginChar);

        for (String i : dataCenter.getGrammarCollection())                          //识别非终结符
            alphabetVn.add(i.charAt(0));
        dataCenter.setAlphabetVn(alphabetVn);

        for (String i : dataCenter.getGrammarCollection()){                         //识别终结符号并处理文法
            String temp = "";
            List<String> arrayString = new ArrayList();
            for (int j = 3; j <= i.length(); j++) {
                if(j == i.length() || i.charAt(j) == '|'){
                    arrayString.add(temp);
                    temp = "";
                    continue;
                }
                temp+=i.charAt(j);
                if(!alphabetVn.contains(i.charAt(j)))
                    alphabetVt.add(i.charAt(j));
            }
            newGrammarCollection.put(i.charAt(0),arrayString);
        }
        dataCenter.setAlphabetVt(alphabetVt);
        dataCenter.setNewGrammarCollection(newGrammarCollection);
    }
}

创建ControlCenter类

package bianyi;

import javax.swing.*;

public class ControlCenter {
    private DataCenter dataCenter;

    public ControlCenter() {
        dataCenter = new DataCenter();
    }

    //文法输入
    public void ctrlInPut(){
        InPut inPut = new InPut(dataCenter);
        //inPut.readGrammar();
        inPut.analysisGrammar();
    }

    //生成First集合
    public void ctrlCreateFirst(){
        CreateFirst createFirst = new CreateFirst(dataCenter);
        createFirst.buildFirst();
    }

    //生成follow集合
    public void ctrlCreateFollow(){
        CreateFollow createFollow = new CreateFollow(dataCenter);
        createFollow.buildFollow();
    }

    //生成分析表
    public void ctrlCreateTable(){
        CreateTable createTable = new CreateTable(dataCenter);
        createTable.buildAnalysisTable();
    }

    //分析程序
    public void ctrlImplement(String receiveString){
        Implement implement = new Implement(dataCenter, receiveString);
        implement.analysisBegin();
    }

    //窗口
    public void ctrlWindows(){
        Windows windows = new Windows("编译原理");
        windows.createWindows();
    }

    //返回数据中心
    public DataCenter getDataCenter() {
        return dataCenter;
    }
}

创建Windows类

package bianyi;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Windows{
    private ControlCenter controlCenter;
    private JFrame myWindows;
    private JTextArea jTextArea;
    private TextField textField;
    public Windows(String titleString) {
        controlCenter = new ControlCenter();
        myWindows = new JFrame(titleString);
    }

    //初始化窗口
    private void init(){
        myWindows.setVisible(true);
        myWindows.setLocation(450,50);
        myWindows.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    //创建窗口
    public void createWindows(){
        init();
        myWindows.setLayout(new GridLayout(2,1));       //窗口布局为网格式布局

        //面板1包含面板2,为文法输入
        JPanel jPanel1 = new JPanel(new BorderLayout());
        jTextArea = new JTextArea(20, 60);
        jTextArea.setText("在这里输入文法");
        JScrollPane jScrollPane = new JScrollPane(jTextArea);
        jPanel1.add(jScrollPane,BorderLayout.CENTER);

        //面板2为,文法输入,first集,follow集,分析表四个按钮
        JPanel jPanel2 = new JPanel(new GridLayout(1,4));
        JButton jButton1 = new JButton("提交文法");
        JButton jButton2 = new JButton("first集");
        JButton jButton3 = new JButton("follow集");
        JButton jButton4 = new JButton("分析表");
        jPanel2.add(jButton1);
        jPanel2.add(jButton2);
        jPanel2.add(jButton3);
        jPanel2.add(jButton4);
        jPanel1.add(jPanel2,BorderLayout.SOUTH);

        //面板3包含面板4,为语句输入
        JPanel jPanel3 = new JPanel(new BorderLayout());
        textField = new TextField("在这里输入语句",70);
        jPanel3.add(textField,BorderLayout.CENTER);

        //面板4为语句输入按钮
        JPanel jPanel4 = new JPanel(new GridLayout(1,2));
        JButton jButton5 = new JButton("提交语句");
        JButton jButton6 = new JButton("分析过程");
        jPanel4.add(jButton5);
        jPanel4.add(jButton6);
        jPanel3.add(jPanel4,BorderLayout.SOUTH);

        //在窗口中添加面板
        myWindows.add(jPanel1);
        myWindows.add(jPanel3);
        myWindows.pack();

        //给按钮添加监听器
        ActionListen actionListen = new ActionListen();
        jButton1.addActionListener(actionListen);
        jButton2.addActionListener(actionListen);
        jButton3.addActionListener(actionListen);
        jButton4.addActionListener(actionListen);
        jButton5.addActionListener(actionListen);
        jButton6.addActionListener(actionListen);
    }

    //监听器
    class ActionListen implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String actionCommand = e.getActionCommand();
            if ("提交文法".equals(actionCommand)){
                ArrayList<String> grammarCollection = new ArrayList();
                String[] strings = jTextArea.getText().split("\n");
                for (String str : strings)
                    grammarCollection.add(str);
                controlCenter.getDataCenter().setGrammarCollection(grammarCollection);
                controlCenter.ctrlInPut();
                controlCenter.ctrlCreateFirst();
                controlCenter.ctrlCreateFollow();
                controlCenter.ctrlCreateTable();

                System.out.println("提交的文法为:");
                for (String s : grammarCollection) {
                    System.out.println(s);
                }
            }else if ("first集".equals(actionCommand)){
                MyDialogDemo myDialogDemo = new MyDialogDemo();
                myDialogDemo.setTitle("first集");

                //输出
                if (controlCenter.getDataCenter().getFirstCollection()==null){
                    JLabel jLabel = new JLabel("请先点击提交文法");
                    myDialogDemo.add(jLabel);
                }else{
                    Map<Character, Set<Character>> firstCollection = controlCenter.getDataCenter().getFirstCollection();
                    Set<Character> alphabetVn = controlCenter.getDataCenter().getAlphabetVn();
                    jTextArea = new JTextArea(30, 60);
                    JScrollPane jScrollPane = new JScrollPane(jTextArea);
                    myDialogDemo.add(jScrollPane,BorderLayout.CENTER);
                    for (Character characterVn : alphabetVn) {
                        jTextArea.append("FIRST("+characterVn+") = { ");
                        for (Character character : firstCollection.get(characterVn)) {
                            jTextArea.append(character+" ");
                        }
                        jTextArea.append("}\r\n");
                    }
                }

                System.out.println("first集构建程序结束");
            }else if ("follow集".equals(actionCommand)){
                MyDialogDemo myDialogDemo = new MyDialogDemo();
                myDialogDemo.setTitle("follow集");

                //输出
                if (controlCenter.getDataCenter().getFollowCollectionOfVn()==null){
                    JLabel jLabel = new JLabel("请先点击提交文法");
                    myDialogDemo.add(jLabel);
                }else{
                    Map<Character, Set<Character>> followCollectionOfVn = controlCenter.getDataCenter().getFollowCollectionOfVn();
                    Set<Character> alphabetVn = controlCenter.getDataCenter().getAlphabetVn();
                    jTextArea = new JTextArea(30, 60);
                    JScrollPane jScrollPane = new JScrollPane(jTextArea);
                    myDialogDemo.add(jScrollPane,BorderLayout.CENTER);
                    for (Character characterVn : alphabetVn) {
                        jTextArea.append("FOLLOW("+characterVn+") = { ");
                        for (Character character : followCollectionOfVn.get(characterVn)) {
                            jTextArea.append(character+" ");
                        }
                        jTextArea.append("}\r\n");
                    }
                }
                System.out.println("follow集构建程序结束");
            }else if ("分析表".equals(actionCommand)){
                MyDialogDemo myDialogDemo = new MyDialogDemo();
                myDialogDemo.setTitle("分析表");

                //输出
                if (controlCenter.getDataCenter().getAnalysisTable()==null){
                    JLabel jLabel = new JLabel("请先点击提交文法");
                    myDialogDemo.add(jLabel);
                }else{
                    Set<Character> alphabetVn = controlCenter.getDataCenter().getAlphabetVn();
                    Set<Character> alphabetVt = controlCenter.getDataCenter().getAlphabetVt();
                    Map<Character, Map<Character, String>> analysisTable = controlCenter.getDataCenter().getAnalysisTable();
                    jTextArea = new JTextArea(30, 60);
                    JScrollPane jScrollPane = new JScrollPane(jTextArea);
                    myDialogDemo.add(jScrollPane,BorderLayout.CENTER);
                    jTextArea.append("  ");
                    for (Character characterVt : alphabetVt) {
                        if (characterVt!=controlCenter.getDataCenter().emptyChar)
                            jTextArea.append("\t"+characterVt);
                    }
                    jTextArea.append("\t"+controlCenter.getDataCenter().endingChar+"\r\n");
                    for (Character characterVn : alphabetVn) {
                        jTextArea.append(characterVn.toString());
                        for (Character characterVt : alphabetVt) {
                            if (characterVt!=controlCenter.getDataCenter().emptyChar){
                                if (/*analysisTable.get(characterVn).get(characterVt)==null || */analysisTable.get(characterVn).get(characterVt).isEmpty())
                                    jTextArea.append("\t"+"  ");
                                else
                                    jTextArea.append("\t"+characterVn+"->"+analysisTable.get(characterVn).get(characterVt));
                            }
                        }
                        if (analysisTable.get(characterVn).get(controlCenter.getDataCenter().endingChar).isEmpty())
                            jTextArea.append("\t"+"  \r\n");
                        else
                            jTextArea.append("\t"+characterVn+"->"+analysisTable.get(characterVn).get(controlCenter.getDataCenter().endingChar)+"\r\n");
                    }
                }
                System.out.println("分析表构建程序结束");
            }else if ("提交语句".equals(actionCommand)){
                String text = textField.getText();
                controlCenter.ctrlImplement(text);

                System.out.println("提交的语句为:"+text);
            }else if ("分析过程".equals(actionCommand)){
                MyDialogDemo myDialogDemo = new MyDialogDemo();
                myDialogDemo.setTitle("提交语句");

                //输出
                if (controlCenter.getDataCenter().getOutLineString()==null){
                    JLabel jLabel = new JLabel("请先点击提交语句或者查看文法是否提交");
                    myDialogDemo.add(jLabel);
                }else{
                    jTextArea = new JTextArea(30, 60);
                    JScrollPane jScrollPane = new JScrollPane(jTextArea);
                    myDialogDemo.add(jScrollPane,BorderLayout.CENTER);
                    List<List<String>> outLineString = controlCenter.getDataCenter().getOutLineString();
                    jTextArea.append("步骤\t\t符号栈\t\t输入串\t\t所用产生式\t\t动作\r\n");
                    for (List<String> strings : outLineString) {
                        for (String string : strings) {
                            jTextArea.append(string+"\t\t");
                        }
                        jTextArea.append("\r\n");
                    }
                }

                System.out.println("分析程序结束");
            }
        }
    }

    //创建弹窗
    private class MyDialogDemo extends JDialog{
        public MyDialogDemo() {
            setVisible(true);
            setBounds(100,100,500,400);
            Container container = this.getContentPane();
            container.setBackground(Color.white);
        }
    }
}

创建Main类

package bianyi;

import java.util.*;

public class Main {
    public static void main(String[] args) {
/*        ControlCenter controlCenter = new ControlCenter();
        DataCenter dataCenter = controlCenter.getDataCenter();
        controlCenter.ctrlWindows();
        List<String> grammarCollection = dataCenter.getGrammarCollection();
        for (String s : grammarCollection) {
            System.out.println(s);
        }*/
        Windows windows = new Windows("编译原理");
        windows.createWindows();
/*        ControlCenter controlCenter = new ControlCenter();
        controlCenter.ctrlWindows();*/

    }
}
/*
+ $ * ( ) i
E T G H F

E->TG
G->+TG|$
T->FH
H->*FH|$
F->(E)|i
end

E->TG
H->*FH|$
F->(E)|i
T->FH
G->+TG|$
end
*

*
* */

在Main类里面启动一下就可以了,在写代码的时候我特地写了ControlCenter类,方便前期编写的调试,有兴趣的也可以更改一下Main类中的调用,其中被我注释的代码效果和没被注释代码是一样的,也可以通过调用ControlCenter类里的方法来使用控制台实现,只不过输出要自己来输出一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

花了我一下午写的代码不应该点个赞吗(doge)

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值