编译原理
来源:互联网 发布:java和asp.net的区别 编辑:程序博客网 时间:2024/04/29 05:35
题目
借助于词法分析程序提供的分析结果,编写一个算符优先语法分析程序,程序能进行语法结构分析和错误检查,并产生相应的归约信息。
思路
- 找到等式的右边
- 转换为输入字符串
- 对输入字符串进行分析,即
归约
、移进
、接受
这三个操作。
代码
/** * 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; } } } } }}
结果
PERFECT!!!
阅读全文
0 0
- 编译原理
- 《编译原理》
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- 编译原理
- @Responsebody与@RequestBody
- 全面解析Linux 内核 3.10.x
- redis,memcache二者的区别是?(优缺点)
- C++学习:迭代器iterator的使用
- ES6之箭头函数
- 编译原理
- 全面解析Linux 内核 3.10.x
- AS上传项目到GitHub报错can't finish Github sharing precess.
- linux 使用shell脚本写数据报表并且在web端浏览
- Android初级学习总结
- Linux的vi命令
- Phantomjs 与 Chrome 的一点区别
- ProjectEuler-Problem 7-10001st prime
- Kotlin官方参考整理——04.函数和lambda表达式