home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* TOPDOWN.PAS *)
- (* 3.Programm: Top-Down-Parser, der auf den als Strings *)
- (* abgelegten Regeln operiert. *)
- (* (c) 1991 Andreas Tengicki & DMV-Verlag *)
- (* ------------------------------------------------------ *)
- PROGRAM TopDown;
-
- USES Regeln, Zketten;
-
- CONST
- Merk_Max = 100;
- Ana_Max = 50;
-
- TYPE
- Merk_Element = RECORD
- Regel : STRING;
- Nr : INTEGER;
- END;
-
- Merk_Feld = ARRAY [1..Merk_Max] OF Merk_Element;
-
- VAR
- RegelAnz,
- MerkAnz,
- i : INTEGER;
- Regel : Regel_Feld;
- Satzform,
- Wort,
- StartSym : STRING;
- Fehler : BOOLEAN;
- Merk : Merk_Feld;
- c : CHAR;
-
- (* Erweiterung für Ausgabe der Satzanalyse *)
- AnaCount : INTEGER;
- Analyse : ARRAY [1..Ana_Max] OF INTEGER;
-
-
- PROCEDURE RegelCut(i : INTEGER);
- VAR
- j : INTEGER;
- BEGIN
- FOR j := i+1 TO MerkAnz DO
- Merk[j-1] := Merk[j];
- DEC(MerkAnz);
- END;
-
- PROCEDURE Regelbestimmung;
- VAR
- i, j, n, add : INTEGER;
- Speichere,
- Result : Merk_Element;
- nonterm : CHAR;
- Flag : BOOLEAN;
- BEGIN
- n := 0;
- REPEAT
- INC(n);
- i := 1;
- WHILE i <= MerkAnz DO
- IF LenStr(Merk[i].Regel) < n THEN
- RegelCut(i)
- ELSE IF Merk[i].Regel[n] IN ['a'..'z'] THEN
- IF (Merk[i].Regel[n] = Wort [n]) AND
- (LenStr(Merk[i].Regel) <= LenStr(Wort)) THEN
- INC(i)
- ELSE BEGIN
- RegelCut(i)
- END
- ELSE BEGIN (* Nonterminal ... *)
- add := 0;
- Speichere := Merk[i];
- nonterm := Merk[i].Regel[n];
- FOR j := 1 TO RegelAnz DO
- IF Regel[j].l[1] = nonterm THEN BEGIN
- Result := Speichere;
- Ersetze(Result.Regel, Regel[j], n);
- IF add = 0 THEN
- Merk[i] := Result
- ELSE
- Merk[Merkanz+add] := Result;
- INC(add);
- END;
- MerkAnz := MerkAnz + add - 1;
- END;
- UNTIL (MerkAnz < 2) OR (n > LenStr(Wort));
- END;
-
- BEGIN
- WriteLn;
- WriteLn;
- WriteLn('Parserstrategien 3.Programm');
- WriteLn(' Top-Down-Parser');
- Regeleingabe(Regelanz, Regel);
- Write('Startsymbol: '); InpStr(StartSym);
- REPEAT
- Write('zu parsendes Wort: '); InpStr(wort);
- Fehler := FALSE;
- Satzform := StartSym;
- AnaCount := 0;
- REPEAT
- MerkAnz := 0;
- FOR i := 1 TO RegelAnz DO
- IF Regel[i].l[1] = Satzform[1] THEN BEGIN
- INC(MerkAnz);
- Merk[MerkAnz].Regel := Regel[i].r;
- Merk[MerkAnz].Nr := i;
- END;
- Regelbestimmung;
- IF Merkanz = 0 THEN
- Fehler := TRUE
- ELSE BEGIN
- INC(AnaCount);
- Analyse[AnaCount] := Merk[1].Nr;
- Ersetze(Satzform, Regel[Merk[1].Nr], 1);
- WHILE (Satzform[1] IN ['a'..'z']) AND NOT Fehler AND
- (LenStr(Satzform)*LenStr(Wort) > 0) DO BEGIN
- IF Satzform[1] = Wort[1] THEN BEGIN
- Satzform := TeilStr(Satzform, 2, LenStr(Satzform));
- Wort := TeilStr(Wort , 2, LenStr(Wort));
- END ELSE
- Fehler := TRUE;
- END;
- END;
- UNTIL Fehler OR (LenStr(Satzform)*LenStr(Wort) = 0);
- IF Fehler OR (LenStr(Wort)+LenStr(Satzform) > 0) THEN
- WriteLn('Wort nicht erkannt.')
- ELSE BEGIN
- WriteLn('Wort erkannt.');
- Write('Ersetzt durch die Regeln: ');
- FOR i := 1 TO AnaCount DO Write(Analyse[i]:3);
- WriteLn;
- END;
- Write('Nochmal [j/n]: '); InpChr(c);
- UNTIL c = 'n';
- END.
- (* ------------------------------------------------------ *)
- (* Ende von TOPDOWN.PAS *)
-
-
-