Aufg. 1.4 a) Wir benötigen Knoten, die eine Verzweigung einführen; lineare Produktionen können i.d.R. wegfallen Es verbleiben: Liste (","), Id und Literal HINWEIS: Es gibt viele Möglichkeiten b) z.B. als Klassenhierarchie: type Knoten is abstract tagged record Konst : Boolean; -- Annahme: immer false bei id, true bei literal Wert : Natural; -- Annahme: bei id "undefiniert" end record; type Knoten_Ptr is access Knoten'Class; type Liste is new Knoten with record Left, Right : Knoten_Ptr; end record; type Id is new Knoten with record Token : String; end record; type Literal is new Knoten with null record; c) (ohne Dispatching) procedure Process (K : in out Knoten_Ptr) is begin if K = null then return; end if; if K.all in Liste'Class then Process_Liste (Liste (K)); elsif K.all in Literal'Class then Process_Literal (Literal (K)); else Process_Id (Id (K)); end if; end Process; procedure Process_Liste (L : in out Liste) is begin -- Postorder-Traversierung, da nur zusammengesetzte Attribute Process (L.Left); Process (L.Right); L.Konst := L.Left.Konst and L.Right.Konst; if L.Konst then L.Wert := L.Right.Wert * 10 + L.Left.Wert; else L.Wert := 0; -- "undefiniert" end if; end Process_Liste; procedure Process_Id (I : in out id) is begin I.Konst := False; I.Wert := 0; -- "undefiniert" end Process_id; procedure Process_Literal (L : in out Literal) is begin L.Konst := True; L.Wert := Get_Value (L); -- Scanner liefert Zahlenwert end Process_Literal; Bsp: (3, 4, 5) AST: Liste ---------- | | Literal (3) Liste --------------- | | Literal (4) Literal (5) (1) Process_Liste ruft Process auf für Left/Right (2) Process_Literal für "3" (3) Process_Liste ruft Process auf für Left/Right (4) Process_Literal für "4" (5) Process_Literal für "5" (6) Attributberechnung für Liste: Wert := 5*10 + 4 = 54 (7) Attributberechnung für Liste: Wert := 54*10 + 3 = 543