tokenizer prolog aufbaukurs ss 2000 heinrich-heine-universität düsseldorf christof rumpf
TRANSCRIPT
TokenizerProlog Aufbaukurs SS 2000
Heinrich-Heine-Universität Düsseldorf
Christof Rumpf
10.04.2000 Tokenizer 2
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.
10.04.2000 Tokenizer 3
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.
10.04.2000 Tokenizer 4
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.
10.04.2000 Tokenizer 5
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, ...
10.04.2000 Tokenizer 6
Klassen von Tokens
• Wörter aus Buchstaben
• Zahlen aus Ziffern
• Operatoren aus Sonderzeichen
• Eventuell White Space als Token
• Andere ...
10.04.2000 Tokenizer 7
Input und Output
• Input– Tastatur– Datei– Programm
• Streams
• DDE
• OLE
• ...
• Output– Bildschirm– Drucker– Datei– Programm
• ...
10.04.2000 Tokenizer 8
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.
10.04.2000 Tokenizer 9
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.
10.04.2000 Tokenizer 10
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.
10.04.2000 Tokenizer 11
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).
10.04.2000 Tokenizer 12
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.
10.04.2000 Tokenizer 13
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.
10.04.2000 Tokenizer 14
Lesen eines Bytes: byte/1
% byte(-Char)
byte(X):- % read a byte from the input streamget0(Y), % get one bytebyte(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 blanksbyte(X,X). % catch all: leave it as is
10.04.2000 Tokenizer 15
Lesen einer Zeile: readln/1
% readln: read one line from the input stream
% readln(-ASCII_List)
readln(ASCII):- % read one linebyte(X), % read one byteX \= eof, !, % fail at the end of filereadln(X,ASCII). % first arg used for termination
readln(eof). % end of file
% readln(+Char, -ASCII_List)
readln(eoln,[]):- !. % termination 1: end of linereadln(eof,[]):- !. % termination 2: end of filereadln(X,[X|T]):- % add byte X to the line buffer
byte(Y), % read the next bytereadln(Y,T). % read the rest of the current line
10.04.2000 Tokenizer 16
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 listtoken(T,ASCII,Rest), !, % call to DCG to get one tokentokenize_line(Rest,Ts). % tokenize rest of ASCII list
10.04.2000 Tokenizer 17
Verarbeitung von Tokens
% token(-Token, +[Token|Tokens], -Tokens)
token(T) --> o(T). % operatorstoken(T) --> b(T). % blankstoken(T) --> i(T). % integerstoken(T) --> l(T). % lower case stringstoken(T) --> u(T). % upper case stringstoken(T) --> s(T). % unrestricted strings
10.04.2000 Tokenizer 18
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(`@).
10.04.2000 Tokenizer 19
Leerzeichen
% blanks b(b(B)) --> blank(B1), blanks(B2), {B is B1+B2}. blank(T) --> [9], {tabsize(T)}. % tabulatorblank(1) --> [32]. % space blanks(N)--> blank(N1), blanks(N2), {N is N1+N2}.blanks(0)--> [].
tabsize(8).
10.04.2000 Tokenizer 20
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([]) --> [].
10.04.2000 Tokenizer 21
Strings
% lower case stringl(l(LS)) --> lc(LC), str(S), {list_text([LC|S],LS)}.% upper case stringu(u(US)) --> uc(UC), str(S), {list_text([UC|S],US)}.% unrestricted strings(s(S)) --> c(C), str(Str), {list_text([C|Str],S)}.% string continuationstr([C|S]) --> c(C), str(S).str([]) --> [].% char c(C) --> [C], {C > 32, not op(C)}.% lower case charlc(LC) --> [LC], {LC > 96, LC < 123}.% upper case charuc(UC) --> [UC], {UC > 64, UC < 91}.
10.04.2000 Tokenizer 22
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.
10.04.2000 Tokenizer 23
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), !.
10.04.2000 Tokenizer 24
Main Loop: Repeat-Schleife
% tokenize_file tokenize_file:-
repeat,count(N),readln(ASCII),tokenize_line(ASCII,TokenList),tokenizer_output(line(N,TokenList)),ASCII = eof,!.
10.04.2000 Tokenizer 25
Output
% tokenizer_output(+line(LineNumber, ListOfTokens)) tokenizer_output(T):-
retract(tokenizer_mode(file_output)), !,writeq(T), put(`.), nl.
tokenizer_output(T):- assert(T), !.
10.04.2000 Tokenizer 26
Literatur
• O‘Keefe, Richard A. (1990): The Craft of Prolog. Chap. 10: Writing Tokenizers in Prolog. MIT Press.