我有一个大学项目,我必须在c ++中使用Bison和Flex为教师选择的语言构建编译器。
该语言是面向对象的垃圾收集动态类型语言。
事情是我和我的朋友只是在我们只知道运行时类型时如何编写class A{private x;public A(){x=10}}
class B{public x;public B(){x=2}}
class C
{
public static main(args)
{
n=input('integer');
if(n>5)
a=new A();
else
a=new B();
write(a.x);
}
}
的mips代码时感到困惑。让我们看看这个伪代码:
n
我们问老师,她说我们将变量的类型存储在符号表中,但我们只在运行时给出这些类型,这意味着我们必须建立一个解释器以及她说的话。但她似乎忘记了我们在某个寄存器或$ sp(堆栈指针)的mips代码中只有n
的值,我们的值不是a
c ++代码,因此我们无法知道tell the c++ program that the value of n is 1
的类型,除非有a
的mips代码。
我们可以为a
的类型提供可能性,在上面的代码中A
可以是B
或a.x
类型,而mips代码是{ {1}}可以是这样的:
beq type(a) A label1
li $a0,0(a)
li $v0 //code for print integer
syscall
label1:raise exception
但是在这句话a.b.c.d.etc
中事情变得复杂,所以这种方法很糟糕。
我的朋友要求老师强制程序员编写类型,因此对于a.b.c
他必须编写A<a>.B<b>.C<c>
例如,结果是异常(错误的强制转换或私有访问)或{{ 1}}但是老师拒绝了,反正我也不喜欢它。
将值存储在符号表中:这将使生成mips无用,程序是纯c ++(它不再是编译器,也不是解释器)。
2 - 为符号表中的符号定义一个值属性,但让mips代码更改该值,如果我们在c ++ a.b.c
中说,然后在生成代码时我们说(在c ++中){{1}然后mips代码将真正改变x,因为它将v0的值存储在与x地址相同的地址中。
但是这种方法要求汇编器和编译器并行工作并行并行才对我们来说很复杂。
那么处理这个问题的最佳方法是什么?
答案 0 :(得分:2)
如果您正在将动态语言翻译成C ++,那么您可以将您的语言对象放在:
class DynamicLanguageObject
{
int m_type;
void* m_pValue; // stores int, double, char*, etc. depending on m_type
map<string, DynamicLanguageObject*> m_fields;
};
然后动态语言中的表达式a.x
对应于C ++中的a.m_fields["x"]
。这种dictionary - 字段方法是有多少动态语言,包括JavaScript和Python,实现了对象。
你“只需要”弄清楚如何用MIPS汇编语言实现哈希表。