文法的分离以及判断属于几型文法

编写一段程序,接受文法的输入,并从文法的产生式中分离出终结符与非终结符,并判断该文法的文法类型(用冒号:代替文法产生式中的箭头→),使用Java语言实现

package Byyl;

import java.util.Scanner;
public class Text1 {

	/**@author 变成真的很有趣
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("请输入要输入的文法的个数:");
		Scanner wf=new Scanner(System.in);
		int t=wf.nextInt();
		char[][]wenfa=new char[t][];//存入输入的文法产生式
		char []zjfu=new char[1024];//存入文法产生式的终结符
		char []fzjf=new char[1024];//存入文法产生式的非终结符
		
		System.out.println("请输入文法产生式:");
		for(int i=0;i<t;i++){
			System.out.println("请输入第"+(i+1)+"个文法式");
			Scanner sc = new Scanner(System.in); 
			wenfa[i]=sc.next().toCharArray(); 
		}
		//遍历文法这个数组;
//		for(int i=0;i<t;i++){			
//			for(int j=0;j<wenfa[i].length;j++) {			
//			System.out.print(wenfa[i][j]);		
//			}
//		}
		
		//遍历文法产生式,分理出其中的非终结符
		int tag=0;
		for(int i=0;i<t;i++){			
			for(int j=0;j<wenfa[i].length;j++) {			
				if(wenfa[i][j]>='A'&&wenfa[i][j]<='Z') {
					fzjf[tag]=wenfa[i][j];
					tag++;
					
					}
		}
	}
		Object[] s  = ifRepeat(fzjf);//对分离的非终结符数组进行除去重复字符操作
		System.out.print("非终结符是");
		for (Object o : s) {
			System.out.print(o);//输入所有非终结符
		}
		
		System.out.println();
		System.out.println("============");
		//遍历文法产生式,分理出其中的终结符
		int flg=0;
		for(int i=0;i<t;i++){			
			for(int j=0;j<wenfa[i].length;j++) {			
				if(wenfa[i][j]>='a'&&wenfa[i][j]<='z') {
					zjfu[flg]=wenfa[i][j];
					flg++;
					
					}
		}
	}
		Object[] c  = ifRepeat(zjfu);//对分离的终结符数组进行除去重复字符操作
		System.out.print("终结符是");
		for (Object o : c) {
			System.out.print(o);//输入所有终结符
		}
		
		char[][] left=new char[t][];//定义存入所有文法产生式的:左侧字符
		char[][] right=new char[t][];//定义存入所有文法产生式的:右侧字符
		char[] a1;
		char[] a2;
		int flag = 4;
		for (int i = 0; i < t; i++) {
			String sr=String.valueOf(wenfa[i]);
        	String[]d=sr.split(":");
        	a1=d[0].toCharArray(); 
        	a2=d[1].toCharArray(); 
        	left[i]=a1;
        	right[i]=a2;
//        	System.out.println(left[i]);
        	if(zero(left[i])) {//0型文法判断
        		if(one(left[i],right[i])) {//1型文法判断
        			if (two(left[i], right[i])) {//2型文法判断
						if (three(left[i], right[i])) {//3型文法判断
							if(flag < 3)
    							;
    						else
    							flag = 3;
    					}
    					else{
    						if(flag < 2)
    							;
    						else
    							flag = 2;
    					}
    				}
    				else{
    					if(flag < 1)
    						;
    					else
    						flag = 1;
    				}
    			}
    			else{
    				flag = 0;
    			}
    		}
    	}
		//遍历:左边的字符
//		for(int i=0;i<t;i++){						
//		System.out.print(left[i]);
//		}
		//遍历:右边的字符
//		for(int i=0;i<t;i++){
//		System.out.print(right[i]);
//		}
		
	JugeResult(flag);
}//主函数结束

	
	private static void JugeResult(int flag) {//输出文法类型
		// TODO Auto-generated method stub
    	switch(flag)
    	{
    	case 0:
    		System.out.println("0型文法!");
    		break;
    	case 1:
    		System.out.println("1型文法!");
    		break;
    	case 2:
    		System.out.println("2型文法!");
    		break;
    	case 3:
    		System.out.println("3型文法!");
    		break;
    	}
    
	}

	public static  Object[] ifRepeat(char[] zjfu){  //除去数组中的重复的元素
    //用来记录去除重复之后的数组长度和给临时数组作为下标索引  
    int t = 0;  
    //临时数组  
    Object[] tempArr = new Object[zjfu.length];  
    //遍历原数组  
    for(int i = 0; i < zjfu.length; i++){  
        //声明一个标记,并每次重置  
        boolean isTrue = true;  
        //内层循环将原数组的元素逐个对比  
        for(int j=i+1;j<zjfu.length;j++){  
            //如果发现有重复元素,改变标记状态并结束当次内层循环  
            if(zjfu[i]==zjfu[j]){  
                isTrue = false;  
                break;  
            }  
        }  
        //判断标记是否被改变,如果没被改变就是没有重复元素  
        if(isTrue){  
            //没有元素就将原数组的元素赋给临时数组  
            tempArr[t] = zjfu[i];  
            //走到这里证明当前元素没有重复,那么记录自增  
            t++;  
        }  
    }  
    //声明需要返回的数组,这个才是去重后的数组  
    Object[]  newArr = new Object[t];  
    //用arraycopy方法将刚才去重的数组拷贝到新数组并返回  
    System.arraycopy(tempArr,0,newArr,0,t);  
    return newArr;  
    
	}
	
	public static boolean zero(char left[])  {//判断是否为0型文法
		int i=0;
		while(left[i] != '\n'){
			if(left[i] < 65 || (left[i] > 90 && left[i] < 97) || left[i] > 122){
				System.out.println("含有非法符号,不合法产生式");
				return false;
			}
			else 
			if((left[i] >= 97 && left[i] <= 122)){
				if(i == (left.length-1)){
					System.out.println("左侧全为终结符,不合法产生式");
					return false;
				}
			}
			else if(left[i] >= 65 && left[i] <= 90){
				//合法产生式
				break;
			}
			i++;
			}
		
		return true;
	}
	
	public static boolean one(char left[],char right[]) {//判断是否为1型文法
    	if(right.length >= left.length)
    	{
    		return true;
    	}
    	return false;
	}
	
    public static boolean two(char left[],char right[])  {//判断是否为2型文法
    	if((1 == left.length) && (left[0] >= 65 && left[0] <= 90))
    	{
    		return true;
    	}
    	return false;
    	
    }
    
    public static boolean three(char left[],char right[])  {//判断是否为3型文法
    	if((1 == right.length) && (right[0] >= 97 && right[0] <= 122))
    	{
    		return true;
    	}
    	if(2 == right.length){
    		if((right[0] >= 65 && right[0] <= 90) && (right[1] >= 97 && right[1] <= 122))
    		{
    			return true;
    		}
    		if((right[0] >= 97 && right[0] <= 122) && (right[1] >= 65 && right[1] <= 90))
    		{
    			return true;
    		}
    	}
    	return false;
    }
}

以下给出我在运行时的截图:
在这里插入图片描述
在这里插入图片描述
有错的地方欢迎各位大牛指正。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值