文法定义
本文法分类器的实现语言是Java,可以对4种文法进行分类
首先我们先定义文法文件的存储格式:
我们的文法文件都是在一个txt文件中存储,txt的默认格式如下:
S,A,B,C
a,b,c
S->ABC,A->a,B->b,C->c
S
在我们定义的G = (VT , VN , P , S)中
- 第一行对应VT,也就是我们的非终结符
- 第二行对应VN,也就是我们的终结符
- 第三行对应S,是我们的产生式,一个产生式的格式如下: S->ABC ,
->是一个产生式的推导符号,左边的S代表产生式的左部,右边的ABC代表产生式的右部 - 最后一行是文法的开始符号
文法读取
下面我们将利用Java 的文件流来对一个文法文件进行读取
首先把txt文件加载到我们的java类中
File file = new File("grammar_type2.txt");
然后利用FileInputStream读取我们的文件File
FileInputStream fileInputStream = new FileInputStream(file);
但是使用fileInputStream对象能进行的方法只有按照定义的偏移量读取byte流,无法整行读取,所以我们需要利用一个缓冲读的类进行辅助
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
现在我们可以通过bufferedReader读取到一整行的内容
首先读取我们的变量(非终结符),读取到一整行的数据之后,我们要将它们按照“,”的分隔符进行分割,所以我们就可以利用Java的String类的split()方法
split(String args)方法接收一个String参数,可以将一个大的字符串按照参数分割符切割成几个小的字符串,比如”A,B,C,D”利用split(“,”)之后会返回一个String数组[“A”,”B”,”C”,”D”]
String VN = bufferedReader.readLine();
String []VNs = VN.split(",");
为了让我们后面对产生式的处理更加方便(验证是否存在这个非终结符(终结符)),我们还需要定义一个HashSet来存放我们的变量
HashSet<String> SetVNs = new HashSet<String>(Arrays.asList(VNs));
读取终结符、产生式利用同样的方法
//读取终结符
String VT = bufferedReader.readLine();
String []VTs = VT.split(",");
HashSet<String> SetVTs = new HashSet<String>(Arrays.asList(VTs));
//读取生成式
String P = bufferedReader.readLine();
String []Ps = P.split(",");
最后再读取开始符
//读取开始符
String S = bufferedReader.readLine();
为了进一步对文法进行分类,我们还需要对产生式进行处理
我们定义的一个产生式是这样的“A->BCD”,我们可以以“->”为分割符,将产生式划分为左部和右部,把左部作为key,右部作为value存入HashMap中
//HashMap存储产生式对应关系
HashMap<String,String> map = new HashMap<>();
for(int i = 0;i<Ps.length;i++){
String[] split = Ps[i].split("->");
//产生式左部
String left = split[0];
//产生式右部
String right = split[1];
map.put(left,right);
}
读取完毕后,对这个文法进行输出
System.out.print("非终结符有:");
for (String VNout:
SetVNs) {
System.out.print(VNout+" ");
}
System.out.println();
System.out.print("终结符有:");
for (String VTout:
SetVTs) {
System.out.print(VTout+" ");
}
System.out.println();
System.out.print("产生式有:");
for (String Pout:
Ps) {
System.out.print(Pout+" ");
}
System.out.println();
System.out.println("开始符为:"+S);
文法分类
在我们读取完毕了,下面我们对文法进