• PL/0编译器(java version)


       1:  package compiler;
       2:   
       3:  import java.io.BufferedReader;
       4:  import java.io.BufferedWriter;
       5:  import java.io.IOException;
       6:  import java.util.Arrays;
       7:  import java.util.logging.Level;
       8:  import java.util.logging.Logger;
       9:   
      10:  /**
      11:   * 类P-code代码解释器(含代码生成函数)
      12:   *
      13:   * @author jiangnan
      14:   *
      15:   */
      16:  public class Interpreter {
      17:   
      18:      //运行栈上限
      19:      private static final int stackSize = 1000;
      20:      //pcode数组上线
      21:      private static final int arraySize = 500;
      22:      //虚拟机代码指针,取值范围[0,arraySize-1]
      23:      public int arrayPtr = 0;
      24:      //存放虚拟机代码的数组
      25:      public Pcode[] pcodeArray;
      26:      //显示虚拟代码与否
      27:      public static boolean listswitch = true;
      28:   
      29:      public Interpreter() {
      30:          pcodeArray = new Pcode[arraySize];
      31:      }
      32:   
      33:      /**
      34:       * 生成虚拟机代码
      35:       *
      36:       * @param x Pcodeuction.f
      37:       * @param y Pcodeuction.l
      38:       * @param z Pcodeuction.a
      39:       */
      40:      public void gen(int f, int l, int a) {
      41:          if (arrayPtr >= arraySize) {                                                                          //超出堆栈的上限
      42:              throw new Error("***ERROR:Program too long***");
      43:          }
      44:          pcodeArray[arrayPtr++] = new Pcode(f, l, a);
      45:   
      46:      }
      47:   
      48:      /**
      49:       * 输出目标代码清单
      50:       *
      51:       * @param start 开始输出的位置
      52:       */
      53:      public void listcode(int start) {
      54:          if (listswitch) {                                                                         //是否显示P-code代码
      55:              for (int i = start; i < arrayPtr; i++) {
      56:                  try {
      57:                      String msg = i + "  " + Pcode.pcode[pcodeArray[i].f] + "  " + pcodeArray[i].l + " " + pcodeArray[i].a;                //形如: lit l,a
      58:                      System.out.println(msg);
      59:                      PL0.pcodeWriter.write(i + "  " + msg + '
    ');
      60:                  } catch (Exception e) {
      61:                      e.printStackTrace();
      62:                      System.out.println("***list pcode meet with error***");
      63:                  }
      64:   
      65:              }
      66:          }
      67:      }
      68:   
      69:      /**
      70:       * 这个过程模拟了一台可以运行类PCODE指令的栈式计算机。 它拥有一个栈式数据段用于存放运行期数据, 拥有一个代码段用于存放类PCODE程序代码。
      71:       * 同时还拥用数据段分配指针、指令指针、指令寄存器、局部段基址指针等寄存器。
      72:       *
      73:       * @param stdin 从键盘输入无符号整数
      74:       * @param stdout 显示pcode运行过程
      75:       */
      76:      public void interpret(BufferedReader stdin, BufferedWriter stdout) {
      77:          int[] runtimeStack = new int[stackSize];                  // 程序运行栈
      78:          Arrays.fill(runtimeStack, 0);                                   //初始化
      79:          System.out.println("***Start Interpret P_CODE***");
      80:   
      81:          int pc = 0, // pc:指令指针,
      82:                  bp = 0, //bp:指令基址,
      83:                  sp = 0;                                                                //sp:栈顶指针
      84:   
      85:          do {
      86:   
      87:              Pcode index = pcodeArray[pc++];// index :存放当前指令, 读当前指令
      88:              System.out.println(pc + "  " + Pcode.pcode[index.f] + " " + index.l + " " + index.a);
      89:              switch (index.f) {
      90:                  case Pcode.LIT:                                                   // 将a的值取到栈顶
      91:                      runtimeStack[sp++] = index.a;
      92:                      break;
      93:                  case Pcode.OPR:                                                   // 数学、逻辑运算
      94:                      switch (index.a) {
      95:                          case 0:                                                          //OPR 0 0;RETURN 返回
      96:                              sp = bp;
      97:                              pc = runtimeStack[sp + 2];
      98:                              bp = runtimeStack[sp + 1];
      99:                              break;
     100:                          case 1:                                                           //OPR 0 1 ;NEG取反
     101:                              runtimeStack[sp - 1] = -runtimeStack[sp - 1];
     102:                              break;
     103:                          case 2:                                                           //OPR 0 2;ADD加法
     104:                              sp--;
     105:                              runtimeStack[sp - 1] += runtimeStack[sp];
     106:                              break;
     107:                          case 3:                                                             //OPR 0 3;SUB减法
     108:                              sp--;
     109:                              runtimeStack[sp - 1] -= runtimeStack[sp];
     110:                              break;
     111:                          case 4:                                                             //OPR 0 4;MUL乘法
     112:                              sp--;
     113:                              runtimeStack[sp - 1] =runtimeStack[sp - 1] * runtimeStack[sp];
     114:                              break;
     115:                          case 5:                                                             //OPR 0 5;DIV除法
     116:                              sp--;
     117:                              runtimeStack[sp - 1] /= runtimeStack[sp];
     118:                              break;
     119:                          case 6:                                                              //OPR 0 6;ODD对2取模mod 2
     120:                              runtimeStack[sp - 1] %= 2;
     121:                              break;
     122:                          case 7:                                                              //OPR 0 7;MOD取模
     123:                              sp--;
     124:                              runtimeStack[sp - 1] %= runtimeStack[sp];
     125:                              break;
     126:                          case 8:                                                             //OPR 0 8;==判断相等
     127:                              sp--;
     128:                              runtimeStack[sp - 1] = (runtimeStack[sp] == runtimeStack[sp - 1] ? 1 : 0);
     129:                              break;
     130:                          case 9:                                                                //OPR 0 9;!=判断不相等
     131:                              sp--;
     132:                              runtimeStack[sp - 1] = (runtimeStack[sp] != runtimeStack[sp - 1] ? 1 : 0);
     133:                              break;
     134:                          case 10:                                                               //OPR 0 10;<判断小于
     135:                              sp--;
     136:                              runtimeStack[sp - 1] = (runtimeStack[sp] < runtimeStack[sp - 1] ? 1 : 0);
     137:                              break;
     138:                          case 11:                                                                //OPR 0 11;>=判断大于等于
     139:                              sp--;
     140:                              runtimeStack[sp - 1] = (runtimeStack[sp] >= runtimeStack[sp - 1] ? 1 : 0);
     141:                              break;
     142:                          case 12:                                                                //OPG 0 12;>判断大于
     143:                              sp--;
     144:                              runtimeStack[sp - 1] = (runtimeStack[sp] > runtimeStack[sp - 1] ? 1 : 0);
     145:                              break;
     146:                          case 13:                                                                 //OPG 0 13;<=判断小于等于
     147:                              sp--;
     148:                              runtimeStack[sp - 1] = (runtimeStack[sp] <= runtimeStack[sp - 1] ? 1 : 0);
     149:                              break;
     150:                          case 14:                                                                 //OPG 0 14;输出栈顶值
     151:                              System.out.println("runtimeStack[sp - 1]" + runtimeStack[sp - 1] + ' ');
     152:                              try {
     153:                                  stdout.write(" " + runtimeStack[sp - 1] + ' ');
     154:                                  stdout.flush();
     155:                              } catch (Exception ex) {
     156:                                  System.out.println("***case 14 meet with error***");
     157:                              }
     158:                              sp--;
     159:                              break;
     160:                          case 15:                                                                 //OPG 0 15;输出换行
     161:                              System.out.print("
    ");
     162:                              try {
     163:                                  stdout.write("
    ");
     164:                              } catch (Exception ex) {
     165:                                  System.out.println("***case 15 meet with error***");
     166:                              }
     167:                              break;
     168:                          case 16:                                                                 //OPG 0 16;读入一行输入,置入栈顶
     169:                              System.out.print("Please Input a Integer : ");
     170:                              runtimeStack[sp] = 0;
     171:                              try {
     172:                                  runtimeStack[sp] = Integer.parseInt(stdin.readLine().trim());       //读入一个整型数字
     173:                                  System.out.println(runtimeStack[sp]);
     174:                                  sp++;
     175:                              } catch (Exception e) {
     176:                                  e.printStackTrace();
     177:                                  System.out.println("***read data meet with error***");
     178:                              }
     179:                              try {
     180:                                  stdout.write(" " + runtimeStack[sp] + '
    ');
     181:                                  stdout.flush();
     182:                              } catch (Exception ex) {
     183:                                  System.out.println("***case 16 meet with error***");
     184:                              }
     185:                              break;
     186:                      }
     187:                      break;
     188:                  case Pcode.LOD:                                          //取相对当前过程的数据基地址为a的内存的值到栈顶
     189:                      runtimeStack[sp] = runtimeStack[base(index.l, runtimeStack, bp) + index.a];
     190:                      sp++;
     191:                      break;
     192:                  case Pcode.STO:                                         //栈顶的值存到相对当前的过程的数据基地址为a的内存
     193:                      sp--;
     194:                      runtimeStack[base(index.l, runtimeStack, bp) + index.a] = runtimeStack[sp];
     195:                      break;
     196:                  case Pcode.CAL:                                                                 //调用子程序
     197:                      runtimeStack[sp] = base(index.l, runtimeStack, bp);            //将静态作用域基地址入栈
     198:                      runtimeStack[sp + 1] = bp;                                                //将动态作用域基地址
     199:                      runtimeStack[sp + 2] = pc;                                               //将当前指针入栈
     200:                      bp = sp;                                                                        //改变基地址指针值为新过程的基地址
     201:                      pc = index.a;                                                                 //跳转至地址a
     202:                      break;
     203:                  case Pcode.INT:                                                               //开辟空间大小为a
     204:                      sp += index.a;
     205:                      break;
     206:                  case Pcode.JMP:                                                               //直接跳转至a
     207:                      pc = index.a;
     208:                      break;
     209:                  case Pcode.JPC:
     210:                      sp--;
     211:                      if (runtimeStack[sp] == 0) //条件跳转至a(当栈顶指针为0时)
     212:                      {
     213:                          pc = index.a;
     214:                      }
     215:                      break;
     216:              }
     217:          } while (pc != 0);
     218:      }
     219:   
     220:      /**
     221:       * 通过给定的层次差来获得该层的堆栈帧基址
     222:       *
     223:       * @param l 目标层次与当前层次的层次差
     224:       * @param runtimeStack 运行栈
     225:       * @param b 当前层堆栈帧基地址
     226:       * @return 目标层次的堆栈帧基地址
     227:       */
     228:      private int base(int l, int[] runtimeStack, int b) {
     229:          while (l > 0) {                                                       //向上找l层
     230:              b = runtimeStack[b];
     231:              l--;
     232:          }
     233:          return b;
     234:      }
     235:   
     236:      public void debugPcodeArray() throws IOException {
     237:          System.out.println("***Auto-Generated Pcode Array***");
     238:          String msg = null;
     239:          for (int i = 0; pcodeArray[i] != null; i++) {
     240:              msg = "" + i + "  " + Pcode.pcode[pcodeArray[i].f] + "  " + pcodeArray[i].l + "  " + pcodeArray[i].a;
     241:              System.out.println(msg);
     242:              PL0.pcodeWriter.write(msg + '
    ');
     243:          }
     244:      }
     245:  }
  • 相关阅读:
    在Visual Studio 2013中修改远程Git服务器的地址
    自定义TFS工作项“所有链接”列表中的列
    在权限受限制的AD域环境中部署SQL Server AlwaysOn高可用性
    spring boot常用注解
    在线编辑器(WangEditor)
    报表生成(POI,jquery.table2excel.js,Echarts)
    java 相关书籍介绍
    poj2456 Aggressive cows
    poj1064 Cable master
    洛谷P1396 营救
  • 原文地址:https://www.cnblogs.com/ZJUT-jiangnan/p/3560950.html
Copyright © 2020-2023  润新知