home *** CD-ROM | disk | FTP | other *** search
- (* HEAP.PAS
- Erlaeuterung zur lexikalischen Analyse. Implementierung der Symboltabelle
- des Scanners als Heap. Es werden Grundsymbole (hier nur Bezeichner) von
- der Tastatur eingelesen und in der Reihenfolge ihres Auftretens zu
- einem Heap aufgebaut. Das Programm kann mit dem Bezeichner 'end' beendet
- werden. Die Laenge der Bezeichner ist maximal auf 3 begrenzt.
- Config.: ATARI ST & Pascal ST Plus, MS-DOS & Turbo Pascal *)
- PROGRAM Heap;
- CONST NxtCol = 4; maxTiefe = 5; (* maximale Hoehe des Baumes *)
- TYPE
- Namen = PACKED ARRAY[1..3] OF CHAR; (* Bezeichnerarray *)
- Heap = ^HeapPointer; (* Heapdefinition *)
- HeapPointer = RECORD n: Namen; linker, rechter: Heap END;
- VAR
- c: CHAR; i, letztePos: INTEGER; Name: Namen; h : Heap;
- Cont: BOOLEAN;
-
- PROCEDURE ClrBos; (* loescht die unteren Zeilen des Bildschirms *)
- BEGIN
- GotoXY(1,23); ClrEol; GotoXY(1,24); ClrEol; GotoXY(1,25); ClrEol;
- GotoXY(1,23);
- END;
-
- PROCEDURE Pause (i: INTEGER);
- VAR j: REAL;
- BEGIN j := 1.0; WHILE i > 0 DO BEGIN i := i-1; j := j+0.0; END; END;
-
- (* stellt den Bezeichner n an der Position (xpos,ypos) alternierend dar: *)
- PROCEDURE Zeige (n: Namen; xpos, ypos: INTEGER);
- VAR i: INTEGER;
- BEGIN
- FOR i := 1 TO 2 DO BEGIN
- LowVideo; Write(n); Pause(3000); GotoXY(xpos,ypos);
- NormVideo; Write(n); Pause(3000); GotoXY(xpos,ypos);
- END;
- END;
-
- (* verbindet die Knoten lastx und x, falls Tiefe > 1 ist: *)
- PROCEDURE Linie (lastx, x, y: INTEGER);
- VAR i: INTEGER;
- BEGIN
- y := y-2; GotoXY(lastx+1,y-1); Write('!'); GotoXY(lastx+1,y); Write('+');
- FOR i := lastx+2 TO x DO BEGIN GotoXY(i,y); Write('-+'); END;
- FOR i := lastx-1 DOWNTO x+1 DO BEGIN GotoXY(i,y); Write('+-'); END;
- GotoXY(x+1,y+1); Write('!');
- END;
-
- (* Ausgabe des Heaps. Es wird versucht n in den Heap h einzufuegen. Der
- Einfuegeprozess wird "grafisch" verfolgt: *)
- PROCEDURE Baum (links, rechts, Tiefe, Col: INTEGER; VAR h: Heap; n: Namen);
- VAR mitte: INTEGER; h1: Heap;
- BEGIN
- IF Tiefe <= maxTiefe THEN BEGIN
- mitte := (rechts-links) DIV 2; GotoXY(links+mitte,Col);
- IF h = NIL THEN BEGIN (* mache neuen Eintrag *)
- New(h1);
- h1^.n := n; h1^.linker := NIL; h1^.rechter := NIL; h := h1;
- Zeige(h^.n,links+mitte,Col);
- IF Tiefe > 1 THEN Linie(letztePos,links+mitte,Col);
- END
- ELSE BEGIN
- Zeige(h^.n,links+mitte,Col); letztePos := links+mitte;
- IF h^.n > n THEN
- baum(links,links+mitte,Succ(Tiefe),Col+NxtCol,h^.rechter,n)
- ELSE IF h^.n < n THEN
- baum(links+mitte,rechts,Succ(Tiefe),Col+NxtCol,h^.linker,n)
- ELSE BEGIN
- ClrBos; Write('Der Bezeichner ',h^.n,' ist schon im Heap !');
- Pause(30000);
- END
- END
- END
- ELSE BEGIN (* Tiefe > maxTiefe *)
- ClrBos; WriteLn('Baumtiefe groesser ',maxTiefe,' !');
- Write('Der Bezeichner ',n,' wird nicht eingefuegt. '); Pause(30000);
- END;
- END;
-
- PROCEDURE lese_id (VAR n: Namen);
- VAR s: STRING[80]; i: INTEGER;
- BEGIN
- ClrBos; Write('neuer Bezeichner : '); ReadLn(s);
- IF Length(s) > 3 THEN BEGIN
- GotoXY(1,23); Write('Es werden nur die ersten 3 Buchstaben registriert');
- Pause(30000); s[0] := Chr(3); ClrBos;
- END;
- n := '___'; (* drei Unterstriche *)
- FOR i := 1 TO Length(s) DO n[i] := s[i];
- IF n = 'end' THEN Cont := FALSE ELSE Write('Fuege neuen Bezeichner ein');
- END;
-
- BEGIN
- i := 1; h := NIL; Cont := TRUE; ClrScr; GotoXY(1,21);
- WriteLn('Heapverwaltung. Beenden der Eingabe mit Bezeichner "end" ');
- WHILE Cont DO
- BEGIN lese_id(Name); baum(1,80,1,1,h,Name); END;
- END.