Kapitel 2.5

Werbung
Programmiersprachen und Übersetzer
Sommersemester 2009
27. April 2009
Aufbau von lexikalen Scannern
Beispiel
Festlegung der Tokenklassen für eine Programmiersprache“, die
”
nur einfache Wertzuweisungen mit arithmetischen Ausdrücken und
if-Anweisungen enthält.
Zunächst definiert man sich zweckmäßigerweise Abkürzungen
<letter> = [A - Z] | [a - z]
<digit>
= [0 - 9]
Die Tokenklassen ident (Identifier) und number (vorzeichenlose
Integer- und Real-Zahlen) wären dann:
<letter> ( <letter> | <digit> )∗
<digit>+ ( .<digit>+ )?
Die Tokenklasse relop (Vergleichsoperator) ist durch den regulären
Ausdruck:
= | <= | <> | < | > | >=
definiert und entsprechend arithop durch:
+ | - | * | /
Die reservierten Wörter if, then und else bilden jeweils für sich
eine Tokenklasse.
Verwendet man einen Scanner-Generator wie etwa LEX, FLEX
oder JFLEX, so reicht es aus, reguläre Ausdrücke zu definieren
und geeignete Aktionen zu konstruieren, die beim Erkennen eines
Tokens ausgeführt werden sollen.
Es ist wichtig, dass alle Eingabezeichen zu Token zusammengefasst
werden. Aus diesem Grund sollte man dann noch eine weitere
Tokenklasse ws (white space) schaffen, die das Überlesen von
Leerzeichen usw. steuert.
<delim> = <blank> | <tab> | <newline>
und die Tokenklasse ws wird definiert durch
<delim>+
Die zugeordnete Aktion wäre dann natürlich eine Null-Operation!
Arbeitsweise von Scanner-Generatoren (LEX)
Lex-Quellenprogramm- Lex-Compiler
lex.l
lex.yy.c
-
C-Compiler
EingabeProgramm
-
a.out
- lex.yy.c
- a.out
- Folge von Token
Aufbau eines Lex-Programms
%{
I
Deklarationen von Konstanten, Variablen usw.
%}
Aufbau eines Lex-Programms
%{
I
Deklarationen von Konstanten, Variablen usw.
%}
I
Deklaration von Abkürzungen für reguläre Teilausdrücke
Aufbau eines Lex-Programms
%{
I
Deklarationen von Konstanten, Variablen usw.
%}
I
Deklaration von Abkürzungen für reguläre Teilausdrücke
%%
I
reguläre Ausdrücke mit zugeordneten Aktionen
(Übersetzungsregeln)
%%
Aufbau eines Lex-Programms
%{
I
Deklarationen von Konstanten, Variablen usw.
%}
I
Deklaration von Abkürzungen für reguläre Teilausdrücke
%%
I
reguläre Ausdrücke mit zugeordneten Aktionen
(Übersetzungsregeln)
%%
I
Hilfsfunktionen
Aufbau der Übersetzungsregeln
Die Übersetzungsregeln haben die Form:
reg. Ausdrucki
{ Aktioni }
Aktionen werden in LEX als Codefragmente in C geschrieben.
Arbeitsweise des durch LEX generierten Scanners
Von der momentanen Position aus liest das Unterprogramm yylex
Zeichen für Zeichen der Eingabe, bis es das längste Wort gefunden
hat, das zu einem der regulären Ausdrücke passt
Dann wird die zugeordnete Aktion ausgeführt, die üblicherweise ein
Rücksprung zum Parser mit der Rückgabe der Tokenklasse ist.
Bemerkung
Gibt es mehr als einen passenden regulären Ausdruck zu diesem
längsten Anfangsstück, wird der in der Reihenfolge des
Lex-Programms erste reguläre Ausdruck gewählt.
Kommunikation mit dem Parser
Die Übergabe der Information von yylex an den Parser geschieht
meist wie folgt:
Kommunikation mit dem Parser
Die Übergabe der Information von yylex an den Parser geschieht
meist wie folgt:
- der Rückgabewert von yylex gibt die Tokenklasse an,
Kommunikation mit dem Parser
Die Übergabe der Information von yylex an den Parser geschieht
meist wie folgt:
- der Rückgabewert von yylex gibt die Tokenklasse an,
- der Tokenwert wird in einer globalen Variable yylval (ist vom
Parser zu liefern!) gespeichert,
Kommunikation mit dem Parser
Die Übergabe der Information von yylex an den Parser geschieht
meist wie folgt:
- der Rückgabewert von yylex gibt die Tokenklasse an,
- der Tokenwert wird in einer globalen Variable yylval (ist vom
Parser zu liefern!) gespeichert,
- yytext ist ein Zeiger auf das erste Zeichen des Tokens und
- yyleng ist die Länge des Tokens in der Eingabe.
Kommunikation mit dem Parser
Die Übergabe der Information von yylex an den Parser geschieht
meist wie folgt:
- der Rückgabewert von yylex gibt die Tokenklasse an,
- der Tokenwert wird in einer globalen Variable yylval (ist vom
Parser zu liefern!) gespeichert,
- yytext ist ein Zeiger auf das erste Zeichen des Tokens und
- yyleng ist die Länge des Tokens in der Eingabe.
Damit können die Hilfsfunktionen des Scanners oder aber der
Parser auf das gefundene Token zugreifen und eventuell weitere
Aktionen ausführen.
Beispieleingabe für LEX
/**************************************************************/
/*
scanner.l
*/
/**************************************************************/
/* Definition von Konstanten, Variablen und Typen */
%{
/* Hier werden die Tokenklassen numerisch codiert */
#define IDENT
1
#define NUMBER
2
#define RELOP
3
#define ARITHOP 4
#define ASSIGNOP 5
#define IF
6
#define THEN
7
#define ELSE
8
#define SEMIK
9
/* Weitere Definitionen z.B. fuer einzelne Operationen */
/* Dies sind die
#define ADD
#define SUB
#define MULT
#define DIV
Tokenwerte zur Tokenklasse 4 */
41
42
43
44
/* Dies sind die Tokenwerte zur Tokenklasse 3 */
#define GT
31
#define GE
32
#define LT
33
#define LE
34
#define EQ
35
#define NE
36
%}
/* Definition regulaerer Ausdruecke */
/* LEX-Konvention: bei der Definition eines Ausdrucks wird name, */
/* beim Gebrauch {name} verwendet. */
delim
ws
letter
digit
ident
number
[ \t\n]
/* \t fuer Tabulator, \n für Zeilenende */
{delim}+
[A-Za-z]
[0-9]
{letter}({letter}|{digit})*
{digit}+(\.{digit}+)?
/* . steht in LEX für ein beliebiges Zeichen, daher
%%
\.*/
{ws}
{ /* keine Aktion und kein Ruecksprung */ }
"if"
"then"
"else"
/* zuerst kommen die Schluesselwoerter */
{ return(IF); }
{ return(THEN); }
{ return(ELSE); }
{ident}
{number}
{ yylval = install_id(); return(IDENT); }
{ yylval = install_num(); return(NUMBER); }
"*"
"/"
"+"
"-"
"<="
"<"
"="
">"
">="
"<>"
":="
";"
%%
{
{
{
{
{
{
{
{
{
{
{
{
yylval = MULT; return(ARITHOP); }
yylval = DIV; return(ARITHOP); }
yylval = ADD; return(ARITHOP); }
yylval = SUB; return(ARITHOP); }
yylval = LE; return(RELOP); }
yylval = LT; return(RELOP); }
yylval = EQ; return(RELOP); }
yylval = GT; return(RELOP); }
yylval = GE; return(RELOP); }
yylval = NE; return(RELOP); }
return(ASSIGNOP); }
return(SEMIK); }
/* Hier wuerden Hilfsfunktionen wie install_id() usw. stehen */
/* Will man vielleicht nur eine Liste der Token ausgeben, so koennte
man an dieser Stelle auch ein Hauptprogramm definieren, z.B.: */
main()
{
int c;
while (c = yylex())
/* Rueckgabewert von yylex */
/* ist 0 falls eof gelesen */
printf( "TOKENKLASSE: %d
%s\n", c, yytext);
}
Hat man keinen Generator für einen Scanner zur Verfügung oder
ist die Verwendung eines automatisch erzeugten Scanner zu
aufwendig, stellt sich die Frage, wie man einen Scanner für eine
gegebene Menge regulärer Ausdrücke konstruieren kann.
Dazu 3 Schritte:
Hat man keinen Generator für einen Scanner zur Verfügung oder
ist die Verwendung eines automatisch erzeugten Scanner zu
aufwendig, stellt sich die Frage, wie man einen Scanner für eine
gegebene Menge regulärer Ausdrücke konstruieren kann.
Dazu 3 Schritte:
1. Transformation regulärer Ausdrücke in Transitionsgraphen
(Darstellung eines nicht-deterministischen Automaten)
Hat man keinen Generator für einen Scanner zur Verfügung oder
ist die Verwendung eines automatisch erzeugten Scanner zu
aufwendig, stellt sich die Frage, wie man einen Scanner für eine
gegebene Menge regulärer Ausdrücke konstruieren kann.
Dazu 3 Schritte:
1. Transformation regulärer Ausdrücke in Transitionsgraphen
(Darstellung eines nicht-deterministischen Automaten)
2. Transformation des nicht-deterministischen in einen
deterministischen Automaten
Hat man keinen Generator für einen Scanner zur Verfügung oder
ist die Verwendung eines automatisch erzeugten Scanner zu
aufwendig, stellt sich die Frage, wie man einen Scanner für eine
gegebene Menge regulärer Ausdrücke konstruieren kann.
Dazu 3 Schritte:
1. Transformation regulärer Ausdrücke in Transitionsgraphen
(Darstellung eines nicht-deterministischen Automaten)
2. Transformation des nicht-deterministischen in einen
deterministischen Automaten
3. Implementation des Automaten
Transitionsgraphen
Transitionsgraphen sind eine graphische Darstellung der
Arbeitsweise endlicher Automaten, die eine Eingabe Zeichen für
Zeichen lesen und dabei verschiedene Zustände durchlaufen.
Transitionsgraphen
Transitionsgraphen sind eine graphische Darstellung der
Arbeitsweise endlicher Automaten, die eine Eingabe Zeichen für
Zeichen lesen und dabei verschiedene Zustände durchlaufen.
I
Zustände werden durch Knoten und Überführungen durch
Kanten dargestellt.
Transitionsgraphen
Transitionsgraphen sind eine graphische Darstellung der
Arbeitsweise endlicher Automaten, die eine Eingabe Zeichen für
Zeichen lesen und dabei verschiedene Zustände durchlaufen.
I
Zustände werden durch Knoten und Überführungen durch
Kanten dargestellt.
I
Es gibt es einen Startzustand, in dem der Automat startet,
und mindestens einen Endzustand.
Transitionsgraphen
Transitionsgraphen sind eine graphische Darstellung der
Arbeitsweise endlicher Automaten, die eine Eingabe Zeichen für
Zeichen lesen und dabei verschiedene Zustände durchlaufen.
I
Zustände werden durch Knoten und Überführungen durch
Kanten dargestellt.
I
Es gibt es einen Startzustand, in dem der Automat startet,
und mindestens einen Endzustand.
I
Gelangt der Automat durch Lesen einiger Zeichen der Eingabe
vom Startzustand aus in einen Endzustand, so hat er das
gelesene Wort in der Eingabe akzeptiert.
Transitionsgraphen
Transitionsgraphen sind eine graphische Darstellung der
Arbeitsweise endlicher Automaten, die eine Eingabe Zeichen für
Zeichen lesen und dabei verschiedene Zustände durchlaufen.
I
Zustände werden durch Knoten und Überführungen durch
Kanten dargestellt.
I
Es gibt es einen Startzustand, in dem der Automat startet,
und mindestens einen Endzustand.
I
Gelangt der Automat durch Lesen einiger Zeichen der Eingabe
vom Startzustand aus in einen Endzustand, so hat er das
gelesene Wort in der Eingabe akzeptiert.
Satz
Die Menge aller so akzeptierten Wörter bildet eine reguläre Sprache
Beispiel
Ein Übergang der Form
i
c
j
hat folgende Bedeutung:
Befindet sich der Automat im Zustand i und liest er als nächstes
Zeichen ein c, so geht er in den Zustand j über (Folgezustand).
Ein doppelter Kreis markiert einen Endzustand.
Prinzipielle Arbeitsweise eines endlichen Automaten
Eingabeband
Lesekopf
-
Steuerwerk
mit Zuständen
Akzeptieren von Eingabewörtern
Es gibt zwei alternative Möglichkeiten, ein Wort zu akzeptieren:
1. Erreicht der Automat einen Endzustand, so hält er an. Die
gelesenen Zeichen bilden ein Wort der Sprache. Ist der
Endzustand zusätzlich mit einem ∗ markiert, so gehört das
zuletzt gelesene Zeichen nicht zum akzeptierten Wort und
muss daher in die Eingabe zurückgestellt werden.
Akzeptieren von Eingabewörtern
Es gibt zwei alternative Möglichkeiten, ein Wort zu akzeptieren:
1. Erreicht der Automat einen Endzustand, so hält er an. Die
gelesenen Zeichen bilden ein Wort der Sprache. Ist der
Endzustand zusätzlich mit einem ∗ markiert, so gehört das
zuletzt gelesene Zeichen nicht zum akzeptierten Wort und
muss daher in die Eingabe zurückgestellt werden.
2. Der Automat liest so lange aus der Eingabe, bis er in einen
Zustand z gerät, in dem das nächste Zeichen nicht gelesen
werden kann. Ist z ein Endzustand, so bilden die gelesenen
Zeichen bilden ein Wort der Sprache.
Beispiel
Der Automat erkennt die Wörter, die durch den regulären
Ausdruck [0-9]+ (.[0-9]+ )? bezeichnet werden
0-9
start
0
0-9
1
0-9
.
2
≠ 0-9
≠.
5
0-9
*
3
≠ 0-9
4
*
Fordert man, daß der Automat immer solange weiterarbeitet, bis er
auf ein Zeichen trifft, für das er keinen Übergang vom
momentanen Zustand hat, so vereinfacht sich der TG zu:
0-9
start
0
0-9
1
0-9
.
2
0-9
3
Ein Wort wird in diesem Fall akzeptiert, wenn der Automat in
einem Endzustand stehenbleibt.
Definition
Ein Transitionsgraph (TG) heißt deterministisch, falls er
1. keine Übergänge besitzt, die mit dem leeren Wort ε markiert
sind und
2. keine Zustände besitzt, von denen aus es mehr als einen mit
einem Zeichen a des Alphabets markierten Übergang gibt.
Verletzt ein Transitionsgraph eine der beiden Bedingungen, wird er
nichtdeterministisch genannt.
Beispiel
a
start
0
a
1
b
2
b
3
b
Die Menge der von diesem Automaten erkannten Worte wird durch
den regulären Ausdruck (a|b)∗ abb bezeichnet.
Beispiel
b
1
a
2
ε
start
0
a
ε
3
b
4
Die Menge der von diesem Automaten erkannten Worte wird durch
den regulären Ausdruck ab∗ |ba∗ bezeichnet.
Erzeugung von Scannern aus deterministischen
Transitionsgraphen
Tabellengesteuerter Scanner
Transitionstabelle T für Transitionsgraphen aus dem
vorangehenden Beispiel
Zustand
0
1
2
3
Eingabezeichen
0-9
.
1
–
1
2
3
–
3
–
Aufbau eines tabellengesteuerten Scanners
Eingabe
$
H
Y
H
H
Ende-Markierung
Lesefenster
Steuerwerk
(mit Zuständen)
?
erkannte Token
- Transitionstabelle T
Arbeitsweise des tabellengesteuerten lexical Scanners
I
Initiale Situation: Auf dem Eingabeband steht das zu lesende
Wort, eventuell gefolgt von einer Endmarkierung.
Das Lesefenster steht auf dem ersten Buchstaben, und die
Steuerung ist im Startzustand.
Arbeitsweise des tabellengesteuerten lexical Scanners
I
I
Initiale Situation: Auf dem Eingabeband steht das zu lesende
Wort, eventuell gefolgt von einer Endmarkierung.
Das Lesefenster steht auf dem ersten Buchstaben, und die
Steuerung ist im Startzustand.
Arbeitsschritt: Abhängig vom momentanen Zustand z der
Steuerung und dem Zeichen c unter dem Lesefenster wird in
der Tansitionstabelle unter dem Eintrag T (z, c) nachgesehen.
a) T (z, c) enthält einen Zustand z 0 . Dann geht die Steuerung in
den Zustand z 0 über, und das Lesefenster wird um ein Zeichen
nach rechts geschoben.
b) T (z, c) enthält keinen Zustand. Ist z ein Endzustand, dann
wurde ein Token erkannt. Ansonsten ist ein Fehler in der
Eingabe aufgetreten.
Bemerkung
1. Um das nächste Token in der Eingabe zu erkennen, wird das
Steuerwerk auf den Startzustand gesetzt und der Automat
erneut gestartet.
Bemerkung
1. Um das nächste Token in der Eingabe zu erkennen, wird das
Steuerwerk auf den Startzustand gesetzt und der Automat
erneut gestartet.
2. Diese Arbeitsweise ist gültig für Transitionsgraphen von
Automaten, die solange weiterarbeiten, bis sie auf ein Zeichen
treffen, für das kein Übergang definiert ist.
Bemerkung
1. Um das nächste Token in der Eingabe zu erkennen, wird das
Steuerwerk auf den Startzustand gesetzt und der Automat
erneut gestartet.
2. Diese Arbeitsweise ist gültig für Transitionsgraphen von
Automaten, die solange weiterarbeiten, bis sie auf ein Zeichen
treffen, für das kein Übergang definiert ist.
3. Für die Automaten, die beim Erreichen eines Endzustands
anhalten, muss die Arbeitsweise des tabellengesteuerten
Scanners leicht modifiziert werden!
Direkt erzeugter Scanner für die Tokenklasse
int scanner ()
{
int
zustand;
char
zeichen;
zustand = 0;
while (TRUE)
{
if (feof(stdin)) return (EOF);
zeichen = getchar();
switch (zustand)
{
case 0: if (isdigit(zeichen))
zustand = 1;
else
error();
break;
case 1: if (zeichen == ’.’)
zustand = 2;
else if (!isdigit(zeichen))
{
ungetc(zeichen);
return (NUMBER);
}
break;
case 2: if (isdigit(zeichen))
zustand = 3;
else
error();
break;
case 3: if (!isdigit(zeichen))
{
ungetc(zeichen);
return(NUMBER);
}
break;
}
}
}
Erzeugung von Transitionsgraphen aus regulären
Ausdrücken
1. Ist der reguläre Ausdruck von der Form ε, so ist der
zugehörige TG von der Form:
start
ε
2. Ist der reguläre Ausdruck von der Form a, so ist der
zugehörige TG von der Form:
start
a
3. Ist der reguläre Ausdruck von der Form α1 | α2 , so ist der
zugehörige TG von der Form:
ε
TG für α
1
ε
start
ε
TG für α
2
ε
4. Ist der reguläre Ausdruck von der Form α1 α2 , so ist der
zugehörige TG von der Form:
start
TG für α
1
ε
TG für α
2
5. Ist der reguläre Ausdruck von der Form α∗ oder α+ , so ist der
zugehörige TG von der Form:
ε
start
ε
TG für α
ε
ε
entfällt bei α+
Umwandlung eines nichtdeterministischen
Transitionsgraphen T in einen deterministischen
1. Schritt: Entfernen der ε-Übergänge.
Idee: Befindet sich der Automat nach Lesen eines Buchstabens im
Zustand z, so befindet“ er sich ebenso in jedem Zustand z 0 , der
”
von z aus durch eine Folge von ε-Übergängen erreichbar ist.
Die Menge der Knoten in dem nichtdeteministischen
Transitionsgraphen T sei K .
Es wird ein neuer Transitionsgraph T 0 folgendermaßen konstruiert:
I
T 0 enthält alle Knoten aus K , auf die wenigstens ein
Übergangspfeil zeigt, der nicht mit ε markiert ist, sowie den
Startknoten von T . Die Menge dieser Knoten werde mit K 0
bezeichnet.
I
T 0 enthält alle Knoten aus K , auf die wenigstens ein
Übergangspfeil zeigt, der nicht mit ε markiert ist, sowie den
Startknoten von T . Die Menge dieser Knoten werde mit K 0
bezeichnet.
I
In T 0 wird ein Übergangspfeil vom Knoten k1 zum Knoten k2
mit der Markierung a eingetragen, wenn man in T vom
Knoten k1 mit einer Folge von ε-Übergängen zu einem
Knoten k gelangen kann, von dem ein mit a markierter
Übergangspfeil zum Knoten k2 führt.
(Diese Folge der ε-Übergänge darf auch leer sein.)
I
T 0 enthält alle Knoten aus K , auf die wenigstens ein
Übergangspfeil zeigt, der nicht mit ε markiert ist, sowie den
Startknoten von T . Die Menge dieser Knoten werde mit K 0
bezeichnet.
I
In T 0 wird ein Übergangspfeil vom Knoten k1 zum Knoten k2
mit der Markierung a eingetragen, wenn man in T vom
Knoten k1 mit einer Folge von ε-Übergängen zu einem
Knoten k gelangen kann, von dem ein mit a markierter
Übergangspfeil zum Knoten k2 führt.
(Diese Folge der ε-Übergänge darf auch leer sein.)
I
Der Startknoten in T ist auch Startknoten in T 0 .
I
T 0 enthält alle Knoten aus K , auf die wenigstens ein
Übergangspfeil zeigt, der nicht mit ε markiert ist, sowie den
Startknoten von T . Die Menge dieser Knoten werde mit K 0
bezeichnet.
I
In T 0 wird ein Übergangspfeil vom Knoten k1 zum Knoten k2
mit der Markierung a eingetragen, wenn man in T vom
Knoten k1 mit einer Folge von ε-Übergängen zu einem
Knoten k gelangen kann, von dem ein mit a markierter
Übergangspfeil zum Knoten k2 führt.
(Diese Folge der ε-Übergänge darf auch leer sein.)
I
Der Startknoten in T ist auch Startknoten in T 0 .
I
Endknoten sind alle Knoten k aus K 0 , von denen aus in T ein
Endknoten mit einer (auch leeren) Folge von ε-Übergängen
erreicht werden kann.
2. Schritt: Vom nichtdeterministischen TG T ohne
ε-Übergänge zum deterministischen TG.
Idee: Befindet sich der Automat in einem Zustand z und könnte er
nach Lesen eines Zeichens a sowohl in den Zustand z1 als auch in
den Zustand z2 gehen, so geht“ er in beide Zustände.
”
Gegeben sei ein nichtdeterministischer Transitionsgraph TN ohne
ε-Überführungen. Die Menge der Knoten von TN sei mit KN
bezeichnet.
Konstruiert wird ein deterministischer Transitionsgraph TD , dessen
Knoten aus gewissen Teilmengen von Knoten aus KN bestehen.
Die Menge der Knoten KD von TD wird dabei sukzessive
bestimmt. KD enthält zu Beginn nur die Menge, die den
Startknoten von TN enthält.
Anschließend wird folgendes solange ausgeführt, bis keine neuen
Knoten mehr zu KD hinzugefügt und keine neuen Überführung
mehr in TD eingetragen werden:
Anschließend wird folgendes solange ausgeführt, bis keine neuen
Knoten mehr zu KD hinzugefügt und keine neuen Überführung
mehr in TD eingetragen werden:
I
Ist P ein Knoten aus KD (d.h. P = {z1 , . . . , zr } mit zi ∈ KN ),
so wird für jedes Eingabezeichen a die Menge Q aller Knoten
in KN bestimmt, für die in TN eine Überführung von einem
Knoten aus P in einen Knoten aus Q mit der Markierung a
vorhanden ist.
Anschließend wird folgendes solange ausgeführt, bis keine neuen
Knoten mehr zu KD hinzugefügt und keine neuen Überführung
mehr in TD eingetragen werden:
I
Ist P ein Knoten aus KD (d.h. P = {z1 , . . . , zr } mit zi ∈ KN ),
so wird für jedes Eingabezeichen a die Menge Q aller Knoten
in KN bestimmt, für die in TN eine Überführung von einem
Knoten aus P in einen Knoten aus Q mit der Markierung a
vorhanden ist.
I
Ist Q 6= ∅ und existiert ein Zustand Q noch nicht in KD , so
wird Q zu den bisher schon in KD vorhandenen Knoten
hinzugefügt.
Anschließend wird folgendes solange ausgeführt, bis keine neuen
Knoten mehr zu KD hinzugefügt und keine neuen Überführung
mehr in TD eingetragen werden:
I
Ist P ein Knoten aus KD (d.h. P = {z1 , . . . , zr } mit zi ∈ KN ),
so wird für jedes Eingabezeichen a die Menge Q aller Knoten
in KN bestimmt, für die in TN eine Überführung von einem
Knoten aus P in einen Knoten aus Q mit der Markierung a
vorhanden ist.
I
Ist Q 6= ∅ und existiert ein Zustand Q noch nicht in KD , so
wird Q zu den bisher schon in KD vorhandenen Knoten
hinzugefügt.
I
Außerdem wird eine mit a markierte Überführung in TD von
P nach Q eingetragen.
I
Der Startknoten in TD ist die Menge, die nur den Startknoten
von TN enthält.
I
Der Startknoten in TD ist die Menge, die nur den Startknoten
von TN enthält.
I
Ein Knoten {z1 , . . . , zr } in TD wird Endknoten in TD , wenn
einer der Knoten zi ∈ KN mit i ∈ [1 : r ] ein Endknoten in TN
ist.
Herunterladen