2008-09-27 14 views
13

Vor ein paar Tagen habe ich einen Blog-Eintrag (http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx) gelesen, wo der Autor die Idee eines generischen natürlichen Sprache DSL-Parser mit .NET diskutieren.Was wäre das beste Werkzeug, um eine natürliche DSL in Java zu erstellen?

Der brillante Teil seiner Idee ist meiner Meinung nach, dass der Text geparst und mit Klassen verglichen wird, die den gleichen Namen wie die Sätze verwenden.

Nehmen wir als Beispiel die folgenden Zeilen:

 
Create user user1 with email [email protected] and password test 
Log user1 in 
Take user1 to category t-shirts 
Make user1 add item Flower T-Shirt to cart 
Take user1 to checkout 

Würde eine Sammlung von „bekannten“ Objekte erhalten umgewandelt verwenden, die das Ergebnis der Analyse nimmt. Einige Beispiel-Objekte wäre (unter Verwendung von Java für mein Beispiel):

public class CreateUser { 
    private final String user; 
    private String email; 
    private String password; 

    public CreateUser(String user) { 
    this.user = user; 
    } 

    public void withEmail(String email) { 
    this.email = email; 
    } 

    public String andPassword(String password) { 
     this.password = password; 
    } 
} 

Also, wenn der erste Satz der Verarbeitung würde AngelegtVon Klasse ein Spiel sein (natürlich, weil es eine Verkettung von „create user“) und, da es Nimmt ein Parameter den Konstruktor an, würde der Parser "user1" als Benutzerparameter annehmen.

Danach würde der Parser identifizieren, dass der nächste Teil "mit E-Mail" auch einen Methodennamen entspricht, und da diese Methode einen Parameter benötigt, würde sie "[email protected]" als E-Mail-Parameter analysieren.

Ich denke, Sie haben die Idee, oder? Eine ziemlich klare Anwendung davon wäre, zumindest für mich, den Anwendungstestern zu ermöglichen, "Testskripte" in natürlicher Sprache zu erstellen und dann die Sätze in Klassen zu analysieren, die JUnit verwenden, um nach App-Verhalten zu suchen.

Ich würde gerne Ideen, Tipps und Meinungen zu Tools oder Ressourcen hören, die einen solchen Parser mit Java codieren könnten. Besser noch, wenn wir es vermeiden könnten, komplexe Lexer oder Frameworks wie ANTLR zu benutzen, von denen ich denke, dass sie vielleicht einen Hammer benutzen würden, um eine Fliege zu töten.

Mehr als das, wenn jemand ein Open-Source-Projekt dafür starten möchte, wäre ich definitiv interessiert.

+0

Ähnlich Glurks Antwort, daher als Kommentar: Wenn Sie nach ausführbaren "natürlichen" Sprachspezifikationen suchen, sollten Sie Cucumber (http://cukes.info/) ausprobieren. Zusammen mit JRuby (und RSpec) können Sie es für Java-basierte BDD (http://behaviour-driven.org/) verwenden. Alternativen sind EasyB und JBehave. –

+0

Was ist DSL? ist es Disambiguierung ähnlicher Sprachen? siehe corporavm.uni-koeln.de/vardial/sharedtask.html – alvas

Antwort

22

Angesichts der Komplexität von Lexing und Parsing weiß ich nicht, ob ich all das von Hand programmieren möchte. ANTLR ist nicht so schwer zu übernehmen und ich denke, es ist Worthing auf der Grundlage Ihres Problems. Wenn Sie eine Syntaxanalyse verwenden, um Syntaxbaum aus der Eingabe zu erstellen und zu abstrahieren, ist es ziemlich einfach, diesen AST mit einer Baumgrammatik zu verarbeiten. Die Baumgrammatik könnte leicht den beschriebenen Prozess ausführen.

Sie finden ANTLR an vielen Orten, einschließlich Eclipse, Groovy und Grails für einen Start. The Definitive ANTLR Reference macht es sogar ziemlich einfach, relativ schnell auf die Basis zu kommen.

Ich hatte ein Projekt, das Anfang des Jahres mit einem von Benutzern generierten Abfragetext umgehen musste. Ich begann einen Weg, um es manuell zu verarbeiten, aber es wurde schnell überwältigend. Ich brauchte ein paar Tage, um die Geschwindigkeit auf ANTLR zu erhöhen und hatte in ein paar Tagen eine erste Version meiner Grammatik und meines Prozessors. Nachträgliche Änderungen und Anpassungen an den Anforderungen hätten jede benutzerdefinierte Version zum Erliegen gebracht, aber nach der Ausführung der ANTLR-Grammatiken hätte ich relativ wenig Aufwand zur Anpassung.

Viel Glück!

+0

Joe, danke. Ich habe dieses Buch in meinem Einkaufswagen auf Amazon ein paar Mal hinzugefügt. Denkst du, es wäre einfach, dynamische Grammatikbäume basierend auf den registrierten Parsern zu erstellen? Die Bibliothek müsste Reflektion verwenden, um Klassennamen, Methoden, (...) zu extrahieren und den Grammatikbaum für ANTLR zu erstellen, oder? – kolrie

+0

Sie können Java (oder ein anderes, ANTLR kann eine Vielzahl von Sprachen erzeugen) direkt in die Grammatik einfügen. Ich benutzte eine Grammatik, um mein DSL zu parsen, und eine Sekunde, um den AST-Baum zu begehen, um die Knoten zu bearbeiten. Da dies alles in Ihrer App läuft, kann es leicht Objekte und Methoden erstellen. –

+2

Es hat ein paar Tage gedauert, bis ich meinen Kopf um ANTLR gewickelt hatte, nachdem ich noch nie einen Lexer/Parser/Kompilierkurs gemacht hatte. Ich bin sehr froh, dass ich es getan habe, da es in Zukunft immer wieder nützlich sein wird. Parr hat ANTLR geschrieben, daher ist das Buch eine großartige Quelle und eine gut geschriebene Einführung in Lexing und Parsing. –

9

Sie möchten vielleicht Xtext betrachten, die intern ANTLR verwendet und einige nette Dinge wie die automatische Generierung eines Editors für Ihr DSL tut.

1

Vielleicht finden Sie diese mehrteilige Blog-Serie, die ich mit Antlr gemacht habe, als Ausgangspunkt. Es nutzt Antlr 2, so werden einige Sachen für Antlr 3 verschieden sein:

http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-antlr-part-1-lexer/

Mark Volkman Präsentationen/Artikel auf Antlr sind sehr hilfreich auch:

http://www.ociweb.com/mark/programming/ANTLR3.html

Ich werde zweitens die Vorschlag über das endgültige ANTLR Buch, das auch ausgezeichnet ist.

0

„Eine ganz klare Anwendung kommt, dass zumindest für mich, wäre Testern zu ermöglichen Anwendung erstellen‚Testen Skripte‘in natürlicher Sprache und dann die Sätze in Klassen zu analysieren, die verwendet JUnit, um nach App-Verhalten zu suchen "

Worüber Sie hier sprechen, klingt genau wie das Tool, FitNesse. Genau wie Sie beschreiben, Kunden schreiben Akzeptanztests "Skripte" in einer Sprache, die für sie Sinn machen, und Programmierer bauen Systeme, die die Tests passieren lassen. Selbst die Implementierung, über die Sie sprechen, ist ziemlich genau wie FitNesse funktioniert - das in den Skripten verwendete Vokabular wird zu Funktionsnamen usw. verkettet, so dass das FitNesse-Framework weiß, welche Funktion aufgerufen werden soll.

it :) Wie auch immer Besuche

10

Wenn Sie, dass „natürliche Sprache“ nennen, sind Sie selbst etwas vorzumachen. Es ist immer noch eine Programmiersprache, nur eine, die versucht, natürliche Sprache nachzuahmen - und ich vermute, dass es scheitern wird, wenn Sie sich mit den Details der Implementierung beschäftigen. Um dies eindeutig zu machen, müssen Sie der Syntax Beschränkungen auferlegen, die die Benutzer, die geführt werden, dazu bringen zu glauben, dass sie "Englisch" schreiben.

Der Vorteil eines DSL ist (oder sollte es zumindest sein), dass es einfach und übersichtlich ist, aber in Bezug auf die Problemdomäne sehr leistungsfähig ist. Die Nachahmung einer natürlichen Sprache ist zweitrangig und kann sich in der Tat als kontraproduktiv für diese primären Ziele erweisen.

Wenn jemand zu dumm ist oder nicht die Fähigkeit zum formellen rigorosen Denken hat, das für die Programmierung benötigt wird, dann wird eine Programmiersprache, die ein natürliches nachahmt, sie NICHT magisch in einen Programmierer verwandeln.

Als COBOL erfunden wurde, glaubten einige ernsthaft, dass es innerhalb von 10 Jahren keine Nachfrage nach professionellen Programmierern geben würde, da COBOL "wie Englisch" war und jeder, der Software brauchte, selbst schreiben konnte. Und wir wissen alle, wie das funktioniert hat.

+1

+1, ja, es bringt mich um, dass Firmen COBOL aufgeben. Warum teure Programmierer einstellen, wenn es viele billige englischsprachige Leute gibt? –