自己写一个文法分类器

文法定义

本文法分类器的实现语言是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);

文法分类

在我们读取完毕了,下面我们对文法进

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值