Aufgaben:
Lesen des Eingabetextes und Zerlegung in die einzelnen Zeichen im Sinne der Grammatik der Programmiersprache(Morpheme, Token, Atome oder Lexeme).
Morpheme k�nnen aufeiander folgen ( a+b*77 ) oder durch Trennzeichen voneinander getrennt sein ( call f1 )
Elliminierung von irrelevanten Textteilen (Kommentare, Leerzeichen...)
Konvertierungen
Erkennung von Wortsymbolen und Ersetzung durch besser handhabbare Symbolcodes
Die Aufgabenteilung von Lexer und Parser ist verschieblich. So kann die Erkennung zusammengesetzter Symbole durch den Scanner, aber auch von der Syntaxanalyse realisiert werden. Auch der Aufbau von Symboltabellen wird mitunter schon von der lexikalischen Analyse vorbereitet.
Die lexikalische Analyse kann als selbst�diger Compilerpass, als paralleler Prozess oder als Unterprogramm der Syntaxanalyse oranisiert sein. Bei den einfachen Einpasscompilern, die im Rahmen der Vorlesung diskutiert werden sollen, soll die lexikalische Analyse ein Unterprogramm sein, das jeweils das n�chste Morphem liefert.
Der Lexer selbst arbeitet in zwei Schritten.
Schritt 1:
Aus dem Eingabestrom werden die Zeichen gelesen und in einem Puffer alle zum Morphem geh�renden Zeichen gesammelt. Hierzu wird ein Automat verwendet.
Schritt 2:
Nachbereitung in Abh�ngigkeit des letzten Zustandes des Automaten.
Schl�sselworterkennung, falls Bezeichenr
Konvertierung, falls Zahl
Eintragen aller relevanten Informationen (Morphemcode, Morphemwert, Zeilen-/Spaltenposition) in eine Struktur Morphem.
<Morphem> ::= <Sonderzeichen>|<Zahl>|<Bezeichner>
<Sonderzeichen> ::= + | - | * | / | , | . | ; | ( | ) | ? | ! | # | = | < | <= | > | >= | :=
<Zahl> ::= Zi {<Zi>}
<Zi> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<Bezeichner> ::=Bu {BuZi}
<BuZi> ::= Bu | Zi
<Bu> ::= A | B | ... | Z | a | b | ... | z
Anhand eines Zustandgraphen kann der Automat zur Bildung der PL/0-Morpheme ganz gut und anschaulich beschrieben werden:

Zur Analyse regul�rer Sprachen eignet sich der endliche Automat. Er wird durch ein 7-tupel in folgender Weise beschrieben.
|
A=(X,Y,Z,f,g,F,z0) X: Eingabealphabet Y: Resultatalphabet Z: Menge der Zust�nde f: Schalt-/�bergangsfunktion g: Ausgabefunktion F: Menge der Finalzust�nde z0: Anfangszustand |
|
Ein Finalzustand ist dann erreicht, wenn ein Morphem vollst�ndig erkannt wurde. Die zu erkennenden Morpheme umfassen
Sonderzeichen
Zahl
Bezeichner / Wortsymbol
<=
>=
:=
Sie
legt fest, in welchen Zustand zn+1 der Automat �bergeht,
wenn er sich in einem Zustand zn befindet und ein bestimmtes
Eingabezeichen anliegt.
Die �bergangsfunktion wird in einer Matrix, die von den Zeichen des
Eingabealphabetes und den Zust�nden des Automaten aufgespannt wird,
dargestellt.
Sie legt fest, in welcher Weise das anliegende Eingabezeichen verarbeitet wird. Im realisierten PL/0-Compiler sind es die folgenden:
�berlesen
schreiben in Puffer
schreiben in Puffer mit Umwandlung in Gro�-/Kleinbuchstaben
Der Anfangszustand ist der Zustand 0.
Soll
nun eine Automatentabelle gebaut werden, so wird jedem Eingabezeichen
eine Spalte, und jedem Zustand eine Zeile zugeordnet. Die Zust�nde sind
aus dem Zustandsgraphen ersichtlich. In die Felder dieser Matrix
wird
der Folgezustand (Schaltfunktion) und die auszuf�hrende Ausgabefunktion
eingetragen. Diese Matrix l�sst sich nun drastisch komprimieren, in dem
die Eingabezeichen klassifiziert werden. Alle Buchstaben k�nnten zB.
die
Klasse Buchstabe, alle Ziffern die Klasse Ziffer und alle Sonderzeichen
die Klasse Sonderzeichen bilden. Dies kann sehr effizient mit einem
Zeichenklassenvektor realisiert werden.
| Zeichenklassenvektor |
Zeichenklassen |
|
0: Sonderzeichen 1: Ziffer 2: Buchstabe 3: ':' 4: '=' 5: '<' 6: '>' 7: Sonstige |
Somit ergibt sich folgende Automatentabelle:
Jeder Eintrag besteht aus zwei Teilen:
Folgezustand
Aktionsindex einer Akltion, die ausgef�hrt wird, bevor der Automat in den Folgezustand �bergeht
Die einzelnen Eintr�ge wurden hier durch einen einfachen char-Wert, der die beiden Informationen in jeweils einer Tetrade codiert, gebildet. Selbstverst�ndlich k�nnte auch jede Eintragung aus einer Struktur mit den Komponenten Folgezustand und Aktion bestehen.
char* vWSymb[]={“BEGIN“,“CALL“,“CONST“,"DO",“END“,“IF“,“ODD“,“PROCEDURE“,“THEN“,“VAR“,“WHILE“};
Diese Methode
ist einfach zu implementieren, aber doch recht uneffektiv, vor allem,
wenn die Anzahl der Wortsymbole gr��er wird. Wesentlich besser sind
Techniken, die auf dem Prinzip der hash-code-Tabellen basieren. Bei
diesen Techniken wird nach einem g�nstigen Kriterium ein Eintrag in
einer Tabelle indiziert, hinter dem sich im bestenfalls nur noch ein
einzelner Eintrag verbirgt, ansonsten mu� von dort aus dann sequenziell
durchsucht werden.
Dieser Quelltext lexframe.c soll einen Rahmen f�r den im
Praktikum zu bauenden Lexer sein und den Einstieg erleichtern.