Имам университетски проект, в който трябва да създам компилатор за език, избран от учителите, използвайки Bison и Flex в c++.
Езикът е обектно-ориентиран, събиран боклук, динамично типизиран език.
Работата е там, че аз и моят приятел просто сме объркани как да напишем mips кода за a.x
, когато знаем само типа на a по време на изпълнение. нека да видим този псевдокод:
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);
}
}
Попитахме учителя, тя каза, че съхраняваме типовете на променливите в символната таблица, но ние даваме тези типове само по време на изпълнение, това означава, че трябва да изградим интерпретатор и това каза тя. но тя изглежда забрави, че имаме само стойността на n
в кода на mips в някакъв регистър или в $sp(stack pointer), нямаме стойността на n
в кода на c++, така че не можем да знаем тип a
, освен ако няма mips код за tell the c++ program that the value of n is 1
.
Можем да направим възможности за това какъв може да бъде типът на a
, в горния код a
е от тип A
или B
и mips кодът на a.x
може да бъде нещо подобно:
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>
например и резултатът е или изключение (грешно предаване или частен достъп), или a.b.c
, но учителят отказа и така или иначе не ми харесва .
Методи, които познавам
1-запазете стойността в таблицата със символи: това ще направи генерирането на mips безполезно и програмата е чист C++ (вече не е нито компилатор, нито интерпретатор).
2-дефинирайте атрибут на стойност за символа в таблицата със символи, но нека кодът на mips промени тази стойност, добре, ако казахме в c++ int n
и след това, докато генерираме код, кажем (в c++) printf("sw $v0,0(%d)",&x)
тогава кодът на mips наистина ще промени x, защото съхранява стойността на v0 в адрес, който е същият като x адрес.
Но този подход изисква асемблерът и компилаторът да работят заедно паралелно и паралелът е просто сложен за нас.
И така, кой е най-добрият метод за справяне с това?