Tokenizer Prolog Aufbaukurs SS 2000 Heinrich-Heine-Universität Düsseldorf Christof Rumpf
Tokenizer2 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.
Tokenizer3 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.
Tokenizer4 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.
Tokenizer5 Klassen von Zeichen ASCII-Code: 1 Byte = 8 Bit = 256 Zeichen Buchstaben a.. z, A.. Z, ä, ö, ü, ß,... Ziffern Sonderzeichen.,;:+-#`´%&... White Space: Leerzeichen und Tabulator Steuerzeichen: Zeilenvorschub, EOF,...
Tokenizer6 Klassen von Tokens Wörter aus Buchstaben Zahlen aus Ziffern Operatoren aus Sonderzeichen Eventuell White Space als Token Andere...
Tokenizer7 Input und Output Input –Tastatur –Datei –Programm Streams DDE OLE... Output –Bildschirm –Drucker –Datei –Programm...
Tokenizer8 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.
Tokenizer9 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.
Tokenizer10 Schreib- Lesezeiger ?- 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.
Tokenizer11 Muster für Ein- Ausgabeprädikate 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).
Tokenizer12 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.
Tokenizer13 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 Aufruf erfolgt meist mit einer Variablen. Kein erneutes Lesen desselben Zeichens.
Tokenizer14 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
Tokenizer15 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
Tokenizer16 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
Tokenizer17 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
Tokenizer18 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(`').
Tokenizer19 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).
Tokenizer20 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([]) --> [].
Tokenizer21 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}.
Tokenizer22 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.
Tokenizer23 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), !.
Tokenizer24 Main Loop: Repeat-Schleife % tokenize_file tokenize_file:- repeat, count(N), readln(ASCII), tokenize_line(ASCII,TokenList), tokenizer_output(line(N,TokenList)), ASCII = eof, !.
Tokenizer25 Output % tokenizer_output(+line(LineNumber, ListOfTokens)) tokenizer_output(T):- retract(tokenizer_mode(file_output)), !, writeq(T), put(`.), nl. tokenizer_output(T):- assert(T), !.
Tokenizer26 Literatur OKeefe, Richard A. (1990): The Craft of Prolog. Chap. 10: Writing Tokenizers in Prolog. MIT Press.