- 目的与要求
通过完成LL(1)语法分析程序分析和调试,了解自顶向下语法分析的思路,熟悉判断LL (1)文法的方法,学会构造LL(1)文法的预测分析表以及对某一个输入串的分析过程。本实验在培养编程能力的同时培养自主学习和团队协作能力。
- 实验内容
- 从键盘读入要分析的文法,并判断正误;若无误,由程序自动构造FIRST、FOLLOW 集以及SELECT集合,判断是否为LL (1)文法;
分析的文法为G[E]:(0)E→ TE’ (1)E’→ +TE’ (2)E’→ε (3)T→ FT’
(4)T’→ *FT’ (5)T’→ε (6)F→ (E) (7)F→a
- 若符合LL (1)文法,由程序自动构造LL (1)分析表;
- 由算法判断给定的输入符号串a*(a+a)是否为该文法的句型。
/**
* Created by kovic on 2023/4/26.
* Use IntelliJ IDEA 2022.2.2
*/
import java.util.*;
public class LL1 {
public static void main(String[] args) {
Test test = new Test();
test.getNvNt();
test.Init();
test.createTable();
test.ouput();
System.out.println("");
test.analyzeLL();
}
}
class Test {
public HashMap<Character, HashSet<Character>> firstSet = new HashMap<Character, HashSet<Character>>();
public HashMap<String, HashSet<Character>> firstSetX = new HashMap<String, HashSet<Character>>();
public Character S = 'E';
public HashMap<Character, HashSet<Character>> followSet = new HashMap<Character, HashSet<Character>>();
public HashSet<Character> VnSet = new HashSet<Character>();
public HashSet<Character> VtSet = new HashSet<Character>();
public HashMap<Character, ArrayList<String>> experssionSet = new HashMap<Character, ArrayList<String>>();
public String[][] table;
public Stack<Character> analyzeStatck = new Stack<Character>();
public String strInput = "a*(a+a)$";
public String action = "";
int index = 0;
Scanner scanner = new Scanner(System.in);
public String[] inputExperssion={};
public void Init() {
for (String e : inputExperssion) {
String[] str = e.split("->");
char c = str[0].charAt(0);
ArrayList<String> list = experssionSet.containsKey(c) ? experssionSet.get(c) : new ArrayList<String>();
list.add(str[1]);
experssionSet.put(c, list);
}
for (Character c : VnSet)
getFirst(c);
for (Character c : VnSet) {
ArrayList<String> l = experssionSet.get(c);
for (String s : l)
getFirst(s);
}
getFollow(S);
for (Character c : VnSet) {
getFollow(c);
}
}
public void getNvNt() {
System.out.println("注意:@ 为空, E‘->K T'->M");
System.out.print("请输入文法产生式的个数:");
int num =scanner.nextInt();
inputExperssion=new String[num];
System.out.println("请输入文法的"+num+"个产生式,并以回车分割每个产生式:");
for(int i=0;i<num;i++){