import java.util.*;
/**
* @author SXH
* @说明 算符优先分析
* */
public class OperatorPrecedence {
/**
* 源串
* */
static String resourceCode;
/**
* 判断是否可以继续执行
*/
static boolean flag = true;
/**
* 栈
* */
static StringBuilder stack = new StringBuilder("#");
/**
* 输入缓冲区
* */
static StringBuilder buffer = new StringBuilder();
/**
* 步骤
*/
static int step = 1;
/**
* 栈顶第一个终结符
*/
static int top;
/**
* 字符顺序表 **暂时用/表示
*/
static String sequenceList = "+*/i()#";
/**
* 优先关系表,其中1为高于,0为等于,-1为低于,-2为不能比
*/
static int relation[][] = { { 1, -1, -1, -1, -1, 1, 1 },
{ 1, 1, -1, -1, -1, 1, 1 }, { 1, 1, -1, -1, -1, 1, 1 },
{ 1, 1, 1, -2, -2, 1, 1 }, { -1, -1, -1, -1, -1, 0, -2 },
{ 1, 1, 1, -2, -2, 1, 1 }, { -1, -1, -1, -1, -1, -2, 0 } };
/**
* 主程序
*/
public static void main(String[] args) {
System.out.print("请输入字符串:");
Scanner s = new Scanner(System.in);
resourceCode = s.nextLine();
buffer.append(resourceCode);
if (sequenceList.indexOf(buffer.charAt(0)) == -1) {// 要检测缓冲区字符
flag = false;
System.err.println("\t由于包含非法字符,这不是句子!!!");
return;
}
if(buffer.charAt(0)!='i'&&buffer.charAt(0)!='('){//不会出现第一个字符不是i和(的时候
flag = false;
System.err.println("\t你的语法混乱,这不是句子!!!");
return;
}
for (int i = 1; i < buffer.length() - 2; i++) {
if (buffer.charAt(i) != 'i') {
if (buffer.charAt(i) == '(') {//左括号后面只能接i
if (buffer.charAt(i + 1) == ')'
|| buffer.charAt(i + 1) == '+'
|| buffer.charAt(i + 1) == '*'
|| buffer.charAt(i + 1) == '/') {
flag = false;
System.err.println("\t你的语法混乱,这不是句子!!!");
return;
}
}
}
}
System.out.println("***************************************");
System.out.println("步骤\t\t栈\t\t输入缓冲区");
System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);
move();
do {
top = stack.length() - 1;// top指向栈顶第一个非终结符
if (buffer.charAt(0) == '#') {// 判断退出
if (stack.charAt(stack.length() - 2) == '#'
&& stack.charAt(stack.length() - 1) == 'N') {
System.out.println();
System.out.println("\t该输入串是句子,可以放心使用。");
break;
}
}
if (stack.charAt(top) == 'N') {
top--;
}
if (sequenceList.indexOf(buffer.charAt(0)) == -1) {// 每次要检测缓冲区首字符
flag = false;
System.err.println("\t由于包含非法字符,这不是句子!!!");
return;
}
compare(stack.charAt(top), buffer.charAt(0));
} while (flag);
}
/**
* 字符优先级比较、进栈、归约
* */
static void compare(char a, char b) {
int i = sequenceList.indexOf(a);// 行
int j = sequenceList.indexOf(b);// 列
// System.out.println(i+" "+j);
switch (relation[i][j]) {
case 1:// a>b,从栈顶找第二个终结符,准备归约
int second;
for (second = top - 1; stack.charAt(second) == 'N'; second--) {
continue;
}
i = sequenceList.indexOf(stack.charAt(top));
j = sequenceList.indexOf(stack.charAt(second));
if (relation[j][i] == 0) {// 栈顶首终结符和第二终结符优先级相等
// stack.delete(second, top);
// stack.append('N');
stack.replace(second, top + 1, "N");// 从第二终结符到第一首终结符都除去,用N替换
} else if (relation[j][i] == -1) {// 栈顶首终结符优先级高
if (stack.charAt(top - 1) == 'N') {// 如果左边有N,则右边也有,和两边的N一起归约
stack.delete(top, top + 2);// 删除掉从start到end-1的字符
} else {// 只归约它自己,他处于栈顶
stack.deleteCharAt(top);
stack.append('N');
}
}
System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);
break;
case 0:// a=b,b入栈
// break;
case -1:// a<b,b入栈
move();
break;
default:// 不能比较
System.err.println(" " + a + "与" + b + "此时不能比较优先级,这个输入串不是句子!!!");
flag = false;
}
return;
}
/**
* 将缓冲区首字符移到栈顶
*/
static void move() {
stack.append(buffer.charAt(0));
buffer.deleteCharAt(0);
System.out.println(step++ + "\t\t" + stack + "\t\t" + buffer);
}
}
编译中的算符优先分析程序
猜你喜欢
转载自blog.csdn.net/BaiFeng303/article/details/42748445
今日推荐
周排行