⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 table.java

📁 完成编译器的基本功能,并且有界面,简单好用
💻 JAVA
字号:
package compiler.pl0;

/**
 * 符号类型,为避免和Java的关键字Object冲突,我们改成Objekt
 */
enum Objekt {
      constant, variable, procedure
}

/**
 *  这个类封装了PL/0编译器的符号表,C语言版本中关键的全局变量tx和table[]就在这里。
 */
public class Table {
      /**
       *  即C语言版本中的tablestruct结构。
       */
      Err err = new Err();
      public String ss = "";

      public class Item {
            String name; // 名字
            Objekt kind; // 类型:const, var or procedure
            int val; // 数值,仅const使用
            int level; // 所处层,var和procedure使用
            int adr; // 地址,var和procedure使用
            int size; // 需要分配的数据区空间, 仅procedure使用	//array也使用
      }

      /**
       * 名字表,请使用get()函数访问
       * @see #get(int)
       */
      private Item[] table = new Item[PL0.txmax];

      /**
       * 当前名字表项指针,也可以理解为当前有效的名字表大小(table size)
       */
      public int tx = 0;

      /**
       * 获得名字表某一项的内容
       * @param i 名字表中的位置
       * @return 名字表第 i 项的内容
       */
      public Item get(int i) {
            if (table[i] == null) {
                  table[i] = new Item();
                  table[i].name = "";
            }
            return table[i];
      }

      /**
       * 把某个符号登陆到名字表中,注意参数跟C语言版本不同
       * @param sym 要登陆到名字表的符号
       * @param k   该符号的类型:const, var, procedure
       * @param lev 名字所在的层次
       * @param dx  当前应分配的变量的相对地址,注意调用enter()后dx要加一
       */
      public void enter(Symbol sym, Objekt k, int lev, int dx) {
            tx++;
            Item item = get(tx);
            item.name = PL0.lex.id; // 注意id和num都是从词法分析器获得
            item.kind = k;
            switch (k) {
                  case constant: // 常量名字
                        if (PL0.lex.num > PL0.amax) {
                              String ss1 = err.report(31); // 数字过大溢出
                              ss = ss + ss1 + "\n";
                              item.val = 0;
                        }
                        else {
                              item.val = PL0.lex.num;
                        }
                        break;
                  case variable: // 变量名字
                        item.level = lev;
                        item.adr = dx;
                        break;
                  case procedure: // 过程名字
                        item.level = lev;
                        break;

            }
      }

      /**
       * 打印符号表内容,摘自C语言版本的 block() 函数。
       * @param start 当前作用域符号表区间的左端
       */
      public void debugTable(int start) {
            if (!PL0.tableswitch) {
                  return;
            }
            System.out.println("TABLE:");
            if (start > tx) {
                  System.out.println("    NULL");
            }
            for (int i = start + 1; i <= tx; i++) {
                  String msg = "OOPS! UNKNOWN TABLE ITEM!";
                  switch (table[i].kind) {
                        case constant:
                              msg = "    " + i + " const " + table[i].name +
                                  " val=" + table[i].val;
                              break;
                        case variable:
                              msg = "    " + i + " var   " + table[i].name +
                                  " lev=" + table[i].level + " addr=" +
                                  table[i].adr;
                              break;
                        case procedure:
                              msg = "    " + i + " proc  " + table[i].name +
                                  " lev=" + table[i].level + " addr=" +
                                  table[i].adr + " size=" + table[i].size;
                              break;
                  }
                  System.out.println(msg);
                  PL0.fas.println(msg);
            }
            System.out.println();
      }

      /**
       * 在名字表中查找某个名字的位置
       * @param idt 要查找的名字
       * @return 如果找到则返回名字项的下标,否则返回0
       */
      public int position(String idt) {
            for (int i = tx; i > 0; i--) {
                  if (get(i).name.equals(idt)) {
                        return i;
                  }
            }
            return 0;
      }

      public String ret() {
           return ss;
     }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -