[ Inhalt ] [ Index ]

Next: Die Übersetzung eines Beispielprogramms Up: Codeerzeugung Previous: Statische und dynamische Semantik

Postfixcodeerzeugung

Postfixcode   auch Umgekehrte Polnische Notation UPN   genannt, wird häufig als Zwischencode erzeugt. Diese Darstellung läßt sich leicht direkt interpretieren oder auch weiter in Maschinencode   transformieren. Wir ordnen jedem syntaktischen Objekt   eine Übersetzungsfunktion   zu, die die Postfixdarstellung ausgibt. Die Übersetzung findet nur statt, wenn die statischen Kontextbedingungen erfüllt sind. Zunächst betrachten wir die arithmetischen Ausdrücke:

void BinNode::Compile() 
{if (l != NULL) l->Compile();
 if (r != NULL) r->Compile();
 PutString(CV(nodetype));
};
void UnNode::Compile() 
{l->Compile();
 PutString(CV(nodetype));
};
void IdNode::Compile() 
{Entry *e;

 e = myEnv->Search(str);
 PutAddr(str, e->GetVal());
}
void IntNode::Compile() 
{PutInt(i);};

Für die Übersetzung der Kontrollanweisungen   erweitern wir den Code um Marken  , sowie um bedingte und unbedingte Sprungbefehle  . Wir betrachten zunächst die Zuweisung  :

void AssNode::Compile() 
{
 l->Compile();
 r->Compile();
 PutString(CV(nodetype));
};

Das WHILE   ist schon ein wenig komplizierter - aber wirklich nur ein wenig!!

void WhileNode::Compile() 
{
 Label lstart, lover;

 NewLabel(); strcpy(lstart, lab);
 NewLabel(); strcpy(lover, lab);

 PutString2(lstart, ":"); 
 if (l != NULL) l->Compile();
 PutString2("BF", lover);
 if (r != NULL) r->Compile();
 PutString2("JMP", lstart); 
 PutString2(lover, ":");
};

Es wird eine Startmarke ausgegeben und die Kontrollbedingung übersetzt. Ist die Bedingung nicht erfüllt, wird zur Übersprungmarke verzweigt, sonst folgt der Schleifenrumpf und der Rücksprung zur Bedingung.

Die IF  -Anweisung in OBERON-0   soll diese kleine Einführung abschließen:

void IfNode::Compile()
{
 Label lelse, lover;

 NewLabel();
 strcpy(lelse, lab);
 expr->Compile();
 PutString2("BF", lelse);
 if (stmt != NULL) stmt->Compile();
 NewLabel();
 strcpy(lover, lab);
 PutString2("JMP", lover);
 PutString2(lelse, ":");
 if (eifp != NULL) 
 {
  ((ElseIfNode*)eifp)->DefineLabel(lover);
  eifp->Compile();
 }
 if (elsp != NULL) elsp->Compile();
 PutString2(lover, ":");
}

void ElseIfNode::Compile()
{
 Label lelse;

 NewLabel();
 strcpy(lelse, lab);
 expr->Compile();
 PutString2("BF", lelse);
 if (stmt != NULL) stmt->Compile();
 PutString2("JMP", lover);
 PutString2(lelse, ":");
 if (eifp != NULL)
 {
  ((ElseIfNode*)eifp)->DefineLabel(lover);
  eifp->Compile();
 } 
}




Next: Die Übersetzung eines Beispielprogramms Up: Codeerzeugung Previous: Statische und dynamische Semantik

Prof. Dr. Reinhard Völler