实验五:LR(0)语法分析程序的设计
1.理解和掌握LR(0)文法的判断和分析过程
2.本实验要求设计一个LR(0)语法分析程序。
3.本实验要求自己独立完成,不允许抄袭别人的实验结果。
4.用C#或JAVA语言实现;
public class Experiment_5 {
//终结符
private static char[] VN = { 'E', 'A', 'B' };
// 非终结符
private static char[] VT = { 'a', 'b', 'c','d','#'};
// 文法G
private static String[] G = { "S':E","E:aA","E:bB","A:cA","A:d","B:cB","B:d" };
// 判断的文法为
// private static String s = "abab#";
private static String V = "abcd#EAB";
// 创建一个栈
private static Stack<String> stack = new Stack<String>();
// 构造LR(1)分析表
private static String[][] LR1 = {
{"S2","S3","","","","1","",""},
{"","","","","acc","","",""},
{"","","S4","S10","","","6",""},
{"","","S5","S11","","","","7"},
{"","","S4","S10","","","8",""},
{"","","S5","S11","","","","9"},
{"r1","r1","r1","r1","r1","","",""},
{"r2","r2","r2","r2","r2","","",""},
{"r3","r3","r3","r3","r3","","",""},
{"r5","r5","r5","r5","r5","","",""},
{"r4","r4","r4","r4","r4","","",""},
{"r6","r6","r6","r6","r6","","",""},
};
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入要判断的句子:");
String s = input.next();
if (Judge(s) == 1){
System.out.println("输入的字符串包含无法识别的字符!!!");
}
else {
if (Accept(s)){
System.out.println("输入的句子可以被接受!!!");
}
else{
System.out.println("输入句子不能被接受!!!");
}
}
}
// 判断输入的字符串中是否包含无法识别的字符
public static int Judge(String s) {
int a = 1;
for (int i = 0; i < s.length(); i++) {
a = 1;
for (int j = 0; j < VT.length; j++) {
if (s.charAt(i) == VT[j]) {
a = 0;
break;
}
}
if (a == 1) {
return a;
}
}
return a;
}
// 查询符号在分析表的位置
private static int posiV(char c) {
for (int i = 0; i < V.length(); i++) {
if (c == V.charAt(i)){
return i;
}
}
return -1;
}
// 执行ACTION动作
private static String ACTION(char c, int i) {
if (posiV(c) <= (VT.length - 1)){
return LR1[i][V.indexOf(String.valueOf(c))];
}
else{
return null;
}
}
// 执行GOTO动作
private static int GOTO(char c, int i) {
if(LR1[i][posiV(c)] != ""){
return Integer.parseInt(LR1[i][posiV(c)]);
}else {
return 0;
}
}
// 输出分析过程
private static void printf(int a, String s, String s1, String s2, String s3, String s4) {
System.out.printf("%-9d%-10s%-10s%-12s%-10s%-8s\n", a, s,s1,s2, s3, s4);
// System.out.println(a+ "\t" +s+ "\t" +s1+ "\t" +s2+ "\t" +s3+ "\t" +s4);
}
// 判断句子是否可以接受
private static boolean Accept(String s) {
s += '#';
// 定义一个字符串,来存放符号
String stack = new String();
stack += '#';
// 定义一个字符串,存放状态
String state = new String();
state += '0';
// 定义一个int变量来记录推导的步数
int count = 1;
// 定义一个指针
int p = 0;
String ss = "";
System.out.printf("%-7s%-9s%-8s%-8s%-10s%-8s\n", "步骤", "状态栈","符号栈","剩余输入串", "ACTION", "GOTO");
System.out.println("---------------------------------------------------------------");
while (p < s.length()) {
//判断状态 大于 S9这种数据
int num = 0 ;
if(state.charAt(state.length() - 1) ==')'){
num = Integer.parseInt(state.substring(state.length()-3, state.length()-1));
}else {
num = Integer.parseInt(state.charAt(state.length() - 1) + "");
}
ss = ACTION(s.charAt(p), num);
// System.out.println(ss);
// 移入
if (!ss.equals("") && ss.charAt(0) == 'S') {
// 输出步骤
printf(count, state, stack, s.substring(p), ss, "");
// 新符号进栈
stack += s.charAt(p);
// 新状态进栈
String nowState ;
if(ss.length()>=3 ){
nowState = "("+ss.substring(1, 3)+")";
}else {
nowState = String.valueOf(ss.charAt(1));
}
state += nowState;
// 指针向后移一位
p++;
// 记步数加+
count++;
} else {
// 规约
if (!ss.equals("") && ss.charAt(0) == 'r') {
// System.out.println(ss);
String t = G[Integer.parseInt(ss.charAt(1) + "")];
// 计算栈中需要被规约的长度
int l = numberVT(t, stack);
// 从符号栈中出栈
stack = stack.substring(0, stack.length() - l);
// 从状态栈出栈
if(state.charAt(state.length() - 1) ==')'){
state= state.substring(0, state.length() - (l+3) );
}else {
state= state.substring(0, state.length() - l);
}
// 加入规约后的非终结符
stack += t.charAt(0);
int inputNum = 0 ;
if(state.charAt(state.length() - 1) ==')'){
inputNum = Integer.parseInt(state.substring(state.length()-3, state.length()-1));
}else {
inputNum = Integer.parseInt(state.charAt(state.length() - 1) + "");
}
int a = GOTO(t.charAt(0), inputNum);
state += a;
printf(count, state, stack, s.substring(p), ss, a + "");
count++;
} else {
if (ss.equals("acc")) {
// 输出
printf(count, state, stack, s.substring(p), "接受", "");
System.out.println("---------------------------------------------------------------");
return true;
} else{
// 输出
printf(count, state, stack, s.substring(p), "出错", "");
}
System.out.println("---------------------------------------------------------------");
return false;
}
}
}
return false;
}
// 计算需要被规约的长度
private static int numberVT(String s, String s1) {
s = s.substring(2);
int c = 0;
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < s1.length(); j++) {
if ((s.charAt(i) == s1.charAt(j))) {
c++;
break;
}
}
}
return c;
}
}