pl/0编译程序的java版
源代码在线查看: table.java
/**
* 这个类封装了PL/0编译器的符号表,C语言版本中关键的全局变量tx和table[]就在这里。
*/
public class Table {
/**
* 即C语言版本中的tablestruct结构。
*/
public class Item {
// 这里定义名字表中的类型,对应C语言版的object枚举类型
public static final int constant = 0;
public static final int variable = 1;
public static final int procedur = 2;
String name; // 名字
int kind; // 类型:const, var or procedur
int val; // 数值,仅const使用
int level; // 所处层,var和procedur使用
int adr; // 地址,var和procedur使用
int size; // 需要分配的数据区空间, 仅procedure使用
}
/**
* 名字表,请使用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, int k, int lev, int dx) {
tx ++;
Item item = get(tx);
item.name = sym.id;
item.kind = k;
switch (k) {
case Item.constant: // 常量名字
if (sym.num > PL0.amax) {
Err.report(31); // 数字过大溢出
item.val = 0;
} else {
item.val = sym.num;
}
break;
case Item.variable: // 变量名字
item.level = lev;
item.adr = dx;
break;
case Item.procedur: // 过程名字
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 String msg = "OOPS! UNKNOWN TABLE ITEM!";
switch (table[i].kind) {
case Item.constant:
msg = " " + i + " const " + table[i].name + " val=" + table[i].val;
break;
case Item.variable:
msg = " " + i + " var " + table[i].name + " lev=" + table[i].level + " addr=" + table[i].adr;
break;
case Item.procedur:
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;
}
}