实验二-语法分析
源码地址CSDN下载
读入文法,获取产生式
内容较简单,不做详细说明(文法由文件读入)
数据结构
- 文法:String
- 产生式:List<> left - - >right
得到终结符、非终结符
内容较简单,不做详细说明(均用String,集合用List)
终结符:vt;非终结符:vn;
消除左递归、左因子
间接左递归
存在形式: 存在两个产生式,分别为:①vn1- ->vn2…②vn2- ->vn1…;
*解决办法:*用①的right代替②的right中出现的vn1(存在多个以vn1开头的产生式时,多次替换);
for(int k=0;k<right.length;k++) {
if(right[k].equals(vnItem)&&!right[k].equals(vnString.get(i))){
setLeftString.add(vnString.get(i));
setLeftString.add(vnItem);
changeString.add(listStringTest.get(j));
String str=listStringTest.get(j);
int index1=str.indexOf('>')+1;
String rightstr1=str.substring(index1);
String[] newstr=rightstr1.split("\\.");
for(int p=0;p<listString.size();p++) {
int index2=str.indexOf('>')+1;
String rightstr2=listString.get(p).substring(index2);
String str1=vnString.get(i)+"-->";
for(int q=0;q<newstr.length;q++) {
if(newstr[q].equals(vnItem)) {
str1=str1+rightstr2;
}else {
str1=str1+"."+newstr[q];
}
}
if(!newString.contains(str1)) {
newString.add(str1);
}
}
}
}
直接左递归
存在形式: 存在产生式为:vn1- ->vn1…左递归:只有在最左侧才为左递归;
解决办法: a,b指任意长度的任意字符;~指空;
①找到以vn1为开始的所有产生式;
②将①中的产生式分为两种:①vn1- ->vn1 a;②vn1- -> b;
③构造新的产生式(3种)为:①vn1- ->b vn1’;②vn1’- ->a vn1’;③vn1- ->~;
for (int i = 0; i < oldListItems.size(); i++) {
if (oldListItems.get(i).charAt(0) == oldListItems.get(i).charAt(4)) {
if(MarkSet.contains(oldListItems.get(i).charAt(0)+""))
continue;//以该非终结符开头的式子已经进行了消除左递归的操作
for (int j = 0; j < oldListItems.size(); j++) {
if (oldListItems.get(j).startsWith("" + oldListItems.get(i).charAt(0))&& oldListItems.get(j).length() >= 5) {
//
MarkSet.add(oldListItems.get(j).charAt(0)+"");
if(oldListItems.get(j).charAt(0) == oldListItems.get(j).charAt(4)) {
newList.add(oldListItems.get(i).charAt(0) + "’" + "-->"+ oldListItems.get(j).substring(6)+"."+ oldListItems.get(i).charAt(0) + "’");
if(