2008-09-27 4 views
13

Пару дней назад я прочитал запись в блоге (http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx), где автор обсуждает идею общего парсера DSL на естественном языке с использованием .NET.Какой лучший инструмент для создания естественного DSL в Java?

Блестящая часть его идеи, на мой взгляд, состоит в том, что текст анализируется и сопоставляется с классами, использующими то же имя, что и предложения.

Взяв в качестве примера, следующие строки:

 
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 

бы получить преобразованы с помощью набора «известных» объектов, который принимает результат анализа. Некоторые примеры объекты будут (с использованием Java для моего примера):

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; 
    } 
} 

Таким образом, при обработке первого предложения, CreateUser класс будет матчем (очевидно, потому что это конкатенация «создать пользователь») и, поскольку оно принимает параметр в конструкторе, синтаксический анализатор будет принимать «user1» как пользовательский параметр.

После этого анализатор определит, что следующая часть «с адресом электронной почты» также соответствует имени метода, и поскольку этот метод принимает параметр, он будет анализировать «[email protected]» как параметр электронной почты.

Я думаю, вы поняли эту идею, верно? Одно из ясных приложений, по крайней мере для меня, было бы позволить тестерам приложений создавать «тестовые сценарии» на естественном языке, а затем анализировать предложения в классах, которые используют JUnit для проверки поведения приложений.

Я хотел бы услышать идеи, советы и мнения по инструментам или ресурсам, которые могли бы кодировать такой парсер с помощью Java. Еще лучше, если бы мы могли избежать использования сложных лексеров или фреймворков, таких как ANTLR, которые, я думаю, могли бы использовать молот, чтобы убить муху.

Более того, если кто-то начнет проект с открытым исходным кодом для этого, мне определенно будет интересно.

+0

Похож на ответ Глерка, поэтому в качестве комментария: Если вы ищете исполняемые «естественные» спецификации языка, вы должны дать Cucumber (http://cukes.info/) попытку. Вместе с JRuby (и RSpec) вы можете использовать его для Java-based BDD (http://behaviour-driven.org/). Альтернативы включают EasyB и JBehave. – 2009-03-25 11:00:39

+0

Что такое DSL? это неоднозначность подобных языков? см. corporavm.uni-koeln.de/vardial/sharedtask.html – alvas 2014-03-23 20:52:26

ответ

22

Учитывая сложность лексинга и синтаксического анализа, я не знаю, хочу ли я закодировать все это вручную. ANTLR не так уж сложно получить пикап, и я думаю, что это стоит взглянуть на вашу проблему. Если вы используете грамматику разбора для создания и абстрактного синтаксического дерева из ввода, его довольно легко обрабатывать AST с помощью грамматики дерева. Грамматика дерева может легко справиться с выполнением описанного вами процесса.

Вы найдете ANTLR во многих местах, включая Eclipse, Groovy и Grails для начала. The Definitive ANTLR Reference даже делает его довольно простым, чтобы быстро добраться до скорости на базовом уровне.

У меня был проект, который должен был обработать некоторый пользовательский текст запроса в начале этого года. Я начал путь к ручному процессу, но он быстро стал подавляющим. Я взял пару дней, чтобы получить скорость на ANTLR, и у меня была начальная версия моей грамматики и процессора, работающая через несколько дней. Последующие изменения и корректировки требований могли бы убить любую пользовательскую версию, но потребовали относительно небольших усилий для настройки после того, как у меня появились ANTLR-грамматики.

Удачи вам!

+0

Джо, спасибо. Я добавил эту книгу в свою корзину по телефону Amazon пару раз. Как вы думаете, было бы легко создать динамические деревья грамматики на основе зарегистрированных парсеров? Библиотека должна будет использовать отражение, чтобы извлечь имя класса, методы (...) и создать дерево грамматики для ANTLR, правильно? – kolrie 2008-09-27 20:27:04

+0

Вы можете вставить Java (или другое, ANTLR может генерировать различные языки) непосредственно в грамматику. Я использовал одну грамматику для разбора моего DSL и второй, чтобы пройти дерево AST, обрабатывая узлы. Поскольку все это работает в вашем приложении, оно может легко создавать объекты и методы вызова. – 2008-09-27 20:45:36

9

Возможно, вы захотите рассмотреть Xtext, который внутренне использует ANTLR и делает некоторые приятные вещи, такие как автоматическое создание редактора для вашего DSL.

1

Вы можете найти эту многостраничную серию блога, которую я сделал с использованием Antlr, чтобы быть полезной в качестве отправной точки. Он использует Antlr 2, так что некоторые вещи будут отличаться для Antlr 3:

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

презентации Марка Volkman в/статьи на Antlr весьма полезны, а также:

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

Я буду секунду предложение об окончательной книге ANTLR, которая также превосходна.

0

«Одно совершенно ясно применение, что, по крайней мере, для меня, было бы разрешить тестеры приложений создавать„тестирование скриптов“на естественном языке, а затем разобрать предложения в классы, которые используются JUnit для проверки поведения приложения «

О чем вы говорите, здесь звучит точно так же, как инструмент FitNesse. Как вы описали, клиенты пишут приемочные тесты «скрипты» на каком-то языке, который имеет для них смысл, а программисты создают системы, которые проходят тесты. Даже реализация, о которой вы говорите, в значительной степени похожа на то, как работает FitNesse - словарный запас, используемый в сценариях, объединяется для создания имен функций и т. Д., Поэтому структура FitNesse знает, какую функцию вызывать.

Во всяком случае, проверить его :)

10

Если вы называете это «естественный язык», вы заблуждаетесь. Это все еще язык программирования, только один, который пытается имитировать естественный язык - и я подозреваю, что он потерпит неудачу, когда вы перейдете к деталям реализации. Чтобы сделать однозначный, вам придется наложить ограничения на синтаксис, который смутит пользователей, которым пришло думать, что они пишут «английский».

Преимущество DSL (или должно быть, во всяком случае) состоит в том, что он прост и понятен, но еще более эффективен в отношении проблемной области. Подражание естественному языку является второстепенной проблемой и фактически может быть контрпродуктивным для этих основных целей.

Если кто-то слишком глуп или не обладает способностью к формальному строгому мышлению, которое требуется для программирования, то язык программирования, который имитирует естественный, НЕ волшебным образом превратит их в программиста.

Когда COBOL был изобретен, некоторые люди всерьез полагали, что в течение 10 лет для профессиональных программистов будет нулевой спрос, поскольку COBOL был «как английский», и любой, кто нуждался в программном обеспечении, мог написать его сам. И мы все знаем, как это работает.

Смежные вопросы