DCG Grammatiken
DCGs und Phrasenstrukturgrammatiken
Parsing mit dem Suchalgorithmus von Prolog
Benutzen von Variablen um Constraints zu sichern Rückgabe des Parsebaums
Andere Anwendungen von DCGs
DCGs und Phrasenstrukturgrammatiken
Parsing mit dem Suchalgorithmus von Prolog
Benutzen von Variablen um Constraints zu sichern Rückgabe des Parsebaums
Andere Anwendungen von DCGs
Prolog und Sprachverarbeitung
DCG Notation ist ein Feature von Prolog, das es uns erlaubt, Phrasenstrukturgrammatiken direkt in Prolog zu schreiben.
Prolog war von Beginn an auf Sprachverarbeitung ausgerichtet.
Built-in Such- und Unifikationsmechanismen konnten direkt für das in den 70er und 80er Jahren herrschende Paradigma der
Sprachverarbeitung eingesetzt werden.
Top-down Parsing= Suche im Standardformalismus von Prolog.
Kein zusätzliches Programm notwendig.
DCG Notation ist ein Feature von Prolog, das es uns erlaubt, Phrasenstrukturgrammatiken direkt in Prolog zu schreiben.
Prolog war von Beginn an auf Sprachverarbeitung ausgerichtet.
Built-in Such- und Unifikationsmechanismen konnten direkt für das in den 70er und 80er Jahren herrschende Paradigma der
Sprachverarbeitung eingesetzt werden.
Top-down Parsing= Suche im Standardformalismus von Prolog.
Kein zusätzliches Programm notwendig.
Phrasenstrukturgrammatik
Syntactic Structures von Chomsky (1957) hat das Prinzip der Konstituentengrammatik eingeführt.
Trivialisierte Definition: Worte die zusammenpassen und als relativ unabhängige syntaktische Einheiten funktionieren.
The waiter brought the meal.
The waiter brought the meal to the table.
The waiter brought the meal of the day.
Syntactic Structures von Chomsky (1957) hat das Prinzip der Konstituentengrammatik eingeführt.
Trivialisierte Definition: Worte die zusammenpassen und als relativ unabhängige syntaktische Einheiten funktionieren.
The waiter brought the meal.
The waiter brought the meal to the table.
The waiter brought the meal of the day.
Phrasenstrukturgrammatik
the waiter brought the meal to the tablebrought the meal to the table
Konstituentenstruktur besteht aus natürlichen Einheiten. Die Konstituenten werden um ein "Headword" herum organisiert welches normalerweise den wichtigsten
semantischen Inhalt trägt. Die Konstituentenstruktur wird nach Part-of-Speech des Headwords benannt.
the waiter: Nominalphrase=np
Phrasenstrukturgrammatik
Baumdarstellung: alternative Repräsentation der Konstituentenstrukturen
s repräsentiert den ganzen Satz und hat den Topknoten. S verzweigt in einfachen Grammatiken zunächst in np und vp
s
np vp
det n v np pp
det n prep np det n
the waiter brought the meal to the table Baumdarstellung: alternative Repräsentation der Konstituentenstrukturen
s repräsentiert den ganzen Satz und hat den Topknoten. S verzweigt in einfachen Grammatiken zunächst in np und vp
s
np vp
det n v np pp
det n prep np det n
the waiter brought the meal to the table
Phrasenstrukturgrammatiken
Phrasenstrukturregeln sind ein Mechanismus, um
Konstituentenstrukturen zu modellieren. PS-Regeln beschreiben Sätze oder Phrasen mit einer Sequenz einfacherer Phrasen.
Eine PS-Regel hat eine linke Seite, die das Elternsymbol darstellt und eine rechte Seite, die mit einem oder mehreren Symbolen die abwärts verbundenen Knoten darstellt (abwärts in der Baumstruktur).
s → np,vp beschreibt den Wurzelknoten. Ein Satz kann aus einer Nominalphrase und einer Verbalphrase bestehen.
Eine Phrasenstrukturgrammatik dekonstruiert Satzphrasen bis hinunter zu den Wörtern = Terminalsymbole.
Phrasenstrukturregeln sind ein Mechanismus, um
Konstituentenstrukturen zu modellieren. PS-Regeln beschreiben Sätze oder Phrasen mit einer Sequenz einfacherer Phrasen.
Eine PS-Regel hat eine linke Seite, die das Elternsymbol darstellt und eine rechte Seite, die mit einem oder mehreren Symbolen die abwärts verbundenen Knoten darstellt (abwärts in der Baumstruktur).
s → np,vp beschreibt den Wurzelknoten. Ein Satz kann aus einer Nominalphrase und einer Verbalphrase bestehen.
Eine Phrasenstrukturgrammatik dekonstruiert Satzphrasen bis hinunter zu den Wörtern = Terminalsymbole.
Phrasenstrukturgrammatiken
PSG beschreibt also vollständige Bäume bis hinunter zu den Blättern
= Wörter = Terminalsymbole
s → np vp det → the
np → det n n → waiter
np → np pp n → table n → meal vp → v np v → brought
pp → p np
p → to
PSG beschreibt also vollständige Bäume bis hinunter zu den Blättern
= Wörter = Terminalsymbole
s → np vp det → the
np → det n n → waiter
np → np pp n → table n → meal vp → v np v → brought
pp → p np
p → to
DCG Grammatiken
DCG ist ein Proglogmechanismus, der es erlaubt
Phrasenstrukturregeln 1:1 in Prologklauseln zu übersetzen s --> np, vp. det --> [the].
np --> det, n. n --> [waiter].
np --> np, pp. n --> [table].
n --> [meal].
vp --> v, np. v --> [brought].
pp --> p, np.
p --> [to].
DCG ist ein Proglogmechanismus, der es erlaubt
Phrasenstrukturregeln 1:1 in Prologklauseln zu übersetzen s --> np, vp. det --> [the].
np --> det, n. n --> [waiter].
np --> np, pp. n --> [table].
n --> [meal].
vp --> v, np. v --> [brought].
pp --> p, np.
p --> [to].
DCG Suchmechanismus
Der interne Suchalgorithmus von Prolog untersucht ob ein Fakt wahr ist oder generiert eine Lösung für eine Zielliste bzw. alle Lösungen wenn Backtracking nach erfolgreicher Lösung erzwungen wird.
Angewandt auf das Parsingproblem: die Suche verifiziert, ob ein Satz [= Wortliste] von der gegebenen Grammatik
[=Prologprogramm] akzeptiert wird.
Sprachgenerierung: zugleich kann Prolog, bei Eingabe des Satzes als Variabler, dazu benutzt werden, alle Sätze zu generieren, die durch dies Grammatik akzeptiert werden [=für das im Programm definierte Vokabular]
Der interne Suchalgorithmus von Prolog untersucht ob ein Fakt wahr ist oder generiert eine Lösung für eine Zielliste bzw. alle Lösungen wenn Backtracking nach erfolgreicher Lösung erzwungen wird.
Angewandt auf das Parsingproblem: die Suche verifiziert, ob ein Satz [= Wortliste] von der gegebenen Grammatik
[=Prologprogramm] akzeptiert wird.
Sprachgenerierung: zugleich kann Prolog, bei Eingabe des Satzes als Variabler, dazu benutzt werden, alle Sätze zu generieren, die durch dies Grammatik akzeptiert werden [=für das im Programm definierte Vokabular]
DCG Suchmechanismus
Wenn der Prolog-Interpreter die DCG Regeln geladen hat (consulted) können wir die Grammatik befragen, indem wir eine
Eingabewortliste und die leere List als Eingabeparameter übergeben:
Sätze akzeptieren.
?- s([the,waiter,brought,the,meal,to,the,table],[]).
yes.
Sätze generieren.
?- s(L,[]).
L=[the,waiter,brought,the,meal,to,the,table]; ...
Wenn der Prolog-Interpreter die DCG Regeln geladen hat (consulted) können wir die Grammatik befragen, indem wir eine
Eingabewortliste und die leere List als Eingabeparameter übergeben:
Sätze akzeptieren.
?- s([the,waiter,brought,the,meal,to,the,table],[]).
yes.
Sätze generieren.
?- s(L,[]).
L=[the,waiter,brought,the,meal,to,the,table]; ...
DCG Suchmechanismus
Trace der Anfrage zum Akzeptieren.
s([the,waiter,brought,the,meal],[]).
Call: (6) s([the, waiter, brought, the, meal], []) ? creep
Call: (7) np([the, waiter, brought, the, meal], _G449) ? creep Call: (8) det([the, waiter, brought, the, meal], _G449) ? creep
Exit: (8) det([the, waiter, brought, the, meal], [waiter, brought, the, meal]) ? creep Call: (8) n([waiter, brought, the, meal], _G449) ? creep
Exit: (8) n([waiter, brought, the, meal], [brought, the, meal]) ? creep
Exit: (7) np([the, waiter, brought, the, meal], [brought, the, meal]) ? creep Call: (7) vp([brought, the, meal], []) ? creep
Call: (8) v([brought, the, meal], _G449) ? creep Exit: (8) v([brought, the, meal], [the, meal]) ? creep Call: (8) np([the, meal], []) ? creep
Call: (9) det([the, meal], _G449) ? creep Exit: (9) det([the, meal], [meal]) ? creep Call: (9) n([meal], []) ? creep
Exit: (9) n([meal], []) ? creep
Exit: (8) np([the, meal], []) ? creep
Exit: (7) vp([brought, the, meal], []) ? creep
Exit: (6) s([the, waiter, brought, the, meal], []) ? creep true .
Trace der Anfrage zum Akzeptieren.
s([the,waiter,brought,the,meal],[]).
Call: (6) s([the, waiter, brought, the, meal], []) ? creep
Call: (7) np([the, waiter, brought, the, meal], _G449) ? creep Call: (8) det([the, waiter, brought, the, meal], _G449) ? creep
Exit: (8) det([the, waiter, brought, the, meal], [waiter, brought, the, meal]) ? creep Call: (8) n([waiter, brought, the, meal], _G449) ? creep
Exit: (8) n([waiter, brought, the, meal], [brought, the, meal]) ? creep
Exit: (7) np([the, waiter, brought, the, meal], [brought, the, meal]) ? creep Call: (7) vp([brought, the, meal], []) ? creep
Call: (8) v([brought, the, meal], _G449) ? creep Exit: (8) v([brought, the, meal], [the, meal]) ? creep Call: (8) np([the, meal], []) ? creep
Call: (9) det([the, meal], _G449) ? creep Exit: (9) det([the, meal], [meal]) ? creep Call: (9) n([meal], []) ? creep
Exit: (9) n([meal], []) ? creep
Exit: (8) np([the, meal], []) ? creep
Exit: (7) vp([brought, the, meal], []) ? creep
Exit: (6) s([the, waiter, brought, the, meal], []) ? creep true .
DCG Suchmechanismus
Generieren von Sätzen:
L = [the, waiter, brought, the, waiter] ; L = [the, waiter, brought, the, table] ; L = [the, waiter, brought, the, meal] ;
L = [the, waiter, brought, the, waiter, to, the, waiter] ; L = [the, waiter, brought, the, waiter, to, the, table] ; L = [the, waiter, brought, the, waiter, to, the, meal] ; Achtung hier Linksrekursion..
L = [the, waiter, brought, the, waiter, to, the, waiter, to|...] ; Generieren von Sätzen:
L = [the, waiter, brought, the, waiter] ; L = [the, waiter, brought, the, table] ; L = [the, waiter, brought, the, meal] ;
L = [the, waiter, brought, the, waiter, to, the, waiter] ; L = [the, waiter, brought, the, waiter, to, the, table] ; L = [the, waiter, brought, the, waiter, to, the, meal] ; Achtung hier Linksrekursion..
L = [the, waiter, brought, the, waiter, to, the, waiter, to|...] ;
DCG Schreibweisen
Terminale = Lexikoneinträge können aus mehreren Token bestehen.
Listenschreibweise:
p --> [in,front,of].
Ein Mix von Terminalen und Non-Terminalen innerhalb einer Klausel ist möglich.
np --> n, [and], n.
Ein Mix von Prologklauseln und DCG Regeln innerhalb einer Klausel ist möglich. DCG Regeln können also Prologziele in der Regelexpansion (=rechte Seite) enthalten. Diese Ziele werden in
geschweifte Klammern geschrieben und dienen z.B. dazu Constraints abzusichern oder können zum Debugging benutzt werden.
np --> n, [and],n, {write('I found two nouns')}.
Terminale = Lexikoneinträge können aus mehreren Token bestehen.
Listenschreibweise:
p --> [in,front,of].
Ein Mix von Terminalen und Non-Terminalen innerhalb einer Klausel ist möglich.
np --> n, [and], n.
Ein Mix von Prologklauseln und DCG Regeln innerhalb einer Klausel ist möglich. DCG Regeln können also Prologziele in der Regelexpansion (=rechte Seite) enthalten. Diese Ziele werden in
geschweifte Klammern geschrieben und dienen z.B. dazu Constraints abzusichern oder können zum Debugging benutzt werden.
np --> n, [and],n, {write('I found two nouns')}.
Interne Darstellung der DCGs
DCG Regeln in Prolog wie s --> np,vp.
werden repräsentiert als:
s(L1,L) :- np(L1,L2), vp(L2,L).
DCG: eine Konstituente, die mit dem Kopf der Regel matcht wird in Subkonstituenten zerlegt, die mit den Goals der rechten Regelseite matchen.
Intern: Konstituenten korrespondieren mit der Differenz des Argumentpaars (was sind die Argumente: Listen!).
[the, waiter, brought the, meal] unifiziert mit L1-L als s [the,waiter] mit L1-L2 als np
[brought, the, meal] mit L2 - L als vp DCG Regeln in Prolog wie
s --> np,vp.
werden repräsentiert als:
s(L1,L) :- np(L1,L2), vp(L2,L).
DCG: eine Konstituente, die mit dem Kopf der Regel matcht wird in Subkonstituenten zerlegt, die mit den Goals der rechten Regelseite matchen.
Intern: Konstituenten korrespondieren mit der Differenz des Argumentpaars (was sind die Argumente: Listen!).
[the, waiter, brought the, meal] unifiziert mit L1-L als s [the,waiter] mit L1-L2 als np
[brought, the, meal] mit L2 - L als vp
Interne Darstellung der DCGs
Lexikalische Regeln wie det --> [the] werden als det([the|L],L) repräsentiert.
Viele Prologimplementationen enthalten ein expand/2 Prädikat, das DCG Regeln in Prologregeln übersetzt.
Lexikalische Regeln wie det --> [the] werden als det([the|L],L) repräsentiert.
Viele Prologimplementationen enthalten ein expand/2 Prädikat, das DCG Regeln in Prologregeln übersetzt.
Parsen und Generierung mit DCGs
DCG Parsing korrespondiert mit Prologs interner top-down-Suche.
Startend von s: s wird in subgoals zerlegt, hier np,vp
startet rewrite Prozess mit np und geht herunter bis die Input-Wörter mit dem Vokabular der Prolog Programms matchen!
Wenn Prolog keine Lösung findet: backtracking und versuchen alternativer Regeln.
Effizienzproblem: u.U. werden lauter komplizierte Bäume aufgebaut, bis Prolog unten merkt, dass die Terminale nicht matchen oder aber bestimmte Constraints nicht gesichert sind.
DCG Parsing korrespondiert mit Prologs interner top-down-Suche.
Startend von s: s wird in subgoals zerlegt, hier np,vp
startet rewrite Prozess mit np und geht herunter bis die Input-Wörter mit dem Vokabular der Prolog Programms matchen!
Wenn Prolog keine Lösung findet: backtracking und versuchen alternativer Regeln.
Effizienzproblem: u.U. werden lauter komplizierte Bäume aufgebaut, bis Prolog unten merkt, dass die Terminale nicht matchen oder aber bestimmte Constraints nicht gesichert sind.
Parsen und Generierung mit DCGs
Linksrekursive Regeln
Haben gesehen, dass unsere kleine DCG-Grammatik grammatische Sätze akzeptiert und generiert. Was ist mit den nicht-grammatischen?
the brought the meal*
kommt nie mehr zurück, warum?
np --> det, n.
np --> np,pp.
Die erste np Regel scheitert, da nach dem Determinator kein Nomen folgt. Also wird die zweite Regel angewandt. Linksrekursiv wird
erneut np aufgerufen: scheitert wieder in der ersten Regel usw.
Linksrekursive Regeln
Haben gesehen, dass unsere kleine DCG-Grammatik grammatische Sätze akzeptiert und generiert. Was ist mit den nicht-grammatischen?
the brought the meal*
kommt nie mehr zurück, warum?
np --> det, n.
np --> np,pp.
Die erste np Regel scheitert, da nach dem Determinator kein Nomen folgt. Also wird die zweite Regel angewandt. Linksrekursiv wird
erneut np aufgerufen: scheitert wieder in der ersten Regel usw.
Parsen und Generierung mit DCGs
Linksrekursive Regeln
Standardlösung: benutze eine Hilfsregel mit einem Hilfssymbol, das nicht linksrekursiv ist.
ngroup --> det, n.
np --> ngroup.
np --> ngroup, pp.
Für eine Grammatik ohne linksrekursive Regeln gilt: jeder Satz, der nicht durch die Grammatik akzeptiert wird, führt zu fail
Linksrekursive Regeln
Standardlösung: benutze eine Hilfsregel mit einem Hilfssymbol, das nicht linksrekursiv ist.
ngroup --> det, n.
np --> ngroup.
np --> ngroup, pp.
Für eine Grammatik ohne linksrekursive Regeln gilt: jeder Satz, der nicht durch die Grammatik akzeptiert wird, führt zu fail
Benutzen von Variablen in DCGs
(1) Variablen in DCG Grammatiken können benutzt werden, um Bedingungen zu implementieren, die auf den Wörtern einer
akzeptierten Phrase bestimmte grammatische Features absichern.
Beispiel Kongruenz: Numerus, Genus, Kasus in Nominalphrasen Beispiel Valenz: Verb steht allein (intransitiv) oder muss durch bestimmte np(s) ergänzt werden
(2) Variablen in DCG Grammatiken werden benutzt, um das Resultat eines Parsevorgangs zu erhalten = Parsebaum
(1) Variablen in DCG Grammatiken können benutzt werden, um Bedingungen zu implementieren, die auf den Wörtern einer
akzeptierten Phrase bestimmte grammatische Features absichern.
Beispiel Kongruenz: Numerus, Genus, Kasus in Nominalphrasen Beispiel Valenz: Verb steht allein (intransitiv) oder muss durch bestimmte np(s) ergänzt werden
(2) Variablen in DCG Grammatiken werden benutzt, um das Resultat eines Parsevorgangs zu erhalten = Parsebaum
Benutzen von Variablen in DCGs
DCG Variablen werden in der internen Repräsentation der DCG Regeln vor den beiden Listenvariablen gehalten.
np(X,Y,Z) --> det(X), n(Y).
expand/2
np(X,Y,Z,L1,L) :- det(X,L1,L2), n(Y,L2,L).
DCG Variablen werden in der internen Repräsentation der DCG Regeln vor den beiden Listenvariablen gehalten.
np(X,Y,Z) --> det(X), n(Y).
expand/2
np(X,Y,Z,L1,L) :- det(X,L1,L2), n(Y,L2,L).
Benutzen von Variablen in DCGs
Implementation Kongruenz = Übereinstimmung von Genus, Numerus und Kasus:
np(Genus,Numerus,Kasus) --> det(Genus,Numerus,Kasus), n(Genus,Numerus,Kasus).
Konsequent:
det(mask,sing,nominativ ) --> [der].
det(mask,sing,) --> [des].
det(mask,sing,dativ) --> [dem].
det(mask,sing,akkusativ) --> [den].
%
det(fem,sing,nominativ) --> [die].
n(mask,sing,nominativ) --> [ober].
n(mask,sing,genitiv) --> [obers].
Implementation Kongruenz = Übereinstimmung von Genus, Numerus und Kasus:
np(Genus,Numerus,Kasus) --> det(Genus,Numerus,Kasus), n(Genus,Numerus,Kasus).
Konsequent:
det(mask,sing,nominativ ) --> [der].
det(mask,sing,) --> [des].
det(mask,sing,dativ) --> [dem].
det(mask,sing,akkusativ) --> [den].
%
det(fem,sing,nominativ) --> [die].
n(mask,sing,nominativ) --> [ober].
n(mask,sing,genitiv) --> [obers].
Benutzen von Variablen in DCGs
Parsebaum zurückgeben: the waiter brought the meal
Baum = s(np(det(the),n(waiter)),vp(v(brought),np(det(the),n(meal)))) Idee um dieses erwartete Ergebnis zu bekommen ist: hänge ein
Argument an alle Regelsymbole an, wobei jedes Regelsymbol einen partiellen Parsebaum für das korrespondierende Symbol enthält. Auf der rechten Seite hat jedes Goal eine Variable, um die Struktur zu speichern, die es parst.
Parsebaum zurückgeben: the waiter brought the meal
Baum = s(np(det(the),n(waiter)),vp(v(brought),np(det(the),n(meal)))) Idee um dieses erwartete Ergebnis zu bekommen ist: hänge ein
Argument an alle Regelsymbole an, wobei jedes Regelsymbol einen partiellen Parsebaum für das korrespondierende Symbol enthält. Auf der rechten Seite hat jedes Goal eine Variable, um die Struktur zu speichern, die es parst.
Benutzen von Variablen in DCGs
Baum = s(np(det(the),n(waiter)),vp(v(brought),np(det(the),n(meal)))) s --> np,vp wird zu
s(s(NP,VP)) --> np(NP),vp(VP).
np --> det,n wird zu
np(np(D,N)) --> det(D), n(N).
vp --> v,np wird zu
vp(vp(V,NP)) --> v(V), np(NP).
Terminalebene:
det --> [the] wird zu det(det(the)) --> [the].
n(n(waiter)) --> [waiter].
Baum = s(np(det(the),n(waiter)),vp(v(brought),np(det(the),n(meal)))) s --> np,vp wird zu
s(s(NP,VP)) --> np(NP),vp(VP).
np --> det,n wird zu
np(np(D,N)) --> det(D), n(N).
vp --> v,np wird zu
vp(vp(V,NP)) --> v(V), np(NP).
Terminalebene:
det --> [the] wird zu det(det(the)) --> [the].
n(n(waiter)) --> [waiter].
Anwendugnsbeispiel DCG:
Tokenisierung
Wortsegmentierung: nimmt eine Zeichenliste als Input und bricht
diese in Token. Beginnen mit Regeln, die eine Tokensequenz mithilfe von Blanks definiert.
Blanks: white space, Newline, Tabulatoren oder Kontrollzeichen.
Token ist eine Sequenz alphanumerischer Zeichen oder anderer
Zeichen. Alphanumerische sind: Ziffern und Buchstaben hier nur aus dem ISO-Latin-set.
Tokenizer Aus Nugues Piere, M. In Introduction to Language Processing with Perl and Prolog, Springer 2006
Wortsegmentierung: nimmt eine Zeichenliste als Input und bricht
diese in Token. Beginnen mit Regeln, die eine Tokensequenz mithilfe von Blanks definiert.
Blanks: white space, Newline, Tabulatoren oder Kontrollzeichen.
Token ist eine Sequenz alphanumerischer Zeichen oder anderer
Zeichen. Alphanumerische sind: Ziffern und Buchstaben hier nur aus dem ISO-Latin-set.
Tokenizer Aus Nugues Piere, M. In Introduction to Language Processing with Perl and Prolog, Springer 2006
Anwendugnsbeispiel DCG:
Tokenisierung
tokens(Tokens) --> blank,{!},tokens(Tokens).
tokens([FirstT|Tokens]) --> token(FirstT),{!}, tokens(Tokens).
tokens([ ]) --> [ ].
% blank als Whitespace oder Kontrollzeichen blank --> [B],{B=< 32,!}.
% Token also Sequenz alphanumerischer Zeichen oder ein anderes
%Symbol
token(Word) --> alphanumerics(List), {name(Word,List),!}.
token(Symbol) --> other(CSymbol), {name(Symbol, [CSymbol]),!}.
tokens(Tokens) --> blank,{!},tokens(Tokens).
tokens([FirstT|Tokens]) --> token(FirstT),{!}, tokens(Tokens).
tokens([ ]) --> [ ].
% blank als Whitespace oder Kontrollzeichen blank --> [B],{B=< 32,!}.
% Token also Sequenz alphanumerischer Zeichen oder ein anderes
%Symbol
token(Word) --> alphanumerics(List), {name(Word,List),!}.
token(Symbol) --> other(CSymbol), {name(Symbol, [CSymbol]),!}.
Anwendugnsbeispiel DCG:
Tokenisierung
%Sequenz von alphanumerischen Zeichen ist ein alphanumerisches
%Zeichen, gefolgt von einem Rest von alphanumerischen Zeichen
%oder einem einzelnen.
alphanumerics([L|LS]) --> alphanumeric(L), alphanumerics(LS).
alphanumerics([L]) --> alphanumeric(L).
%Ziffern: alphanumeric(D) --> [D], {48 =< D, D =< 57,!}.
%Buchstaben: alphanumeric(L) --> [L], {65 =< L, L =< 90,!}.
alphanumeric(L) --> [L], {97 =< L, L =< 122,!}.
%Other: other(Symbol) --> [Symbol],{!}.
%file einlesen und aufrufen
?- read_file(myFile,CharList), tokens(TokenList,CharList,[]).
%Sequenz von alphanumerischen Zeichen ist ein alphanumerisches
%Zeichen, gefolgt von einem Rest von alphanumerischen Zeichen
%oder einem einzelnen.
alphanumerics([L|LS]) --> alphanumeric(L), alphanumerics(LS).
alphanumerics([L]) --> alphanumeric(L).
%Ziffern: alphanumeric(D) --> [D], {48 =< D, D =< 57,!}.
%Buchstaben: alphanumeric(L) --> [L], {65 =< L, L =< 90,!}.
alphanumeric(L) --> [L], {97 =< L, L =< 122,!}.
%Other: other(Symbol) --> [Symbol],{!}.
%file einlesen und aufrufen
?- read_file(myFile,CharList), tokens(TokenList,CharList,[]).
Anwendugnsbeispiel DCG:
Tokenisierung
%Zweiter Teil der Tokenisierung ist es Satzgrenzen zu erkennen
Nimmt TokenList als input SentenceList ist dann eine Wortliste, die einem Satz entspricht, gefolgt vom Rest der Sätze. Der letzte Satz kann ein Satz mit Punktuation sein, oder aber eine Reihe von
Wörtern ohne Punktuation.
Punktuation: .:;!?
%Zweiter Teil der Tokenisierung ist es Satzgrenzen zu erkennen
Nimmt TokenList als input SentenceList ist dann eine Wortliste, die einem Satz entspricht, gefolgt vom Rest der Sätze. Der letzte Satz kann ein Satz mit Punktuation sein, oder aber eine Reihe von
Wörtern ohne Punktuation.
Punktuation: .:;!?
Anwendugnsbeispiel DCG:
Tokenisierung
sentences([S|RS]) --> words_of_a_sentence(S), sentences(RS).
%letzter Satz mit Punktuation
sentences([S]) --> words_of_a_sentence(S).
%ohne
sentences([S]) --> words_without_punctuation(S).
words_of_a_sentence([P]) --> end_punctuation(P).
words_of_a_sentence([W|RS]) --> word(W),
words_of_a_sentence(RS).
words_without_punctuation(RS).
words_without_punctuation([W]) --> [W].
end_punctuation(P) --> [P],{end_punctuation(P),!}.
end_punctuation(P) :- member(P, ['.',';',':','!','?']).
word(W) -->[W].
sentences([S|RS]) --> words_of_a_sentence(S), sentences(RS).
%letzter Satz mit Punktuation
sentences([S]) --> words_of_a_sentence(S).
%ohne
sentences([S]) --> words_without_punctuation(S).
words_of_a_sentence([P]) --> end_punctuation(P).
words_of_a_sentence([W|RS]) --> word(W),
words_of_a_sentence(RS).
words_without_punctuation(RS).
words_without_punctuation([W]) --> [W].
end_punctuation(P) --> [P],{end_punctuation(P),!}.
end_punctuation(P) :- member(P, ['.',';',':','!','?']).
word(W) -->[W].
Anwendugnsbeispiel DCG:
Tokenisierung
Aufruf des gesamten DCG Tokenizing Programms:
?- read_file(myFile, CharacterList), tokens(TokenList,CharacterList,[]), sentences(SentenceList,TokenList,[]).
Aufruf des gesamten DCG Tokenizing Programms:
?- read_file(myFile, CharacterList), tokens(TokenList,CharacterList,[]), sentences(SentenceList,TokenList,[]).