home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* FIRSTFOL.PAS *)
- (* 2.Programm: Erzeugt die First(n) einer Satzform bzw. *)
- (* die Follow(n) eines Nonterminals. *)
- (* Die Regeln werden wieder als Strings *)
- (* eingegeben; die Analyse erfolgt über *)
- (* einfachste Stringverarbeitung. *)
- (* (c) 1991 Andreas Tengicki & DMV-Verlag *)
- (* ------------------------------------------------------ *)
- PROGRAM FirstFol;
-
- USES FiFoQueu, Regeln, Zketten;
-
- CONST
- Count_Max = 10;
-
- VAR
- Inp, Out : FiFo_Satz_Ptr;
- Element,
- Satzform : Fifo_Element;
- Regel : Regel_Feld;
- RegelAnz,
- n, Modus,
- Pos,
- Pos2, i,
- CountStop : INTEGER;
- Erg : STRING;
- NonTerm,
- c : CHAR;
- Flag : BOOLEAN;
-
- FUNCTION nTest(Satzform : STRING; Pos : INTEGER) : BOOLEAN;
- (* prüft, ob die N auf POS folgenden Symbole der *)
- (* SATZFORM Terminals sind. *)
- VAR
- Flag : BOOLEAN;
- i : INTEGER;
- BEGIN
- Flag := TRUE;
- i := 1;
- WHILE Flag AND (i <= n) AND
- (i+Pos <= LenStr(Satzform)) DO BEGIN
- IF Satzform[i+Pos] IN ['A'..'Z'] THEN Flag := FALSE;
- INC(i);
- END;
- nTest := Flag;
- END;
-
- FUNCTION Follow( Satzform : STRING;
- VAR Ergebnis : STRING) : BOOLEAN;
- (* - ist TRUE, falls ein follow(n) von nonterm *)
- (* in SATZFORM enthalten ist, und gibt das *)
- (* follow(n) als ERGEBNIS zurueck. *)
- (* - sonst FALSE, ERGEBNIS ist dann undefiniert *)
- VAR
- Flag : BOOLEAN;
- Pos : INTEGER;
- BEGIN
- Pos := InStr(NonTerm, Satzform);
- Flag := (Pos = 0);
- IF Flag THEN
- Flag := nTest(Satzform, Pos);
- IF Flag THEN
- Ergebnis := TeilStr(Satzform, Pos+1, Pos+n);
- Follow := Flag;
- END;
-
- BEGIN
- WriteLn;
- WriteLn;
- WriteLn('Parserstrategien 2.Programm:');
- WriteLn(' First-Follow-Erzeugung');
-
- (* Initialisierungen *)
- FiFo_Init_d(Inp, Out);
-
- (* Eingaben *)
- Regeleingabe(RegelAnz, Regel);
- REPEAT
- Write('Modus (0:First-, 1:Follow-Erzeugung): ');
- ReadLn(Modus);
- IF Modus = 0 THEN BEGIN
- Write('Satzform: ');
- InpStr(Satzform.Satz);
- Write('n: '); ReadLn(n);
- END ELSE BEGIN
- Write('Startsymbol: ');
- InpStr(Satzform.Satz);
- Write('n: '); ReadLn(n);
- Write('Zu untersuchendes Nonterminal: ');
- InpChr(NonTerm);
- END;
- Element.Satz := Satzform.Satz;
- Element.Last := '';
- Element.Count := -1;
- FiFo_In_d(Inp, Out, Element);
-
- (* Analyseschleife *)
- CountStop := 0;
- REPEAT
- Fifo_Out_d(Inp, Out, Element);
- IF Element.Count = 0 THEN BEGIN
- IF Modus = 0 THEN BEGIN
- (* Wort könnte ausgegeben werden *)
- IF nTest(Element.Satz, 0) THEN
- WriteLn(TeilStr(Element.Satz, 1, n));
-
- END ELSE IF Follow(Element.Satz, Erg) THEN BEGIN
- Element.Last := Erg;
- WriteLn(Erg);
- END;
- (* gemäß Regel ersetzen, falls Satzform noch *)
- (* interessant ist. *)
- IF Element.Count > Count_Max THEN
- INC(CountStop)
- ELSE BEGIN
- Satzform := Element;
- FOR i := 1 TO RegelAnz DO BEGIN
- Pos := InStr(Regel[i].l, Satzform.Satz);
- IF Pos <> 0 THEN BEGIN
- Element := Satzform;
- Ersetze(Element.Satz, Regel[i], Pos);
- (* wurde First/Follow verändert ? *)
- IF Modus = 0 THEN BEGIN
- IF Pos > n THEN (* First-Modus *)
- INC(Element.Count)
- ELSE
- Element.Count := 0
- END ELSE BEGIN (* Follow-Modus *)
- IF Follow(Element.Satz, Erg) THEN
- IF Erg = Element.Last THEN
- INC(Element.Count)
- ELSE
- Element.Count := 0
- ELSE
- INC(Element.Count);
- END;
- FiFo_In_d(Inp, Out, Element);
- END;
- END;
- END;
- END;
- UNTIL (Inp = NIL);
- WriteLn('Abbruch bei ', CountStop:1, ' Satzformen.');
-
- Write('Nochmal [j/n]: '); InpChr(c);
- UNTIL c = 'n';
- END.
- (* ------------------------------------------------------ *)
- (* Ende von FIRSTFOL.PAS *)
-