编写一段程序,接受文法的输入,并从文法的产生式中分离出终结符与非终结符,并判断该文法的文法类型(用冒号:代替文法产生式中的箭头→),使用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;
}
}
以下给出我在运行时的截图:
有错的地方欢迎各位大牛指正。