Als Teil eines Projekts muss ich einen Parser schreiben, der eine Datei lesen und in Fakten analysieren kann, die ich in meinem Programm verwenden kann.
Die Dateistruktur sieht folgendermaßen aus:
%Vor%Was ich am Ende möchte, ist:
%Vor%Ich lese meine Datei so:
%Vor%Ich habe jetzt in mehreren Büchern und online über DCG gelesen, aber sie alle erklären die gleichen einfachen Beispiele, wo Sie Sätze wie "die Katze isst die Fledermaus" usw. generieren können ... Wenn ich es für das obige Beispiel verwenden möchte Ich versage kläglich.
Was ich geschafft habe, war das "Parsen" der unteren Zeile:
%Vor%bis
%Vor%mit diesem:
%Vor% Ich weiß nicht einmal, ob ich die dcg hier richtig benutze, also wäre jede Hilfe hier hilfreich. Nun, das Problem, das ich habe, ist, wie man das mit mehreren Elementen in meiner Liste macht und wie man mit '{' und '}' umgeht.
Was ich wirklich will, ist ein dcg, das mit diesen Arten von Sätzen umgehen kann (mit mehr als 2 Elementen):
Jetzt weiß ich, dass sich viele Leute hier auf die Bibliotheken dcg_basics und pio beziehen, wenn es um dcgs geht. Jedoch habe ich ein zusätzliches Problem, dass, wenn ich versuche, die Bibliothek zu verwenden, ich den Fehler empfange:
%Vor%wenn ich das tue:
%Vor%Zusätzliche Informationen:
Jegliche Hilfe dazu wäre willkommen!
BEARBEITEN: Ziel dieser Frage ist es, mehr über DCG und seine Verwendung in Parsern zu erfahren.
Solange Ihre Datei in einfacher Prolog-Syntax vorliegt, sollten Sie Prolog-Ausdruck IO verwenden. Vollständig strukturierte Begriffe werden mit einem einzelnen -Aufruf gelesen. Die Verwendung einer DCG ist komplizierter und ein wenig weniger effizient (nicht sicher hier, sollte messen, aber lesen (Term) ruft einen Prolog-Parser auf, der in C implementiert ist ...) Siehe dieses andere Question , die das gleiche Format verwendet (zumindest könnte man überprüfen, ob ein anderer Typ hier eine Antwort bekommen hat) auf SO über Ihre gleiche Aufgabe ...)
Bearbeiten nach Kommentaren ...
Sie haben Recht, dass DCG die richtige Möglichkeit ist, das allgemeine Parsen in Prolog zu behandeln. Argumente in DCG-Produktionen können als semantische Attribute betrachtet werden, daher kann die Programmierung von DCG als eine arbeitende semantische Analyse der Eingabe angesehen werden (siehe Attribut Grammar , eine wichtige Technik - auch im Bereich des Language Engineering).
Und tatsächlich können die vorgestellten Beispiele ohne die mit Term IO erforderlichen Hacks perfekt gelöst werden.
Hier ist es:
%Vor%damit haben wir
%Vor%Dank der Bibliothek (pureio ) können wir semantische Programmierung auf Prolog-Streams anwenden und werden mit dem gleichen Verhalten von Phrase / 2 belohnt.
mehr
Diese andere Antwort zeigt eine praktische Möglichkeit zur Implementierung eines Ausdrucksrechners mit Operatorauflösung und fauler Auswertung.
>Nun, der Zweck einer Hausaufgabenfrage ist zu lernen. Wenn Sie es mit einem DCG tun, werden Sie eine allgemein nützlichere Fertigkeit lernen als Pferdesportler.
Ich denke, Ihre Probleme sind weniger mit DCG's als mit String-Handhabung.
Sie haben eine Reihe von Stellen, an denen Sie univ (den Operator = ..) verwenden, um zwischen Listen und Strings zu konvertieren. Univ ist wahrscheinlich NICHT, was du hier willst. Univ vereinheitlicht einen Begriff mit einer Liste.
%Vor%Sie müssen wissen, dass eine Zeichenfolge in Prolog in verschiedenen Formen vorliegen kann Die Zeichenfolge 'hi Flores' könnte
sein'hi Flores' - das ist ein Atom - ein "fester Brocken" der Sache. Die einfachen Anführungszeichen werden für einige Zeichenfolgen nicht benötigt (siehe Ihr Buch), also ist hi_flores ein vollkommen gutes Atom ohne Anführungszeichen.
%Vor%in Ihrer Datei, so dass es "Hi Floris" im Debug ausgibt, nicht eine Reihe von Zahlen.
Es gibt auch eine Liste von Atomen mit einem Zeichen
[h, i, '', 'F', l, o, r, i, s]
aber Sie wollen diese wahrscheinlich nicht.
Sie könnten die SICSTUS-Kompatibilität pred read_line nützlich finden.
In einer DCG möchten Sie manchmal "Literale" - wörtlich das Ding - abgleichen. Wenn ja, lege das in eine Liste. Hier ist eine DCG für if-Anweisungen in einer vage VBish-Sprache
%Vor%Das wh ist überall ein optionaler Whitespace.
Nun können Sie für die Gesamtstrategie entweder Zeile für Zeile lesen oder die gesamte Datei einlesen. Verwenden Sie für eine Zeile read_line, die eine Liste mit Codes zurückgibt. read_file_to_codes wird die ganze Datei erhalten.
Wenn Sie die gesamte Dateistrategie verwenden und Zeilenumbrüche wichtig sind, müssen Sie sie offensichtlich aus der Whitespace-Definition entfernen.
Und all das führt natürlich zu der Frage, warum Fragen zu diesem Problem SO statt der Box des Lehrers überfluten.
Ich parse die Zeichenfolge in eine Liste und manipuliere dann die Liste. Mit DCG können Sie
konvertieren %Vor%bis
%Vor%Hinweis zu tun:
%Vor%Hier haben Sie zwei Muster, mit denen umzugehen ist: (L & gt; R) und {L, R}. Das wird nicht sehr kompliziert und wirklich leicht zu lesen sein.
IMHO, DCG Grammatikregeln sind ziemlich hässlich beim Tokenizing, ich wirklich Sache, DCG sollte nie für diese Aufgabe vorgeschlagen worden sein; der wirkliche Deal mit DCG ist das Parsen der Token, weil Prolog Symbolik verwendet, also kann ich sagen, dass die beste Option darin besteht, einen fremden Aufruf an einen, sagen wir C Tokenizer zu erstellen, der mit der einfachen Liste von Token vereinheitlicht und dann DCG lässt mach, wofür es war. Auf diese Weise ist die Implementierung sauberer und Sie müssen sich keine Sorgen machen, cr, Leerzeichen zu analysieren ...
Angenommen, Sie haben eine hypothetische Sprache mit einer Aussage, die wie folgt aussieht:
%Vor%Ich möchte mir nicht vorstellen, dies in DCG zu symbolisieren; Ich bin zu faul, um das mit einem Werkzeug zu lernen, das nicht für eine solche Aufgabe entwickelt wurde. Besser wäre es, einen ausländischen Aufruf zu einem Prädikat zu haben, das mir die einfache Liste der Token liefert.
%Vor%Die Liste für unser laufendes Beispiel sieht einfach wie folgt aus:
%Vor%Ich denke, das ist viel eleganter und deine Regeln sind entsprechend angepasst. Ich könnte mich in meinen Gedanken irren, aber am Ende ist es eine Frage des Geschmacks, und meiner Meinung nach ist DCG kein Tokenizer, und ich würde es niemals dafür verwenden, wenn es nicht unbedingt erforderlich ist. Zugegebenermaßen kann ich einige Anwendungen erkennen, bei denen es sinnvoll wäre, sie auch als Tokenizer zu verwenden, aber trotzdem denke ich, dass die Aufgaben getrennt sein sollten.
Bitte beachten Sie, dass ich NICHT sage, dass Prolog keine guten Möglichkeiten hat, Sie könnten immer im Prolog Tokenizing machen, aber Sie sollten die Aufgaben trennen und DCG nur mit Symbolen und anderen streng benötigten Zeichen oder Strings behandeln (als Großbuchstaben) Zeichenfolgen, wie Eigennamen oder andere Zeichen).
Endlich scheint mir, dass die Leute vergessen haben, dass Tokening und Parsing zwei getrennte Aufgaben sind; mehr in Prolog, da Token sind Symbole, was ist, was Prolog gut ist, und Parsen Tokens / Symbole (keine Zeichen), was DCG besser, wie versenkt Semantik Schnittstellen Prolog, die das wünschenswerte Szenario ist.
Tags und Links parsing prolog swi-prolog dcg