项目的完整代码在 C2j-Compiler
前言
在之前完成了描述符号表的数据结构,现在就可以正式构造符号表了。符号表的创建自然是要根据语法分析过程中走的,所以符号表的创建就在LRStateTableParser里的takeActionForReduce方法
不过在此之前,当然还需要一个方便对这个符号表操作的类了
这一篇主要的两个文件是
- TypeSystem.java
- LRStateTableParser.java
操作符号表
操作符号表的方法都在TypeSystem类里。
TypeSystem里主要有这几个方法:
类型说明符
逻辑都很简单
public TypeLink newType(String typeText) {
Specifier sp;
int type = Specifier.NONE;
boolean isLong = false, isSigned = true;
switch (typeText.charAt(0)) {
case 'c':
if (typeText.charAt(1) == 'h') {
type = Specifier.CHAR;
}
break;
case 'd':
case 'f':
System.err.println("Floating point Numbers are not supported");
System.exit(1);
break;
case 'i':
type = Specifier.INT;
break;
case 'l':
isLong = true;
break;
case 'u':
isSigned = false;
break;
case 'v':
if (typeText.charAt(2) == 'i') {
type = Specifier.VOID;
}
break;
case 's':
//ignore short signed
break;
default:
break;
}
sp = new Specifier();
sp.setType(type);
sp.setLong(isLong);
sp.setSign(isSigned);
TypeLink link = new TypeLink(false, false, sp);
return link;
}
创建存储类型
其实这一部分有的到后面解释执行或者代码生成的时候,现在这个编译器是不处理的
这一部分的逻辑也很简单
public TypeLink newClass(String classText) {
Specifier sp = new Specifier();
sp.setType(Specifier.NONE);
setClassType(sp, classText.charAt(0));
TypeLink link = new TypeLink(false, false, sp);
return link;
}
private void setClassType(Specifier sp, char c) {
switch(c) {
case 0:
sp.setStorageClass(Specifier.FIXED);
sp.setStatic(false);
sp.setExternal(false);
break;
case 't':
sp.setStorageClass(Specifier.TYPEDEF);
break;
case 'r':
sp.setStorageClass(Specifier.REGISTER);
break;
case 's':
sp.setStatic(true);
break;
case 'e':
sp.setExternal(true);
break;
default:
System.err.println("Internal error, Invalid Class type");
System.exit(1);
break;
}
}
给符号添加修饰符
addSpecifierToDeclaration是为当前整