编译原理之Java实现判断输入的是几型文法

编译原理之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();
    }

}

拒绝伸手党,拿走评个论或者点个赞

运行截图

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 57
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值