编译中的算符优先分析程序

来源:互联网 发布:js数据添加二维数组 编辑:程序博客网 时间:2024/06/02 06:16
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) == '(') {//左括号后面只能接iif (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);}}

0 0
原创粉丝点击