?? table.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 + -