在 Java 中创建符号 table 时在编译时考虑未知变量值
Taking unknown variable values into account at compile-time when creating a symbol table in Java
我正在为我自己的编程语言创建一个编译器,作为我大学的学期项目在 Minecraft 中创建机器人。到目前为止,我已经成功地使用 ANTLR 创建了一个解析器,创建了我自己的抽象语法树结构并使用 ANTLR 访问器创建了 AST。我正处于上下文分析阶段,我目前正在创建符号 tables 并控制结构。我的 SymbolTable class 看起来像这样:
public class SymbolTable {
private HashMap<String, Symbol> ST = new HashMap<>();
public SymbolTable parent;
public LinkedList<SymbolTable> children = new LinkedList<>();
public String kind;
public String id;
public SymbolTable(String kind, String id){
this.kind = kind;
this.id = id;
}
public void put(String id, Symbol val){
ST.put(id, val);
}
public Symbol get(String id){
if(ST.containsKey(id)) {
return ST.get(id);
}
else{
try {
return parent.get(id);
}
catch(NullPointerException e){
return null;
}
}
}
public boolean contains(String id){
if(ST.containsKey(id)) {
return true;
}
else{
if(parent == null){
return false;
}
return parent.contains(id);
}
}
public String prettyPrint(){
String st = "(TABLE " + this.kind + " " + this.id + " " + ST.toString();
for(SymbolTable nst : children){
st = st.concat(" " + nst.prettyPrint());
}
st = st.concat(")");
return st;
}
public boolean isFunction(){
if(this.kind == "fun"){
return true;
}
else if(!(this.parent == null)){
return this.parent.isFunction();
}
else{
return false;
}
}
}
将变量和函数放入符号[=31=]没问题;为此,我使用访问者方法,如下所示:
@Override
public Symbol visitStrVarCond(StrVarCondNode node){ return new StringSymbol("var", "string", node.val); }
然而,据我了解,符号 table 中符号的值(例如变量的值,或函数的 return 值)也需要出现在符号 table 中。这也没有问题,我已经可以做到了。
不过,我的问题是:
程序员可能使用的一些值在编译时是未知的。它们仅在给定程序的 运行 时间已知。例如:玩家的当前位置,库存槽中的特定项目等。我的语言有事件,因此例如如果程序员希望机器人挖矿直到检测到特定块,他们可以这样写:
event block(12:0)
// do stuff
end event
这个特定事件,块事件,包含诸如块位置之类的变量。但是,这在编译时是未知的。在向符号 tables?
中插入值时,我该如何考虑这些事情?
However, as far as I understand, the value of the symbols in the symbol table (for instance the value of variables, or the return value of a function) also needs to be present in the symbol table.
符号 table 中的符号的 location 需要出现在那里 - 通常以堆栈偏移的形式出现。实际的 值 在编译时通常是未知的。
举个例子,想像 x = y
这样的东西。符号 table 的目的是让编译器知道 x
和 y
的类型用于类型验证(在适用的语言中),并知道"load" 和 "store" 它将发出的指令。但是它可以在不知道 x
中存储的实际值是什么的情况下生成输出代码。
我正在为我自己的编程语言创建一个编译器,作为我大学的学期项目在 Minecraft 中创建机器人。到目前为止,我已经成功地使用 ANTLR 创建了一个解析器,创建了我自己的抽象语法树结构并使用 ANTLR 访问器创建了 AST。我正处于上下文分析阶段,我目前正在创建符号 tables 并控制结构。我的 SymbolTable class 看起来像这样:
public class SymbolTable {
private HashMap<String, Symbol> ST = new HashMap<>();
public SymbolTable parent;
public LinkedList<SymbolTable> children = new LinkedList<>();
public String kind;
public String id;
public SymbolTable(String kind, String id){
this.kind = kind;
this.id = id;
}
public void put(String id, Symbol val){
ST.put(id, val);
}
public Symbol get(String id){
if(ST.containsKey(id)) {
return ST.get(id);
}
else{
try {
return parent.get(id);
}
catch(NullPointerException e){
return null;
}
}
}
public boolean contains(String id){
if(ST.containsKey(id)) {
return true;
}
else{
if(parent == null){
return false;
}
return parent.contains(id);
}
}
public String prettyPrint(){
String st = "(TABLE " + this.kind + " " + this.id + " " + ST.toString();
for(SymbolTable nst : children){
st = st.concat(" " + nst.prettyPrint());
}
st = st.concat(")");
return st;
}
public boolean isFunction(){
if(this.kind == "fun"){
return true;
}
else if(!(this.parent == null)){
return this.parent.isFunction();
}
else{
return false;
}
}
}
将变量和函数放入符号[=31=]没问题;为此,我使用访问者方法,如下所示:
@Override
public Symbol visitStrVarCond(StrVarCondNode node){ return new StringSymbol("var", "string", node.val); }
然而,据我了解,符号 table 中符号的值(例如变量的值,或函数的 return 值)也需要出现在符号 table 中。这也没有问题,我已经可以做到了。
不过,我的问题是:
程序员可能使用的一些值在编译时是未知的。它们仅在给定程序的 运行 时间已知。例如:玩家的当前位置,库存槽中的特定项目等。我的语言有事件,因此例如如果程序员希望机器人挖矿直到检测到特定块,他们可以这样写:
event block(12:0)
// do stuff
end event
这个特定事件,块事件,包含诸如块位置之类的变量。但是,这在编译时是未知的。在向符号 tables?
中插入值时,我该如何考虑这些事情?However, as far as I understand, the value of the symbols in the symbol table (for instance the value of variables, or the return value of a function) also needs to be present in the symbol table.
符号 table 中的符号的 location 需要出现在那里 - 通常以堆栈偏移的形式出现。实际的 值 在编译时通常是未知的。
举个例子,想像 x = y
这样的东西。符号 table 的目的是让编译器知道 x
和 y
的类型用于类型验证(在适用的语言中),并知道"load" 和 "store" 它将发出的指令。但是它可以在不知道 x
中存储的实际值是什么的情况下生成输出代码。