编译原理之Java实现判断输入的是几型文法
实验一:文法的判断与处理
实验要求:
1)编写一段程序,接受文法的输入;
2)从文法的产生式中分离出非终结符和终结符,并输出;
3)判断该文法的文法类型,是否为0型,1型,2型或3型文法,并输出判断结果。
4)用C#或JAVA语言实现;
5)终结符和非终结符的判断依据为是否为小写字母;
文法定义符号→用“:”代替。
aS:aB
bS:bA
A:bAA
A:a
A:aS
B:b
B:bS
B:aBB
注意:此代码只适合大小写字母的文法
源码:
package grammar;
import java.util.*;
/**
* @Author: 16201533
* @Date: 2019/3/26 9:58
* @Version 1.0
*/
public class Grammar {
private Set<String> set = new HashSet<>();//产生式集合
private Set<Character> vn = new HashSet<>();//非终结符集
private Set<Character> vt = new HashSet<>();//终结符集
private int type = 3;
private final String rex = "^(?=.*[A-Z])[a-zA-Z]*$",//用于匹配产生式左边(必须包含一个大写字母)
rex1 = "^[a-zA-Z]*$";//用于匹配产生式右边(可以匹配空字符串)
public Grammar() {
拒绝伸手党,拿走评个论或者点个赞
}
public boolean addProduction(String s) {//添加产生式
int index = s.indexOf(':');
if (index > 0) {
s = s + " ";//解决输入"S:"无法分成两个字符串数组的问题
String[] split = s.split(":");
if (split.length == 2) {
split[1] = split[1].trim();
if (split[0].matches(rex) && split[1].matches(rex1)) {
set.add(s);
parseProduction(split[0], split[1]);
analysisType(split[0], split[1]);
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
}
private void analysisType(String s1, String s2) {//分析是几型文法
if (type > 0) {//如果当前是0型,则不会进入if
if (type > 1 && s1.length() == 1 && s1.charAt(0) < 97 && s2.length() > 0) {//左边是只有一个大写字母,右边长度大于0
String r = "^[a-z][A-Z]?$";//匹配3型文法右边,第一个是小写字母,可以有第二个,必须是大写字母
if (!s2.matches(r)) {//不能匹配3型文法右边,则是2型文法
type = 2;
}
} else if (s2.length() == 0 || s2.length() >= s1.length()) {
type = 1;
} else {
type = 0;
}
}
}
private void parseProduction(String s1, String s2) {//分解产生式
String s = s1 + s2;
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) < 97) {//大写字母,非终结符
vn.add(s.charAt(i));
} else {
vt.add(s.charAt(i));
}
}
}
public void print() {//打印非终结符,终结符和产生式
System.out.print("非终结符:");
for (char c : vn) {
System.out.print(c + " ");
}
System.out.print("\n终结符:");
for (char c : vt) {
System.out.print(c + " ");
}
System.out.println("\n产生式:");
for (String s : set) {
System.out.println(s);
}
if (set.isEmpty()) {//产生式为空
System.out.println("请先输入产生式");
} else {
System.out.println("该文法是 " + type + " 型文法");
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入产生式(以end结束)");
String s = scanner.nextLine();
Grammar grammar = new Grammar();
while (!"end".equals(s)) {
if (!grammar.addProduction(s)) {
System.out.println("输入产生式错误,添加失败");
}
System.out.println("输入产生式(以end结束)");
s = scanner.nextLine();
}
grammar.print();
}
}