260 likes | 374 Views
Tokenizer. Prolog Aufbaukurs SS 2000 Heinrich-Heine-Universität Düsseldorf Christof Rumpf. Tokenizer. Ein Tokenizer ist ein Programm, das beliebigen Zeicheninput in eine Liste von Tokens umwandelt. Ziel ist die Verarbeitung von Daten, die nicht in Prolog-Syntax vorliegen.
E N D
Tokenizer Prolog Aufbaukurs SS 2000 Heinrich-Heine-Universität Düsseldorf Christof Rumpf
Tokenizer • Ein Tokenizer ist ein Programm, das beliebigen Zeicheninput in eine Liste von Tokens umwandelt. • Ziel ist die Verarbeitung von Daten, die nicht in Prolog-Syntax vorliegen. • Quelle der Daten kann die Tastatur oder eine Datei sein. Tokenizer
Tokens • Ein Token ist ein Intervall in einer Zeichenfolge, der per Konvention als nicht weiter zerlegbar gilt. • Z.B. sind die Wörter dieser Präsentation durch Leerzeichen getrennte Tokens. • Zeichen wie Punkt, Komma und Zeilenwechsel können ebenfalls Trenner sein oder auch selbständige Tokens bilden. Tokenizer
Anwendungen • Natürlichsprachlicher Input • Umwandeln einer Zeichenfolge in eine Wortliste. • Compilerbau • Übergabe einer Tokenliste an einen Compiler. • Datenbanken • Import von Daten aus einer externen Datenbank. Tokenizer
Klassen von Zeichen • ASCII-Code: 1 Byte = 8 Bit = 256 Zeichen • Buchstaben a..z, A..Z, ä, ö, ü, ß, ... • Ziffern 0..1 • Sonderzeichen .,;:+-#`´„%& ... • White Space: Leerzeichen und Tabulator • Steuerzeichen: Zeilenvorschub, EOF, ... Tokenizer
Klassen von Tokens • Wörter aus Buchstaben • Zahlen aus Ziffern • Operatoren aus Sonderzeichen • Eventuell White Space als Token • Andere ... Tokenizer
Input Tastatur Datei Programm Streams DDE OLE ... Output Bildschirm Drucker Datei Programm ... Input und Output Tokenizer
Standard-Input • see/1 bestimmt • seen/0 schließt • seeing/1 liefert • see ohne seen: Keine Eingabemöglichkeit mehr - Absturz von Prolog. • seen für Tastatur (user): kein Effekt. den aktuellen Standard-Input. Tokenizer
Standard-Output • tell/1 bestimmt • told/0 schließt • telling/1 liefert • tell ohne told: Keine Kontrolle mehr über die Ausgabe des Programms. • told für Bildschirm (user): kein Effekt. den aktuellen Standard-Output. Tokenizer
?- see(‘test.txt‘). Öffnet die Datei test.txt im aktuellen Verzeichnis und setzt den Lesezeiger an den Anfang der Datei. Lesezeiger bleibt positioniert, falls Datei schon offen. Scheitert, falls Datei nicht existiert oder bereits zum Schreiben geöffnet ist. Lesezeiger kann nur vom Anfang zum Ende bewegt werden. ?- tell(‘test.txt‘). Öffnet oder erzeugt die Datei test.txt im aktuellen Verzeich-nis und setzt den Schreibzeiger an den Anfang der Datei. Schreibzeiger bleibt positioniert, falls Datei schon offen. Evtl. vorhandene Daten in der Datei sind damit verloren. Scheitert, falls die Datei bereits zum Lesen geöffnet ist. Schreibzeiger kann nur vom Anfang zum Ende bewegt werden. Schreib- Lesezeiger Tokenizer
input(Goal,F1):- seeing(F2), see(F1), (call(Goal); true), !, seen, see(F2). output(Goal,F1):- telling(F2), tell(F1), (call(Goal); true), !, told, tell(F2). Muster für Ein- Ausgabeprädikate Tokenizer
Anwendungsbeispiel ?- input(read_sentence(S),user), parse(S,Tree), output(pp(Tree),prn), output(pp(Tree),‘c:\tree.txt‘). Im folgenden Beispiel wird ein Satz von der Tastatur eingelesen und geparst. Der Parser liefert einen Syntaxbaum zurück, der mit einem Pretty-Printer zuerst auf den Drucker und dann in eine Datei ausgegeben wird. Tokenizer
Lesen von Zeichen • get0/1 liest ein Zeichen vom Standard-Input und verschiebt den Lesezeiger um eine Position (ein Byte) nach rechts. • Das Argument ist ein ASCII-Symbol 0..255. • Aufruf erfolgt meist mit einer Variablen. • Kein erneutes Lesen desselben Zeichens. Tokenizer
Lesen eines Bytes: byte/1 % byte(-Char) byte(X):- % read a byte from the input stream get0(Y), % get one byte byte(Y,X), !. % transduce byte byte(eof). % get0/1 fails at the end of file % byte(+InputChar, -OutputChar) byte(13,eoln):- get0(10), !. % end of line (CR+LF)- (DOS-)Files byte(13,eoln):- !. % end of line (CR)- console (+UNIX) byte(X,32):- X < 32, !. % other control chars become blanks byte(X,X). % catch all: leave it as is Tokenizer
Lesen einer Zeile: readln/1 % readln: read one line from the input stream % readln(-ASCII_List) readln(ASCII):- % read one line byte(X), % read one byte X \= eof, !, % fail at the end of file readln(X,ASCII). % first arg used for termination readln(eof). % end of file % readln(+Char, -ASCII_List) readln(eoln,[]):- !. % termination 1: end of line readln(eof,[]):- !. % termination 2: end of file readln(X,[X|T]):- % add byte X to the line buffer byte(Y), % read the next byte readln(Y,T). % read the rest of the current line Tokenizer
Tokenizing einer Zeile % tokenize_line(+ASCII_List, -TokenList) tokenize_line(eof,[eof]):- !. % termination 1: end of file tokenize_line( [], []):- !. % termination 2: end of line tokenize_line(ASCII,[T|Ts]):- % tokenize ASCII list token(T,ASCII,Rest), !, % call to DCG to get one token tokenize_line(Rest,Ts). % tokenize rest of ASCII list Tokenizer
Verarbeitung von Tokens % token(-Token, +[Token|Tokens], -Tokens) token(T) --> o(T). % operators token(T) --> b(T). % blanks token(T) --> i(T). % integers token(T) --> l(T). % lower case strings token(T) --> u(T). % upper case strings token(T) --> s(T). % unrestricted strings Tokenizer
Sonderzeichen (Operatoren) o(o(SO)) --> [AO], {op(AO), list_text([AO],SO)}. op(`^). op(`!). op(`"). op(`$). op(`%). op(`&). op(`/). op(`(). op(`)). op(`=). op(`\). op(`{). op(`}). op(`[). op(`]). op(`<). op(`>). op(`|). op(`+). op(`*). op(`~). op(`#). op(`,). op(`.). op(`;). op(`:). op(`-). op(``). op(`'). op(`@). Tokenizer
Leerzeichen % blanks b(b(B)) --> blank(B1), blanks(B2), {B is B1+B2}. blank(T) --> [9], {tabsize(T)}. % tabulator blank(1) --> [32]. % space blanks(N)--> blank(N1), blanks(N2), {N is N1+N2}. blanks(0)--> []. tabsize(8). Tokenizer
Integers % integers i(i(I)) --> digit(I1), digits(I2), {name(I,[I1|I2])}. digit(I) --> [I], {I > 47, I < 58}. digits([I|Is]) --> digit(I), digits(Is). digits([]) --> []. Tokenizer
Strings % lower case string l(l(LS)) --> lc(LC), str(S), {list_text([LC|S],LS)}. % upper case string u(u(US)) --> uc(UC), str(S), {list_text([UC|S],US)}. % unrestricted string s(s(S)) --> c(C), str(Str), {list_text([C|Str],S)}. % string continuation str([C|S]) --> c(C), str(S). str([]) --> []. % char c(C) --> [C], {C > 32, not op(C)}. % lower case char lc(LC) --> [LC], {LC > 96, LC < 123}. % upper case char uc(UC) --> [UC], {UC > 64, UC < 91}. Tokenizer
Top-Level-Prädikat 1 % tokenize_file(+InputFile, +OutputFile) tokenize_file(I,O):- assert(tokenizer_mode(file_output)), % Two modes: file or database output. tell(O), tokenize_file(I), !, told. tokenize_file(_,_):- told. Tokenizer
Top-Level-Prädikat 2 % tokenize_file(+InputFile) tokenize_file(F):- reset_tokenizer, see(F), tokenize_file, !, seen. tokenize_file(_):- seen. reset_tokenizer:- abolish(cnt/1), abolish(line/2), !. Tokenizer
Main Loop: Repeat-Schleife % tokenize_file tokenize_file:- repeat, count(N), readln(ASCII), tokenize_line(ASCII,TokenList), tokenizer_output(line(N,TokenList)), ASCII = eof, !. Tokenizer
Output % tokenizer_output(+line(LineNumber, ListOfTokens)) tokenizer_output(T):- retract(tokenizer_mode(file_output)), !, writeq(T), put(`.), nl. tokenizer_output(T):- assert(T), !. Tokenizer
Literatur • O‘Keefe, Richard A. (1990): The Craft of Prolog. Chap. 10: Writing Tokenizers in Prolog. MIT Press. Tokenizer