Какой лучший инструмент для создания естественного DSL в Java?
Пару дней назад я прочитал запись в блоге (http://ayende.com/Blog/archive/2008/09/08/Implementing-generic-natural-language-DSL.aspx), где автор обсуждает идею общего естественного языка DSL парсер с использованием .NET.
Блестящая часть его идеи, на мой взгляд, состоит в том, что текст анализируется и сопоставляется с классами, использующими то же имя, что и предложения.
Взяв в качестве примера следующие строки:
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, которые, я думаю, могли бы использовать молоток, чтобы убить муху.
Более того, если кто-то начнет проект с открытым исходным кодом для этого, мне определенно будет интересно.
Ответы
Ответ 1
Учитывая сложность лексинга и синтаксического анализа, я не знаю, хочу ли я закодировать все это вручную. ANTLR не так сложно подбирать, и я думаю, что стоит посмотреть на вашу проблему. Если вы используете грамматику синтаксического анализа для построения и абстрактного синтаксического дерева из ввода, его довольно легко обрабатывать AST с помощью грамматики дерева. Грамматика дерева может легко справиться с выполнением описанного вами процесса.
Вы найдете ANTLR во многих местах, включая Eclipse, Groovy и Grails для начала. Определяющий ANTLR Reference даже позволяет довольно быстро быстро подняться на базовый уровень.
У меня был проект, который должен был обработать некоторый пользовательский текст запроса в начале этого года. Я начал путь к ручному процессу, но он быстро стал подавляющим. Я взял пару дней, чтобы получить скорость на ANTLR, и у меня была начальная версия моей грамматики и процессора, работающая через несколько дней. Последующие изменения и корректировки требований могли бы убить любую пользовательскую версию, но потребовали относительно небольших усилий для настройки после того, как у меня появились грамматики ANTLR.
Удачи!
Ответ 2
Если вы называете этот "естественный язык", вы обманываете себя. Он по-прежнему является языком программирования, который пытается воспроизвести естественный язык - и я подозреваю, что он не сработает, когда вы перейдете к деталям реализации. Чтобы сделать однозначный, вам придется наложить ограничения на синтаксис, который смутит пользователей, которым пришло думать, что они пишут "английский".
Преимущество DSL (или должно быть, во всяком случае) заключается в том, что он прост и ясен, но обладает мощным уровнем в отношении проблемной области. Подражание естественному языку является второстепенной проблемой и может фактически быть контрпродуктивным для этих основных целей.
Если кто-то слишком глуп или лишен возможности формально строгого мышления, необходимого для программирования, тогда язык программирования, который имитирует естественный, НЕ волшебным образом превратит их в программиста.
Когда COBOL был изобретен, некоторые люди всерьез полагали, что в течение 10 лет будет отсутствовать спрос на профессиональных программистов, поскольку COBOL "как английский", и любой, кто нуждается в программном обеспечении, мог написать его сам. И мы все знаем, как это работает.
Ответ 3
Возможно, вы захотите рассмотреть Xtext, который внутренне использует ANTLR и делает некоторые приятные вещи, такие как автоматическое создание редактора для вашего DSL.
Ответ 4
Впервые я слышал о DSL, был от Jetbrains, создателя IntellJ Idea.
У них есть этот инструмент: MPS (Meta Programming System)
Ответ 5
Вы можете найти эту многостраничную серию блога, которую я сделал, используя Antlr, чтобы быть полезной в качестве отправной точки. Он использует Antlr 2, поэтому некоторые вещи будут отличаться для Antlr 3:
http://tech.puredanger.com/2007/01/13/implementing-a-scripting-language-with-antlr-part-1-lexer/
Марк Фолькман: презентации/статьи об Antlr также весьма полезны:
http://www.ociweb.com/mark/programming/ANTLR3.html
Я остановлю предложение об окончательной книге ANTLR, которая также превосходна.
Ответ 6
"Одно из ясных приложений, по крайней мере для меня, было бы позволить тестерам приложений создавать" тестовые скрипты "на естественном языке, а затем анализировать предложения в классах, которые используют JUnit для проверки поведения приложений"
То, о чем вы говорите, звучит точно так же, как инструмент FitNesse.
Именно так, как вы описываете, клиенты пишут приемочные тесты "скрипты" на каком-то языке, который имеет для них смысл, а программисты создают системы, которые проходят тесты. Даже реализация, о которой вы говорите, в значительной степени похожа на то, как работает FitNesse - словарь, используемый в сценариях, объединяется для создания имен функций и т.д., Так что структура FitNesse знает, какую функцию вызывать.
В любом случае, проверьте это:)