题目
借助于词法分析程序提供的分析结果,编写一个算符优先语法分析程序,程序能进行语法结构分析和错误检查,并产生相应的归约信息。
思路
- 找到等式的右边
- 转换为输入字符串
- 对输入字符串进行分析,即
归约
、移进
、接受
这三个操作。
代码
/**
* Created by luopu on 2017/6/8.
*/
package 编译原理实验二;
import java.util.*;
@SuppressWarnings("unused")
public class A {
static int no=0;
static int[][] jilu=new int[10][10];
static int index=0;
static String[] oper={
">", ">", "<", "<", "<", ">", "<", ">",
">", ">", "<", "<", "<", ">", "<", ">",
">", ">", ">", ">", "<", ">", "<", ">",
">", ">", ">", ">", "<", ">", "<", ">",
"<", "<", "<", "<", "<", "=", "<", "e",
">", ">", ">", ">", "e", ">", "e", ">",
">", ">", ">", ">", "e", ">", "e", ">",
"<", "<", "<", "<", "<", "e", "<", "="};
static Stack<String> stk = new Stack<String>();
static int ans=1;
public static String contentsOf(Stack<String> stk) {
String str=stk.toString();
str=str.replace("[", "");
str=str.replace("]", "");
str=str.replace(",", "");
str=str.replace(" ", "");
return str;
}
public static void printStates(String str, String op) {
String current=str.substring(0, 1);
String rest=str.substring(1, str.length());
String action="移进";
if(op==">") {
jilu[no][index++]=ans;
action="归约";
}
if(op=="="&&rest.length()==0) {
action="接受";
}
System.out.printf("%5d%10s%7s%10s%15s%5s\n", ans++,contentsOf(stk),op,current,rest,action);
if(action.equals("接受")) {
System.out.print("归约产生式步骤号为:");
for(int i=0; jilu[no][i]!=0; i++) {
System.out.print(jilu[no][i]+" ");
}
index=0;
System.out.println("\n");
}
}
public static int numOf(String str) {
switch(str) {
case "+": return 0;
case "-": return 1;
case "*": return 2;
case "/": return 3;
case "(": return 4;
case ")": return 5;
case "i": return 6;
case "#": return 7;
}
return 8;
}
public static void second(String str) {
stk.clear();
ans=1;
stk.push("#");
int k=0, r=0, i=0;
String op="";
for(;;) {
// 得到k, r的值
for(i=0; i<10; i++) {
k=numOf(stk.get(stk.size()-1-i));
if(k!=8) {
r=numOf(str.substring(0, 1));
break;
}
}
// 得到优先关系符
op=oper[k*8+r];
// 归约? 移进?接受?
if(op.equals(">")) {
// 归约
printStates(str, op);
for(;i>0;i--) {
stk.pop();
}
for(;;) {
stk.pop();
k=numOf(stk.lastElement());
if(k!=8&&!oper[k*8+r].equals("e")) {
break;
}
}
stk.push("N");
} else {
// 移进
printStates(str, op);
stk.push(str.substring(0, 1));
str=str.substring(1, str.length());
if(op.equals("=")&&str.length()==0) {
// 接受
break;
}
}
}
}
public static void first(String str) {
System.out.println("算术表达式"+(++no)+"为:"+str);
try {
int a=Integer.parseInt(str);
str="i#";
} catch (Exception e) {
String newStr="";
for (int i = 0; i < str.length(); i++) {
if(0<=(str.charAt(i)-'0')&&(str.charAt(i)-'0')<=9) {
newStr+="i";
} else {
newStr+=str.charAt(i);
}
}
str=newStr+"#";
}
System.out.println("转换为输入串:"+str);
System.out.println("步骤号 符号栈 优先关系 当前分析符 剩余字符串 动作");
second(str);
}
public static void main(String[] args) {
String str="b=100 101:a=2*(1+3) IF (b>10) THEN a=1 ELSE IF(b>=5) THEN a=2 ELSE GOTO 101";
String fenxiStr="";
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)=='='&&str.charAt(i-1)!='>') {
i++;
for(;i<str.length(); i++) {
if(str.charAt(i)!=' ') {
fenxiStr+=str.charAt(i);
} else {
first(fenxiStr);
fenxiStr="";
break;
}
}
}
}
}
}