Какой лучший инструмент для создания естественного 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 знает, какую функцию вызывать.

В любом случае, проверьте это:)